ASoC: Fixes for v3.19 A few last minute fixes for v3.19, all driver specific. None of them stand out particularly - it's all the standard people who are affected will care stuff. The Samsung fix is a DT only fix for the audio controller, it's being merged via the ASoC tree due to process messups (the submitter sent it at the end of a tangentally related series rather than separately to the ARM folks) in order to make sure that it gets to people sooner.
Unified · Split
| @@ -31,7 +31,7 @@ i2c0: i2c@fed40000 { · 30 unmodified lines | ||
| 31 | 31 | compatible = "st,comms-ssc4-i2c"; |
| 32 | 32 | reg = <0xfed40000 0x110>; |
| 33 | 33 | interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>; |
| 34 | − clocks = <&CLK_S_ICN_REG_0>; | |
| 34 | + clocks = <&clk_s_a0_ls CLK_ICN_REG>; | |
| 35 | 35 | clock-names = "ssc"; |
| 36 | 36 | clock-frequency = <400000>; |
| 37 | 37 | pinctrl-names = "default"; |
| @@ -47,6 +47,7 @@ dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM · 46 unmodified lines | ||
| 47 | 47 | dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O |
| 48 | 48 | dallas,ds75 Digital Thermometer and Thermostat |
| 49 | 49 | dlg,da9053 DA9053: flexible system level PMIC with multicore support |
| 50 | +dlg,da9063 DA9063: system PMIC for quad-core application processors | |
| 50 | 51 | epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE |
| 51 | 52 | epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE |
| 52 | 53 | fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer |
| @@ -708,6 +708,16 @@ X: drivers/iio/*/adjd* · 707 unmodified lines | ||
| 708 | 708 | F: drivers/staging/iio/*/ad* |
| 709 | 709 | F: staging/iio/trigger/iio-trig-bfin-timer.c |
| 710 | 710 | |
| 711 | +ANDROID DRIVERS | |
| 712 | +M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
| 713 | +M: Arve Hj�nnev�g <arve@android.com> | |
| 714 | +M: Riley Andrews <riandrews@android.com> | |
| 715 | +T: git git://git.kernel.org/pub/scm/linux/kernel/gregkh/staging.git | |
| 716 | +L: devel@driverdev.osuosl.org | |
| 717 | +S: Supported | |
| 718 | +F: drivers/android/ | |
| 719 | +F: drivers/staging/android/ | |
| 720 | + | |
| 711 | 721 | AOA (Apple Onboard Audio) ALSA DRIVER |
| 712 | 722 | M: Johannes Berg <johannes@sipsolutions.net> |
| 713 | 723 | L: linuxppc-dev@lists.ozlabs.org |
| @@ -4943,6 +4953,16 @@ F: Documentation/input/multi-touch-protocol.txt · 4229 unmodified lines | ||
| 4943 | 4953 | F: drivers/input/input-mt.c |
| 4944 | 4954 | K: \b(ABS|SYN)_MT_ |
| 4945 | 4955 | |
| 4956 | +INTEL ASoC BDW/HSW DRIVERS | |
| 4957 | +M: Jie Yang <yang.jie@linux.intel.com> | |
| 4958 | +L: alsa-devel@alsa-project.org | |
| 4959 | +S: Supported | |
| 4960 | +F: sound/soc/intel/sst-haswell* | |
| 4961 | +F: sound/soc/intel/sst-dsp* | |
| 4962 | +F: sound/soc/intel/sst-firmware.c | |
| 4963 | +F: sound/soc/intel/broadwell.c | |
| 4964 | +F: sound/soc/intel/haswell.c | |
| 4965 | + | |
| 4946 | 4966 | INTEL C600 SERIES SAS CONTROLLER DRIVER |
| 4947 | 4967 | M: Intel SCU Linux support <intel-linux-scu@intel.com> |
| 4948 | 4968 | M: Artur Paszkiewicz <artur.paszkiewicz@intel.com> |
| @@ -10166,6 +10186,7 @@ USERSPACE I/O (UIO) · 5217 unmodified lines | ||
| 10166 | 10186 | M: "Hans J. Koch" <hjk@hansjkoch.de> |
| 10167 | 10187 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 10168 | 10188 | S: Maintained |
| 10189 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git | |
| 10169 | 10190 | F: Documentation/DocBook/uio-howto.tmpl |
| 10170 | 10191 | F: drivers/uio/ |
| 10171 | 10192 | F: include/linux/uio*.h |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 3 |
| 2 | 2 | PATCHLEVEL = 19 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc6 | |
| 4 | +EXTRAVERSION = -rc7 | |
| 5 | 5 | NAME = Diseased Newt |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -156,6 +156,8 @@ retry: · 155 unmodified lines | ||
| 156 | 156 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 157 | 157 | if (fault & VM_FAULT_OOM) |
| 158 | 158 | goto out_of_memory; |
| 159 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 160 | + goto bad_area; | |
| 159 | 161 | else if (fault & VM_FAULT_SIGBUS) |
| 160 | 162 | goto do_sigbus; |
| 161 | 163 | BUG(); |
| @@ -161,6 +161,8 @@ good_area: · 160 unmodified lines | ||
| 161 | 161 | |
| 162 | 162 | if (fault & VM_FAULT_OOM) |
| 163 | 163 | goto out_of_memory; |
| 164 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 165 | + goto bad_area; | |
| 164 | 166 | else if (fault & VM_FAULT_SIGBUS) |
| 165 | 167 | goto do_sigbus; |
| 166 | 168 | |
| @@ -368,7 +368,7 @@ · 367 unmodified lines | ||
| 368 | 368 | }; |
| 369 | 369 | |
| 370 | 370 | i2s1: i2s@13960000 { |
| 371 | − compatible = "samsung,s5pv210-i2s"; | |
| 371 | + compatible = "samsung,s3c6410-i2s"; | |
| 372 | 372 | reg = <0x13960000 0x100>; |
| 373 | 373 | clocks = <&clock CLK_I2S1>; |
| 374 | 374 | clock-names = "iis"; |
| @@ -378,7 +378,7 @@ · 3 unmodified lines | ||
| 378 | 378 | }; |
| 379 | 379 | |
| 380 | 380 | i2s2: i2s@13970000 { |
| 381 | − compatible = "samsung,s5pv210-i2s"; | |
| 381 | + compatible = "samsung,s3c6410-i2s"; | |
| 382 | 382 | reg = <0x13970000 0x100>; |
| 383 | 383 | clocks = <&clock CLK_I2S2>; |
| 384 | 384 | clock-names = "iis"; |
| @@ -166,12 +166,12 @@ · 165 unmodified lines | ||
| 166 | 166 | #address-cells = <1>; |
| 167 | 167 | #size-cells = <0>; |
| 168 | 168 | |
| 169 | − ethphy1: ethernet-phy@0 { | |
| 170 | − reg = <0>; | |
| 169 | + ethphy1: ethernet-phy@1 { | |
| 170 | + reg = <1>; | |
| 171 | 171 | }; |
| 172 | 172 | |
| 173 | − ethphy2: ethernet-phy@1 { | |
| 174 | − reg = <1>; | |
| 173 | + ethphy2: ethernet-phy@2 { | |
| 174 | + reg = <2>; | |
| 175 | 175 | }; |
| 176 | 176 | }; |
| 177 | 177 | }; |
| @@ -17,14 +17,6 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | aliases { |
| 19 | 19 | ethernet0 = &emac; |
| 20 | − serial0 = &uart0; | |
| 21 | − serial1 = &uart1; | |
| 22 | − serial2 = &uart2; | |
| 23 | − serial3 = &uart3; | |
| 24 | − serial4 = &uart4; | |
| 25 | − serial5 = &uart5; | |
| 26 | − serial6 = &uart6; | |
| 27 | − serial7 = &uart7; | |
| 28 | 20 | }; |
| 29 | 21 | |
| 30 | 22 | chosen { |
| @@ -39,6 +31,14 @@ · 8 unmodified lines | ||
| 39 | 31 | <&ahb_gates 44>; |
| 40 | 32 | status = "disabled"; |
| 41 | 33 | }; |
| 34 | + | |
| 35 | + framebuffer@1 { | |
| 36 | + compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; | |
| 37 | + allwinner,pipeline = "de_fe0-de_be0-lcd0-hdmi"; | |
| 38 | + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, | |
| 39 | + <&ahb_gates 44>, <&ahb_gates 46>; | |
| 40 | + status = "disabled"; | |
| 41 | + }; | |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | 44 | cpus { |
| @@ -438,8 +438,8 @@ · 393 unmodified lines | ||
| 438 | 438 | reg-names = "phy_ctrl", "pmu1", "pmu2"; |
| 439 | 439 | clocks = <&usb_clk 8>; |
| 440 | 440 | clock-names = "usb_phy"; |
| 441 | − resets = <&usb_clk 1>, <&usb_clk 2>; | |
| 442 | − reset-names = "usb1_reset", "usb2_reset"; | |
| 441 | + resets = <&usb_clk 0>, <&usb_clk 1>, <&usb_clk 2>; | |
| 442 | + reset-names = "usb0_reset", "usb1_reset", "usb2_reset"; | |
| 443 | 443 | status = "disabled"; |
| 444 | 444 | }; |
| 445 | 445 | |
| @@ -55,6 +55,12 @@ · 54 unmodified lines | ||
| 55 | 55 | model = "Olimex A10s-Olinuxino Micro"; |
| 56 | 56 | compatible = "olimex,a10s-olinuxino-micro", "allwinner,sun5i-a10s"; |
| 57 | 57 | |
| 58 | + aliases { | |
| 59 | + serial0 = &uart0; | |
| 60 | + serial1 = &uart2; | |
| 61 | + serial2 = &uart3; | |
| 62 | + }; | |
| 63 | + | |
| 58 | 64 | soc@01c00000 { |
| 59 | 65 | emac: ethernet@01c0b000 { |
| 60 | 66 | pinctrl-names = "default"; |
| @@ -18,10 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | aliases { |
| 20 | 20 | ethernet0 = &emac; |
| 21 | − serial0 = &uart0; | |
| 22 | − serial1 = &uart1; | |
| 23 | − serial2 = &uart2; | |
| 24 | − serial3 = &uart3; | |
| 25 | 21 | }; |
| 26 | 22 | |
| 27 | 23 | chosen { |
| @@ -390,8 +386,8 @@ · 362 unmodified lines | ||
| 390 | 386 | reg-names = "phy_ctrl", "pmu1"; |
| 391 | 387 | clocks = <&usb_clk 8>; |
| 392 | 388 | clock-names = "usb_phy"; |
| 393 | − resets = <&usb_clk 1>; | |
| 394 | − reset-names = "usb1_reset"; | |
| 389 | + resets = <&usb_clk 0>, <&usb_clk 1>; | |
| 390 | + reset-names = "usb0_reset", "usb1_reset"; | |
| 395 | 391 | status = "disabled"; |
| 396 | 392 | }; |
| 397 | 393 | |
| @@ -53,6 +53,10 @@ · 52 unmodified lines | ||
| 53 | 53 | model = "HSG H702"; |
| 54 | 54 | compatible = "hsg,h702", "allwinner,sun5i-a13"; |
| 55 | 55 | |
| 56 | + aliases { | |
| 57 | + serial0 = &uart1; | |
| 58 | + }; | |
| 59 | + | |
| 56 | 60 | soc@01c00000 { |
| 57 | 61 | mmc0: mmc@01c0f000 { |
| 58 | 62 | pinctrl-names = "default"; |
| @@ -54,6 +54,10 @@ · 53 unmodified lines | ||
| 54 | 54 | model = "Olimex A13-Olinuxino Micro"; |
| 55 | 55 | compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13"; |
| 56 | 56 | |
| 57 | + aliases { | |
| 58 | + serial0 = &uart1; | |
| 59 | + }; | |
| 60 | + | |
| 57 | 61 | soc@01c00000 { |
| 58 | 62 | mmc0: mmc@01c0f000 { |
| 59 | 63 | pinctrl-names = "default"; |
| @@ -55,6 +55,10 @@ · 54 unmodified lines | ||
| 55 | 55 | model = "Olimex A13-Olinuxino"; |
| 56 | 56 | compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13"; |
| 57 | 57 | |
| 58 | + aliases { | |
| 59 | + serial0 = &uart1; | |
| 60 | + }; | |
| 61 | + | |
| 58 | 62 | soc@01c00000 { |
| 59 | 63 | mmc0: mmc@01c0f000 { |
| 60 | 64 | pinctrl-names = "default"; |
| @@ -16,11 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | / { |
| 17 | 17 | interrupt-parent = <&intc>; |
| 18 | 18 | |
| 19 | − aliases { | |
| 20 | − serial0 = &uart1; | |
| 21 | − serial1 = &uart3; | |
| 22 | − }; | |
| 23 | − | |
| 24 | 19 | cpus { |
| 25 | 20 | #address-cells = <1>; |
| 26 | 21 | #size-cells = <0>; |
| @@ -349,8 +344,8 @@ · 322 unmodified lines | ||
| 349 | 344 | reg-names = "phy_ctrl", "pmu1"; |
| 350 | 345 | clocks = <&usb_clk 8>; |
| 351 | 346 | clock-names = "usb_phy"; |
| 352 | − resets = <&usb_clk 1>; | |
| 353 | − reset-names = "usb1_reset"; | |
| 347 | + resets = <&usb_clk 0>, <&usb_clk 1>; | |
| 348 | + reset-names = "usb0_reset", "usb1_reset"; | |
| 354 | 349 | status = "disabled"; |
| 355 | 350 | }; |
| 356 | 351 | |
| @@ -53,12 +53,6 @@ · 52 unmodified lines | ||
| 53 | 53 | interrupt-parent = <&gic>; |
| 54 | 54 | |
| 55 | 55 | aliases { |
| 56 | − serial0 = &uart0; | |
| 57 | − serial1 = &uart1; | |
| 58 | − serial2 = &uart2; | |
| 59 | − serial3 = &uart3; | |
| 60 | − serial4 = &uart4; | |
| 61 | − serial5 = &uart5; | |
| 62 | 56 | ethernet0 = &gmac; |
| 63 | 57 | }; |
| 64 | 58 | |
| @@ -55,6 +55,12 @@ · 54 unmodified lines | ||
| 55 | 55 | model = "LeMaker Banana Pi"; |
| 56 | 56 | compatible = "lemaker,bananapi", "allwinner,sun7i-a20"; |
| 57 | 57 | |
| 58 | + aliases { | |
| 59 | + serial0 = &uart0; | |
| 60 | + serial1 = &uart3; | |
| 61 | + serial2 = &uart7; | |
| 62 | + }; | |
| 63 | + | |
| 58 | 64 | soc@01c00000 { |
| 59 | 65 | spi0: spi@01c05000 { |
| 60 | 66 | pinctrl-names = "default"; |
| @@ -19,6 +19,14 @@ · 18 unmodified lines | ||
| 19 | 19 | model = "Merrii A20 Hummingbird"; |
| 20 | 20 | compatible = "merrii,a20-hummingbird", "allwinner,sun7i-a20"; |
| 21 | 21 | |
| 22 | + aliases { | |
| 23 | + serial0 = &uart0; | |
| 24 | + serial1 = &uart2; | |
| 25 | + serial2 = &uart3; | |
| 26 | + serial3 = &uart4; | |
| 27 | + serial4 = &uart5; | |
| 28 | + }; | |
| 29 | + | |
| 22 | 30 | soc@01c00000 { |
| 23 | 31 | mmc0: mmc@01c0f000 { |
| 24 | 32 | pinctrl-names = "default"; |
| @@ -20,6 +20,9 @@ · 19 unmodified lines | ||
| 20 | 20 | compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20"; |
| 21 | 21 | |
| 22 | 22 | aliases { |
| 23 | + serial0 = &uart0; | |
| 24 | + serial1 = &uart6; | |
| 25 | + serial2 = &uart7; | |
| 23 | 26 | spi0 = &spi1; |
| 24 | 27 | spi1 = &spi2; |
| 25 | 28 | }; |
| @@ -54,14 +54,6 @@ · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | aliases { |
| 56 | 56 | ethernet0 = &gmac; |
| 57 | − serial0 = &uart0; | |
| 58 | − serial1 = &uart1; | |
| 59 | − serial2 = &uart2; | |
| 60 | − serial3 = &uart3; | |
| 61 | − serial4 = &uart4; | |
| 62 | − serial5 = &uart5; | |
| 63 | − serial6 = &uart6; | |
| 64 | − serial7 = &uart7; | |
| 65 | 57 | }; |
| 66 | 58 | |
| 67 | 59 | chosen { |
| @@ -55,6 +55,10 @@ · 54 unmodified lines | ||
| 55 | 55 | model = "Ippo Q8H Dual Core Tablet (v5)"; |
| 56 | 56 | compatible = "ippo,q8h-v5", "allwinner,sun8i-a23"; |
| 57 | 57 | |
| 58 | + aliases { | |
| 59 | + serial0 = &r_uart; | |
| 60 | + }; | |
| 61 | + | |
| 58 | 62 | chosen { |
| 59 | 63 | bootargs = "earlyprintk console=ttyS0,115200"; |
| 60 | 64 | }; |
| @@ -52,15 +52,6 @@ · 51 unmodified lines | ||
| 52 | 52 | / { |
| 53 | 53 | interrupt-parent = <&gic>; |
| 54 | 54 | |
| 55 | − aliases { | |
| 56 | − serial0 = &uart0; | |
| 57 | − serial1 = &uart1; | |
| 58 | − serial2 = &uart2; | |
| 59 | − serial3 = &uart3; | |
| 60 | − serial4 = &uart4; | |
| 61 | − serial5 = &r_uart; | |
| 62 | − }; | |
| 63 | − | |
| 64 | 55 | cpus { |
| 65 | 56 | #address-cells = <1>; |
| 66 | 57 | #size-cells = <0>; |
| @@ -54,6 +54,11 @@ · 53 unmodified lines | ||
| 54 | 54 | model = "Merrii A80 Optimus Board"; |
| 55 | 55 | compatible = "merrii,a80-optimus", "allwinner,sun9i-a80"; |
| 56 | 56 | |
| 57 | + aliases { | |
| 58 | + serial0 = &uart0; | |
| 59 | + serial1 = &uart4; | |
| 60 | + }; | |
| 61 | + | |
| 57 | 62 | chosen { |
| 58 | 63 | bootargs = "earlyprintk console=ttyS0,115200"; |
| 59 | 64 | }; |
| @@ -52,16 +52,6 @@ · 51 unmodified lines | ||
| 52 | 52 | / { |
| 53 | 53 | interrupt-parent = <&gic>; |
| 54 | 54 | |
| 55 | − aliases { | |
| 56 | − serial0 = &uart0; | |
| 57 | − serial1 = &uart1; | |
| 58 | − serial2 = &uart2; | |
| 59 | − serial3 = &uart3; | |
| 60 | − serial4 = &uart4; | |
| 61 | − serial5 = &uart5; | |
| 62 | − serial6 = &r_uart; | |
| 63 | − }; | |
| 64 | − | |
| 65 | 55 | cpus { |
| 66 | 56 | #address-cells = <1>; |
| 67 | 57 | #size-cells = <0>; |
| @@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) · 37 unmodified lines | ||
| 38 | 38 | vcpu->arch.hcr = HCR_GUEST_MASK; |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu) | |
| 42 | +{ | |
| 43 | + return vcpu->arch.hcr; | |
| 44 | +} | |
| 45 | + | |
| 46 | +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr) | |
| 47 | +{ | |
| 48 | + vcpu->arch.hcr = hcr; | |
| 49 | +} | |
| 50 | + | |
| 41 | 51 | static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu) |
| 42 | 52 | { |
| 43 | 53 | return 1; |
| @@ -125,9 +125,6 @@ struct kvm_vcpu_arch { · 124 unmodified lines | ||
| 125 | 125 | * Anything that is not used directly from assembly code goes |
| 126 | 126 | * here. |
| 127 | 127 | */ |
| 128 | − /* dcache set/way operation pending */ | |
| 129 | − int last_pcpu; | |
| 130 | − cpumask_t require_dcache_flush; | |
| 131 | 128 | |
| 132 | 129 | /* Don't run the guest on this vcpu */ |
| 133 | 130 | bool pause; |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | #ifndef __ASSEMBLY__ |
| 46 | 46 | |
| 47 | +#include <linux/highmem.h> | |
| 47 | 48 | #include <asm/cacheflush.h> |
| 48 | 49 | #include <asm/pgalloc.h> |
| 49 | 50 | |
| @@ -161,13 +162,10 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) · 111 unmodified lines | ||
| 161 | 162 | return (vcpu->arch.cp15[c1_SCTLR] & 0b101) == 0b101; |
| 162 | 163 | } |
| 163 | 164 | |
| 164 | −static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, | |
| 165 | − unsigned long size, | |
| 166 | − bool ipa_uncached) | |
| 165 | +static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn, | |
| 166 | + unsigned long size, | |
| 167 | + bool ipa_uncached) | |
| 167 | 168 | { |
| 168 | − if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached) | |
| 169 | − kvm_flush_dcache_to_poc((void *)hva, size); | |
| 170 | − | |
| 171 | 169 | /* |
| 172 | 170 | * If we are going to insert an instruction page and the icache is |
| 173 | 171 | * either VIPT or PIPT, there is a potential problem where the host |
| @@ -179,18 +177,77 @@ static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, · 5 unmodified lines | ||
| 179 | 177 | * |
| 180 | 178 | * VIVT caches are tagged using both the ASID and the VMID and doesn't |
| 181 | 179 | * need any kind of flushing (DDI 0406C.b - Page B3-1392). |
| 180 | + * | |
| 181 | + * We need to do this through a kernel mapping (using the | |
| 182 | + * user-space mapping has proved to be the wrong | |
| 183 | + * solution). For that, we need to kmap one page at a time, | |
| 184 | + * and iterate over the range. | |
| 182 | 185 | */ |
| 183 | − if (icache_is_pipt()) { | |
| 184 | − __cpuc_coherent_user_range(hva, hva + size); | |
| 185 | − } else if (!icache_is_vivt_asid_tagged()) { | |
| 186 | + | |
| 187 | + bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached; | |
| 188 | + | |
| 189 | + VM_BUG_ON(size & PAGE_MASK); | |
| 190 | + | |
| 191 | + if (!need_flush && !icache_is_pipt()) | |
| 192 | + goto vipt_cache; | |
| 193 | + | |
| 194 | + while (size) { | |
| 195 | + void *va = kmap_atomic_pfn(pfn); | |
| 196 | + | |
| 197 | + if (need_flush) | |
| 198 | + kvm_flush_dcache_to_poc(va, PAGE_SIZE); | |
| 199 | + | |
| 200 | + if (icache_is_pipt()) | |
| 201 | + __cpuc_coherent_user_range((unsigned long)va, | |
| 202 | + (unsigned long)va + PAGE_SIZE); | |
| 203 | + | |
| 204 | + size -= PAGE_SIZE; | |
| 205 | + pfn++; | |
| 206 | + | |
| 207 | + kunmap_atomic(va); | |
| 208 | + } | |
| 209 | + | |
| 210 | +vipt_cache: | |
| 211 | + if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) { | |
| 186 | 212 | /* any kind of VIPT cache */ |
| 187 | 213 | __flush_icache_all(); |
| 188 | 214 | } |
| 189 | 215 | } |
| 190 | 216 | |
| 217 | +static inline void __kvm_flush_dcache_pte(pte_t pte) | |
| 218 | +{ | |
| 219 | + void *va = kmap_atomic(pte_page(pte)); | |
| 220 | + | |
| 221 | + kvm_flush_dcache_to_poc(va, PAGE_SIZE); | |
| 222 | + | |
| 223 | + kunmap_atomic(va); | |
| 224 | +} | |
| 225 | + | |
| 226 | +static inline void __kvm_flush_dcache_pmd(pmd_t pmd) | |
| 227 | +{ | |
| 228 | + unsigned long size = PMD_SIZE; | |
| 229 | + pfn_t pfn = pmd_pfn(pmd); | |
| 230 | + | |
| 231 | + while (size) { | |
| 232 | + void *va = kmap_atomic_pfn(pfn); | |
| 233 | + | |
| 234 | + kvm_flush_dcache_to_poc(va, PAGE_SIZE); | |
| 235 | + | |
| 236 | + pfn++; | |
| 237 | + size -= PAGE_SIZE; | |
| 238 | + | |
| 239 | + kunmap_atomic(va); | |
| 240 | + } | |
| 241 | +} | |
| 242 | + | |
| 243 | +static inline void __kvm_flush_dcache_pud(pud_t pud) | |
| 244 | +{ | |
| 245 | +} | |
| 246 | + | |
| 191 | 247 | #define kvm_virt_to_phys(x) virt_to_idmap((unsigned long)(x)) |
| 192 | 248 | |
| 193 | −void stage2_flush_vm(struct kvm *kvm); | |
| 249 | +void kvm_set_way_flush(struct kvm_vcpu *vcpu); | |
| 250 | +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled); | |
| 194 | 251 | |
| 195 | 252 | #endif /* !__ASSEMBLY__ */ |
| 196 | 253 | |
| @@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 280 unmodified lines | ||
| 281 | 281 | vcpu->cpu = cpu; |
| 282 | 282 | vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); |
| 283 | 283 | |
| 284 | − /* | |
| 285 | − * Check whether this vcpu requires the cache to be flushed on | |
| 286 | − * this physical CPU. This is a consequence of doing dcache | |
| 287 | − * operations by set/way on this vcpu. We do it here to be in | |
| 288 | − * a non-preemptible section. | |
| 289 | − */ | |
| 290 | − if (cpumask_test_and_clear_cpu(cpu, &vcpu->arch.require_dcache_flush)) | |
| 291 | − flush_cache_all(); /* We'd really want v7_flush_dcache_all() */ | |
| 292 | − | |
| 293 | 284 | kvm_arm_set_running_vcpu(vcpu); |
| 294 | 285 | } |
| 295 | 286 | |
| @@ -541,7 +532,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) · 245 unmodified lines | ||
| 541 | 532 | ret = kvm_call_hyp(__kvm_vcpu_run, vcpu); |
| 542 | 533 | |
| 543 | 534 | vcpu->mode = OUTSIDE_GUEST_MODE; |
| 544 | − vcpu->arch.last_pcpu = smp_processor_id(); | |
| 545 | 535 | kvm_guest_exit(); |
| 546 | 536 | trace_kvm_exit(*vcpu_pc(vcpu)); |
| 547 | 537 | /* |
| @@ -189,82 +189,40 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu, · 188 unmodified lines | ||
| 189 | 189 | return true; |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | −/* See note at ARM ARM B1.14.4 */ | |
| 192 | +/* | |
| 193 | + * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized). | |
| 194 | + */ | |
| 193 | 195 | static bool access_dcsw(struct kvm_vcpu *vcpu, |
| 194 | 196 | const struct coproc_params *p, |
| 195 | 197 | const struct coproc_reg *r) |
| 196 | 198 | { |
| 197 | − unsigned long val; | |
| 198 | − int cpu; | |
| 199 | − | |
| 200 | 199 | if (!p->is_write) |
| 201 | 200 | return read_from_write_only(vcpu, p); |
| 202 | 201 | |
| 203 | − cpu = get_cpu(); | |
| 204 | − | |
| 205 | − cpumask_setall(&vcpu->arch.require_dcache_flush); | |
| 206 | − cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush); | |
| 207 | − | |
| 208 | − /* If we were already preempted, take the long way around */ | |
| 209 | − if (cpu != vcpu->arch.last_pcpu) { | |
| 210 | − flush_cache_all(); | |
| 211 | − goto done; | |
| 212 | − } | |
| 213 | − | |
| 214 | − val = *vcpu_reg(vcpu, p->Rt1); | |
| 215 | − | |
| 216 | − switch (p->CRm) { | |
| 217 | − case 6: /* Upgrade DCISW to DCCISW, as per HCR.SWIO */ | |
| 218 | − case 14: /* DCCISW */ | |
| 219 | − asm volatile("mcr p15, 0, %0, c7, c14, 2" : : "r" (val)); | |
| 220 | − break; | |
| 221 | − | |
| 222 | − case 10: /* DCCSW */ | |
| 223 | − asm volatile("mcr p15, 0, %0, c7, c10, 2" : : "r" (val)); | |
| 224 | − break; | |
| 225 | − } | |
| 226 | − | |
| 227 | −done: | |
| 228 | − put_cpu(); | |
| 229 | − | |
| 202 | + kvm_set_way_flush(vcpu); | |
| 230 | 203 | return true; |
| 231 | 204 | } |
| 232 | 205 | |
| 233 | 206 | /* |
| 234 | 207 | * Generic accessor for VM registers. Only called as long as HCR_TVM |
| 235 | − * is set. | |
| 208 | + * is set. If the guest enables the MMU, we stop trapping the VM | |
| 209 | + * sys_regs and leave it in complete control of the caches. | |
| 210 | + * | |
| 211 | + * Used by the cpu-specific code. | |
| 236 | 212 | */ |
| 237 | −static bool access_vm_reg(struct kvm_vcpu *vcpu, | |
| 238 | − const struct coproc_params *p, | |
| 239 | − const struct coproc_reg *r) | |
| 213 | +bool access_vm_reg(struct kvm_vcpu *vcpu, | |
| 214 | + const struct coproc_params *p, | |
| 215 | + const struct coproc_reg *r) | |
| 240 | 216 | { |
| 217 | + bool was_enabled = vcpu_has_cache_enabled(vcpu); | |
| 218 | + | |
| 241 | 219 | BUG_ON(!p->is_write); |
| 242 | 220 | |
| 243 | 221 | vcpu->arch.cp15[r->reg] = *vcpu_reg(vcpu, p->Rt1); |
| 244 | 222 | if (p->is_64bit) |
| 245 | 223 | vcpu->arch.cp15[r->reg + 1] = *vcpu_reg(vcpu, p->Rt2); |
| 246 | 224 | |
| 247 | − return true; | |
| 248 | −} | |
| 249 | − | |
| 250 | −/* | |
| 251 | − * SCTLR accessor. Only called as long as HCR_TVM is set. If the | |
| 252 | − * guest enables the MMU, we stop trapping the VM sys_regs and leave | |
| 253 | − * it in complete control of the caches. | |
| 254 | − * | |
| 255 | − * Used by the cpu-specific code. | |
| 256 | − */ | |
| 257 | −bool access_sctlr(struct kvm_vcpu *vcpu, | |
| 258 | − const struct coproc_params *p, | |
| 259 | − const struct coproc_reg *r) | |
| 260 | −{ | |
| 261 | − access_vm_reg(vcpu, p, r); | |
| 262 | − | |
| 263 | − if (vcpu_has_cache_enabled(vcpu)) { /* MMU+Caches enabled? */ | |
| 264 | − vcpu->arch.hcr &= ~HCR_TVM; | |
| 265 | − stage2_flush_vm(vcpu->kvm); | |
| 266 | − } | |
| 267 | − | |
| 225 | + kvm_toggle_cache(vcpu, was_enabled); | |
| 268 | 226 | return true; |
| 269 | 227 | } |
| 270 | 228 | |
| @@ -153,8 +153,8 @@ static inline int cmp_reg(const struct coproc_reg *i1, · 152 unmodified lines | ||
| 153 | 153 | #define is64 .is_64 = true |
| 154 | 154 | #define is32 .is_64 = false |
| 155 | 155 | |
| 156 | −bool access_sctlr(struct kvm_vcpu *vcpu, | |
| 157 | − const struct coproc_params *p, | |
| 158 | − const struct coproc_reg *r); | |
| 156 | +bool access_vm_reg(struct kvm_vcpu *vcpu, | |
| 157 | + const struct coproc_params *p, | |
| 158 | + const struct coproc_reg *r); | |
| 159 | 159 | |
| 160 | 160 | #endif /* __ARM_KVM_COPROC_LOCAL_H__ */ |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | static const struct coproc_reg a15_regs[] = { |
| 35 | 35 | /* SCTLR: swapped by interrupt.S. */ |
| 36 | 36 | { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32, |
| 37 | − access_sctlr, reset_val, c1_SCTLR, 0x00C50078 }, | |
| 37 | + access_vm_reg, reset_val, c1_SCTLR, 0x00C50078 }, | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | static struct kvm_coproc_target_table a15_target_table = { |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | static const struct coproc_reg a7_regs[] = { |
| 38 | 38 | /* SCTLR: swapped by interrupt.S. */ |
| 39 | 39 | { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32, |
| 40 | − access_sctlr, reset_val, c1_SCTLR, 0x00C50878 }, | |
| 40 | + access_vm_reg, reset_val, c1_SCTLR, 0x00C50878 }, | |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | 43 | static struct kvm_coproc_target_table a7_target_table = { |
| @@ -58,6 +58,26 @@ static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) · 57 unmodified lines | ||
| 58 | 58 | kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | +/* | |
| 62 | + * D-Cache management functions. They take the page table entries by | |
| 63 | + * value, as they are flushing the cache using the kernel mapping (or | |
| 64 | + * kmap on 32bit). | |
| 65 | + */ | |
| 66 | +static void kvm_flush_dcache_pte(pte_t pte) | |
| 67 | +{ | |
| 68 | + __kvm_flush_dcache_pte(pte); | |
| 69 | +} | |
| 70 | + | |
| 71 | +static void kvm_flush_dcache_pmd(pmd_t pmd) | |
| 72 | +{ | |
| 73 | + __kvm_flush_dcache_pmd(pmd); | |
| 74 | +} | |
| 75 | + | |
| 76 | +static void kvm_flush_dcache_pud(pud_t pud) | |
| 77 | +{ | |
| 78 | + __kvm_flush_dcache_pud(pud); | |
| 79 | +} | |
| 80 | + | |
| 61 | 81 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, |
| 62 | 82 | int min, int max) |
| 63 | 83 | { |
| @@ -119,6 +139,26 @@ static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) · 55 unmodified lines | ||
| 119 | 139 | put_page(virt_to_page(pmd)); |
| 120 | 140 | } |
| 121 | 141 | |
| 142 | +/* | |
| 143 | + * Unmapping vs dcache management: | |
| 144 | + * | |
| 145 | + * If a guest maps certain memory pages as uncached, all writes will | |
| 146 | + * bypass the data cache and go directly to RAM. However, the CPUs | |
| 147 | + * can still speculate reads (not writes) and fill cache lines with | |
| 148 | + * data. | |
| 149 | + * | |
| 150 | + * Those cache lines will be *clean* cache lines though, so a | |
| 151 | + * clean+invalidate operation is equivalent to an invalidate | |
| 152 | + * operation, because no cache lines are marked dirty. | |
| 153 | + * | |
| 154 | + * Those clean cache lines could be filled prior to an uncached write | |
| 155 | + * by the guest, and the cache coherent IO subsystem would therefore | |
| 156 | + * end up writing old data to disk. | |
| 157 | + * | |
| 158 | + * This is why right after unmapping a page/section and invalidating | |
| 159 | + * the corresponding TLBs, we call kvm_flush_dcache_p*() to make sure | |
| 160 | + * the IO subsystem will never hit in the cache. | |
| 161 | + */ | |
| 122 | 162 | static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, |
| 123 | 163 | phys_addr_t addr, phys_addr_t end) |
| 124 | 164 | { |
| @@ -128,9 +168,16 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, · 3 unmodified lines | ||
| 128 | 168 | start_pte = pte = pte_offset_kernel(pmd, addr); |
| 129 | 169 | do { |
| 130 | 170 | if (!pte_none(*pte)) { |
| 171 | + pte_t old_pte = *pte; | |
| 172 | + | |
| 131 | 173 | kvm_set_pte(pte, __pte(0)); |
| 132 | − put_page(virt_to_page(pte)); | |
| 133 | 174 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 175 | + | |
| 176 | + /* No need to invalidate the cache for device mappings */ | |
| 177 | + if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE) | |
| 178 | + kvm_flush_dcache_pte(old_pte); | |
| 179 | + | |
| 180 | + put_page(virt_to_page(pte)); | |
| 134 | 181 | } |
| 135 | 182 | } while (pte++, addr += PAGE_SIZE, addr != end); |
| 136 | 183 | |
| @@ -149,8 +196,13 @@ static void unmap_pmds(struct kvm *kvm, pud_t *pud, · 12 unmodified lines | ||
| 149 | 196 | next = kvm_pmd_addr_end(addr, end); |
| 150 | 197 | if (!pmd_none(*pmd)) { |
| 151 | 198 | if (kvm_pmd_huge(*pmd)) { |
| 199 | + pmd_t old_pmd = *pmd; | |
| 200 | + | |
| 152 | 201 | pmd_clear(pmd); |
| 153 | 202 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 203 | + | |
| 204 | + kvm_flush_dcache_pmd(old_pmd); | |
| 205 | + | |
| 154 | 206 | put_page(virt_to_page(pmd)); |
| 155 | 207 | } else { |
| 156 | 208 | unmap_ptes(kvm, pmd, addr, next); |
| @@ -173,8 +225,13 @@ static void unmap_puds(struct kvm *kvm, pgd_t *pgd, · 16 unmodified lines | ||
| 173 | 225 | next = kvm_pud_addr_end(addr, end); |
| 174 | 226 | if (!pud_none(*pud)) { |
| 175 | 227 | if (pud_huge(*pud)) { |
| 228 | + pud_t old_pud = *pud; | |
| 229 | + | |
| 176 | 230 | pud_clear(pud); |
| 177 | 231 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 232 | + | |
| 233 | + kvm_flush_dcache_pud(old_pud); | |
| 234 | + | |
| 178 | 235 | put_page(virt_to_page(pud)); |
| 179 | 236 | } else { |
| 180 | 237 | unmap_pmds(kvm, pud, addr, next); |
| @@ -209,10 +266,9 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd, · 28 unmodified lines | ||
| 209 | 266 | |
| 210 | 267 | pte = pte_offset_kernel(pmd, addr); |
| 211 | 268 | do { |
| 212 | − if (!pte_none(*pte)) { | |
| 213 | − hva_t hva = gfn_to_hva(kvm, addr >> PAGE_SHIFT); | |
| 214 | − kvm_flush_dcache_to_poc((void*)hva, PAGE_SIZE); | |
| 215 | − } | |
| 269 | + if (!pte_none(*pte) && | |
| 270 | + (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE) | |
| 271 | + kvm_flush_dcache_pte(*pte); | |
| 216 | 272 | } while (pte++, addr += PAGE_SIZE, addr != end); |
| 217 | 273 | } |
| 218 | 274 | |
| @@ -226,12 +282,10 @@ static void stage2_flush_pmds(struct kvm *kvm, pud_t *pud, · 7 unmodified lines | ||
| 226 | 282 | do { |
| 227 | 283 | next = kvm_pmd_addr_end(addr, end); |
| 228 | 284 | if (!pmd_none(*pmd)) { |
| 229 | − if (kvm_pmd_huge(*pmd)) { | |
| 230 | − hva_t hva = gfn_to_hva(kvm, addr >> PAGE_SHIFT); | |
| 231 | − kvm_flush_dcache_to_poc((void*)hva, PMD_SIZE); | |
| 232 | − } else { | |
| 285 | + if (kvm_pmd_huge(*pmd)) | |
| 286 | + kvm_flush_dcache_pmd(*pmd); | |
| 287 | + else | |
| 233 | 288 | stage2_flush_ptes(kvm, pmd, addr, next); |
| 234 | − } | |
| 235 | 289 | } |
| 236 | 290 | } while (pmd++, addr = next, addr != end); |
| 237 | 291 | } |
| @@ -246,12 +300,10 @@ static void stage2_flush_puds(struct kvm *kvm, pgd_t *pgd, · 8 unmodified lines | ||
| 246 | 300 | do { |
| 247 | 301 | next = kvm_pud_addr_end(addr, end); |
| 248 | 302 | if (!pud_none(*pud)) { |
| 249 | − if (pud_huge(*pud)) { | |
| 250 | − hva_t hva = gfn_to_hva(kvm, addr >> PAGE_SHIFT); | |
| 251 | − kvm_flush_dcache_to_poc((void*)hva, PUD_SIZE); | |
| 252 | − } else { | |
| 303 | + if (pud_huge(*pud)) | |
| 304 | + kvm_flush_dcache_pud(*pud); | |
| 305 | + else | |
| 253 | 306 | stage2_flush_pmds(kvm, pud, addr, next); |
| 254 | − } | |
| 255 | 307 | } |
| 256 | 308 | } while (pud++, addr = next, addr != end); |
| 257 | 309 | } |
| @@ -278,7 +330,7 @@ static void stage2_flush_memslot(struct kvm *kvm, · 20 unmodified lines | ||
| 278 | 330 | * Go through the stage 2 page tables and invalidate any cache lines |
| 279 | 331 | * backing memory already mapped to the VM. |
| 280 | 332 | */ |
| 281 | −void stage2_flush_vm(struct kvm *kvm) | |
| 333 | +static void stage2_flush_vm(struct kvm *kvm) | |
| 282 | 334 | { |
| 283 | 335 | struct kvm_memslots *slots; |
| 284 | 336 | struct kvm_memory_slot *memslot; |
| @@ -905,6 +957,12 @@ static bool kvm_is_device_pfn(unsigned long pfn) · 620 unmodified lines | ||
| 905 | 957 | return !pfn_valid(pfn); |
| 906 | 958 | } |
| 907 | 959 | |
| 960 | +static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn, | |
| 961 | + unsigned long size, bool uncached) | |
| 962 | +{ | |
| 963 | + __coherent_cache_guest_page(vcpu, pfn, size, uncached); | |
| 964 | +} | |
| 965 | + | |
| 908 | 966 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, |
| 909 | 967 | struct kvm_memory_slot *memslot, unsigned long hva, |
| 910 | 968 | unsigned long fault_status) |
| @@ -994,8 +1052,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, · 83 unmodified lines | ||
| 994 | 1052 | kvm_set_s2pmd_writable(&new_pmd); |
| 995 | 1053 | kvm_set_pfn_dirty(pfn); |
| 996 | 1054 | } |
| 997 | − coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE, | |
| 998 | − fault_ipa_uncached); | |
| 1055 | + coherent_cache_guest_page(vcpu, pfn, PMD_SIZE, fault_ipa_uncached); | |
| 999 | 1056 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); |
| 1000 | 1057 | } else { |
| 1001 | 1058 | pte_t new_pte = pfn_pte(pfn, mem_type); |
| @@ -1003,8 +1060,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, · 1 unmodified line | ||
| 1003 | 1060 | kvm_set_s2pte_writable(&new_pte); |
| 1004 | 1061 | kvm_set_pfn_dirty(pfn); |
| 1005 | 1062 | } |
| 1006 | − coherent_cache_guest_page(vcpu, hva, PAGE_SIZE, | |
| 1007 | − fault_ipa_uncached); | |
| 1063 | + coherent_cache_guest_page(vcpu, pfn, PAGE_SIZE, fault_ipa_uncached); | |
| 1008 | 1064 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, |
| 1009 | 1065 | pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); |
| 1010 | 1066 | } |
| @@ -1411,3 +1467,71 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 400 unmodified lines | ||
| 1411 | 1467 | unmap_stage2_range(kvm, gpa, size); |
| 1412 | 1468 | spin_unlock(&kvm->mmu_lock); |
| 1413 | 1469 | } |
| 1470 | + | |
| 1471 | +/* | |
| 1472 | + * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized). | |
| 1473 | + * | |
| 1474 | + * Main problems: | |
| 1475 | + * - S/W ops are local to a CPU (not broadcast) | |
| 1476 | + * - We have line migration behind our back (speculation) | |
| 1477 | + * - System caches don't support S/W at all (damn!) | |
| 1478 | + * | |
| 1479 | + * In the face of the above, the best we can do is to try and convert | |
| 1480 | + * S/W ops to VA ops. Because the guest is not allowed to infer the | |
| 1481 | + * S/W to PA mapping, it can only use S/W to nuke the whole cache, | |
| 1482 | + * which is a rather good thing for us. | |
| 1483 | + * | |
| 1484 | + * Also, it is only used when turning caches on/off ("The expected | |
| 1485 | + * usage of the cache maintenance instructions that operate by set/way | |
| 1486 | + * is associated with the cache maintenance instructions associated | |
| 1487 | + * with the powerdown and powerup of caches, if this is required by | |
| 1488 | + * the implementation."). | |
| 1489 | + * | |
| 1490 | + * We use the following policy: | |
| 1491 | + * | |
| 1492 | + * - If we trap a S/W operation, we enable VM trapping to detect | |
| 1493 | + * caches being turned on/off, and do a full clean. | |
| 1494 | + * | |
| 1495 | + * - We flush the caches on both caches being turned on and off. | |
| 1496 | + * | |
| 1497 | + * - Once the caches are enabled, we stop trapping VM ops. | |
| 1498 | + */ | |
| 1499 | +void kvm_set_way_flush(struct kvm_vcpu *vcpu) | |
| 1500 | +{ | |
| 1501 | + unsigned long hcr = vcpu_get_hcr(vcpu); | |
| 1502 | + | |
| 1503 | + /* | |
| 1504 | + * If this is the first time we do a S/W operation | |
| 1505 | + * (i.e. HCR_TVM not set) flush the whole memory, and set the | |
| 1506 | + * VM trapping. | |
| 1507 | + * | |
| 1508 | + * Otherwise, rely on the VM trapping to wait for the MMU + | |
| 1509 | + * Caches to be turned off. At that point, we'll be able to | |
| 1510 | + * clean the caches again. | |
| 1511 | + */ | |
| 1512 | + if (!(hcr & HCR_TVM)) { | |
| 1513 | + trace_kvm_set_way_flush(*vcpu_pc(vcpu), | |
| 1514 | + vcpu_has_cache_enabled(vcpu)); | |
| 1515 | + stage2_flush_vm(vcpu->kvm); | |
| 1516 | + vcpu_set_hcr(vcpu, hcr | HCR_TVM); | |
| 1517 | + } | |
| 1518 | +} | |
| 1519 | + | |
| 1520 | +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled) | |
| 1521 | +{ | |
| 1522 | + bool now_enabled = vcpu_has_cache_enabled(vcpu); | |
| 1523 | + | |
| 1524 | + /* | |
| 1525 | + * If switching the MMU+caches on, need to invalidate the caches. | |
| 1526 | + * If switching it off, need to clean the caches. | |
| 1527 | + * Clean + invalidate does the trick always. | |
| 1528 | + */ | |
| 1529 | + if (now_enabled != was_enabled) | |
| 1530 | + stage2_flush_vm(vcpu->kvm); | |
| 1531 | + | |
| 1532 | + /* Caches are now on, stop trapping VM ops (until a S/W op) */ | |
| 1533 | + if (now_enabled) | |
| 1534 | + vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) & ~HCR_TVM); | |
| 1535 | + | |
| 1536 | + trace_kvm_toggle_cache(*vcpu_pc(vcpu), was_enabled, now_enabled); | |
| 1537 | +} | |
| @@ -223,6 +223,45 @@ TRACE_EVENT(kvm_hvc, · 222 unmodified lines | ||
| 223 | 223 | __entry->vcpu_pc, __entry->r0, __entry->imm) |
| 224 | 224 | ); |
| 225 | 225 | |
| 226 | +TRACE_EVENT(kvm_set_way_flush, | |
| 227 | + TP_PROTO(unsigned long vcpu_pc, bool cache), | |
| 228 | + TP_ARGS(vcpu_pc, cache), | |
| 229 | + | |
| 230 | + TP_STRUCT__entry( | |
| 231 | + __field( unsigned long, vcpu_pc ) | |
| 232 | + __field( bool, cache ) | |
| 233 | + ), | |
| 234 | + | |
| 235 | + TP_fast_assign( | |
| 236 | + __entry->vcpu_pc = vcpu_pc; | |
| 237 | + __entry->cache = cache; | |
| 238 | + ), | |
| 239 | + | |
| 240 | + TP_printk("S/W flush at 0x%016lx (cache %s)", | |
| 241 | + __entry->vcpu_pc, __entry->cache ? "on" : "off") | |
| 242 | +); | |
| 243 | + | |
| 244 | +TRACE_EVENT(kvm_toggle_cache, | |
| 245 | + TP_PROTO(unsigned long vcpu_pc, bool was, bool now), | |
| 246 | + TP_ARGS(vcpu_pc, was, now), | |
| 247 | + | |
| 248 | + TP_STRUCT__entry( | |
| 249 | + __field( unsigned long, vcpu_pc ) | |
| 250 | + __field( bool, was ) | |
| 251 | + __field( bool, now ) | |
| 252 | + ), | |
| 253 | + | |
| 254 | + TP_fast_assign( | |
| 255 | + __entry->vcpu_pc = vcpu_pc; | |
| 256 | + __entry->was = was; | |
| 257 | + __entry->now = now; | |
| 258 | + ), | |
| 259 | + | |
| 260 | + TP_printk("VM op at 0x%016lx (cache was %s, now %s)", | |
| 261 | + __entry->vcpu_pc, __entry->was ? "on" : "off", | |
| 262 | + __entry->now ? "on" : "off") | |
| 263 | +); | |
| 264 | + | |
| 226 | 265 | #endif /* _TRACE_KVM_H */ |
| 227 | 266 | |
| 228 | 267 | #undef TRACE_INCLUDE_PATH |
| @@ -189,6 +189,13 @@ static void __init armada_375_380_coherency_init(struct device_node *np) · 188 unmodified lines | ||
| 189 | 189 | coherency_cpu_base = of_iomap(np, 0); |
| 190 | 190 | arch_ioremap_caller = armada_pcie_wa_ioremap_caller; |
| 191 | 191 | |
| 192 | + /* | |
| 193 | + * We should switch the PL310 to I/O coherency mode only if | |
| 194 | + * I/O coherency is actually enabled. | |
| 195 | + */ | |
| 196 | + if (!coherency_available()) | |
| 197 | + return; | |
| 198 | + | |
| 192 | 199 | /* |
| 193 | 200 | * Add the PL310 property "arm,io-coherent". This makes sure the |
| 194 | 201 | * outer sync operation is not used, which allows to |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/gpio_keys.h> |
| 19 | 19 | #include <linux/input.h> |
| 20 | 20 | #include <linux/interrupt.h> |
| 21 | +#include <linux/irqchip.h> | |
| 22 | +#include <linux/irqchip/arm-gic.h> | |
| 21 | 23 | #include <linux/kernel.h> |
| 22 | 24 | #include <linux/mfd/tmio.h> |
| 23 | 25 | #include <linux/mmc/host.h> |
| @@ -273,6 +275,22 @@ static void __init ape6evm_add_standard_devices(void) · 249 unmodified lines | ||
| 273 | 275 | sizeof(ape6evm_leds_pdata)); |
| 274 | 276 | } |
| 275 | 277 | |
| 278 | +static void __init ape6evm_legacy_init_time(void) | |
| 279 | +{ | |
| 280 | + /* Do not invoke DT-based timers via clocksource_of_init() */ | |
| 281 | +} | |
| 282 | + | |
| 283 | +static void __init ape6evm_legacy_init_irq(void) | |
| 284 | +{ | |
| 285 | + void __iomem *gic_dist_base = ioremap_nocache(0xf1001000, 0x1000); | |
| 286 | + void __iomem *gic_cpu_base = ioremap_nocache(0xf1002000, 0x1000); | |
| 287 | + | |
| 288 | + gic_init(0, 29, gic_dist_base, gic_cpu_base); | |
| 289 | + | |
| 290 | + /* Do not invoke DT-based interrupt code via irqchip_init() */ | |
| 291 | +} | |
| 292 | + | |
| 293 | + | |
| 276 | 294 | static const char *ape6evm_boards_compat_dt[] __initdata = { |
| 277 | 295 | "renesas,ape6evm", |
| 278 | 296 | NULL, |
| @@ -280,7 +298,9 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { · 1 unmodified line | ||
| 280 | 298 | |
| 281 | 299 | DT_MACHINE_START(APE6EVM_DT, "ape6evm") |
| 282 | 300 | .init_early = shmobile_init_delay, |
| 301 | + .init_irq = ape6evm_legacy_init_irq, | |
| 283 | 302 | .init_machine = ape6evm_add_standard_devices, |
| 284 | 303 | .init_late = shmobile_init_late, |
| 285 | 304 | .dt_compat = ape6evm_boards_compat_dt, |
| 305 | + .init_time = ape6evm_legacy_init_time, | |
| 286 | 306 | MACHINE_END |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/input.h> |
| 22 | 22 | #include <linux/interrupt.h> |
| 23 | 23 | #include <linux/irq.h> |
| 24 | +#include <linux/irqchip.h> | |
| 25 | +#include <linux/irqchip/arm-gic.h> | |
| 24 | 26 | #include <linux/kernel.h> |
| 25 | 27 | #include <linux/leds.h> |
| 26 | 28 | #include <linux/mfd/tmio.h> |
| @@ -811,6 +813,16 @@ static void __init lager_init(void) · 784 unmodified lines | ||
| 811 | 813 | lager_ksz8041_fixup); |
| 812 | 814 | } |
| 813 | 815 | |
| 816 | +static void __init lager_legacy_init_irq(void) | |
| 817 | +{ | |
| 818 | + void __iomem *gic_dist_base = ioremap_nocache(0xf1001000, 0x1000); | |
| 819 | + void __iomem *gic_cpu_base = ioremap_nocache(0xf1002000, 0x1000); | |
| 820 | + | |
| 821 | + gic_init(0, 29, gic_dist_base, gic_cpu_base); | |
| 822 | + | |
| 823 | + /* Do not invoke DT-based interrupt code via irqchip_init() */ | |
| 824 | +} | |
| 825 | + | |
| 814 | 826 | static const char * const lager_boards_compat_dt[] __initconst = { |
| 815 | 827 | "renesas,lager", |
| 816 | 828 | NULL, |
| @@ -819,6 +831,7 @@ static const char * const lager_boards_compat_dt[] __initconst = { · 2 unmodified lines | ||
| 819 | 831 | DT_MACHINE_START(LAGER_DT, "lager") |
| 820 | 832 | .smp = smp_ops(r8a7790_smp_ops), |
| 821 | 833 | .init_early = shmobile_init_delay, |
| 834 | + .init_irq = lager_legacy_init_irq, | |
| 822 | 835 | .init_time = rcar_gen2_timer_init, |
| 823 | 836 | .init_machine = lager_init, |
| 824 | 837 | .init_late = shmobile_init_late, |
| @@ -133,7 +133,9 @@ void __init rcar_gen2_timer_init(void) · 132 unmodified lines | ||
| 133 | 133 | #ifdef CONFIG_COMMON_CLK |
| 134 | 134 | rcar_gen2_clocks_init(mode); |
| 135 | 135 | #endif |
| 136 | +#ifdef CONFIG_ARCH_SHMOBILE_MULTI | |
| 136 | 137 | clocksource_of_init(); |
| 138 | +#endif | |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | 141 | struct memory_reserve_config { |
| @@ -70,6 +70,18 @@ void __init shmobile_init_delay(void) · 69 unmodified lines | ||
| 70 | 70 | if (!max_freq) |
| 71 | 71 | return; |
| 72 | 72 | |
| 73 | +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY | |
| 74 | + /* Non-multiplatform r8a73a4 SoC cannot use arch timer due | |
| 75 | + * to GIC being initialized from C and arch timer via DT */ | |
| 76 | + if (of_machine_is_compatible("renesas,r8a73a4")) | |
| 77 | + has_arch_timer = false; | |
| 78 | + | |
| 79 | + /* Non-multiplatform r8a7790 SoC cannot use arch timer due | |
| 80 | + * to GIC being initialized from C and arch timer via DT */ | |
| 81 | + if (of_machine_is_compatible("renesas,r8a7790")) | |
| 82 | + has_arch_timer = false; | |
| 83 | +#endif | |
| 84 | + | |
| 73 | 85 | if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) { |
| 74 | 86 | if (is_a7_a8_a9) |
| 75 | 87 | shmobile_setup_delay_hz(max_freq, 1, 3); |
| @@ -1940,13 +1940,32 @@ void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping) · 1939 unmodified lines | ||
| 1940 | 1940 | } |
| 1941 | 1941 | EXPORT_SYMBOL_GPL(arm_iommu_release_mapping); |
| 1942 | 1942 | |
| 1943 | +static int __arm_iommu_attach_device(struct device *dev, | |
| 1944 | + struct dma_iommu_mapping *mapping) | |
| 1945 | +{ | |
| 1946 | + int err; | |
| 1947 | + | |
| 1948 | + err = iommu_attach_device(mapping->domain, dev); | |
| 1949 | + if (err) | |
| 1950 | + return err; | |
| 1951 | + | |
| 1952 | + kref_get(&mapping->kref); | |
| 1953 | + dev->archdata.mapping = mapping; | |
| 1954 | + | |
| 1955 | + pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev)); | |
| 1956 | + return 0; | |
| 1957 | +} | |
| 1958 | + | |
| 1943 | 1959 | /** |
| 1944 | 1960 | * arm_iommu_attach_device |
| 1945 | 1961 | * @dev: valid struct device pointer |
| 1946 | 1962 | * @mapping: io address space mapping structure (returned from |
| 1947 | 1963 | * arm_iommu_create_mapping) |
| 1948 | 1964 | * |
| 1949 | − * Attaches specified io address space mapping to the provided device, | |
| 1965 | + * Attaches specified io address space mapping to the provided device. | |
| 1966 | + * This replaces the dma operations (dma_map_ops pointer) with the | |
| 1967 | + * IOMMU aware version. | |
| 1968 | + * | |
| 1950 | 1969 | * More than one client might be attached to the same io address space |
| 1951 | 1970 | * mapping. |
| 1952 | 1971 | */ |
| @@ -1955,25 +1974,16 @@ int arm_iommu_attach_device(struct device *dev, · 2 unmodified lines | ||
| 1955 | 1974 | { |
| 1956 | 1975 | int err; |
| 1957 | 1976 | |
| 1958 | − err = iommu_attach_device(mapping->domain, dev); | |
| 1977 | + err = __arm_iommu_attach_device(dev, mapping); | |
| 1959 | 1978 | if (err) |
| 1960 | 1979 | return err; |
| 1961 | 1980 | |
| 1962 | − kref_get(&mapping->kref); | |
| 1963 | − dev->archdata.mapping = mapping; | |
| 1964 | − | |
| 1965 | − pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev)); | |
| 1981 | + set_dma_ops(dev, &iommu_ops); | |
| 1966 | 1982 | return 0; |
| 1967 | 1983 | } |
| 1968 | 1984 | EXPORT_SYMBOL_GPL(arm_iommu_attach_device); |
| 1969 | 1985 | |
| 1970 | −/** | |
| 1971 | − * arm_iommu_detach_device | |
| 1972 | − * @dev: valid struct device pointer | |
| 1973 | − * | |
| 1974 | − * Detaches the provided device from a previously attached map. | |
| 1975 | − */ | |
| 1976 | −void arm_iommu_detach_device(struct device *dev) | |
| 1986 | +static void __arm_iommu_detach_device(struct device *dev) | |
| 1977 | 1987 | { |
| 1978 | 1988 | struct dma_iommu_mapping *mapping; |
| 1979 | 1989 | |
| @@ -1989,6 +1999,19 @@ void arm_iommu_detach_device(struct device *dev) · 9 unmodified lines | ||
| 1989 | 1999 | |
| 1990 | 2000 | pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev)); |
| 1991 | 2001 | } |
| 2002 | + | |
| 2003 | +/** | |
| 2004 | + * arm_iommu_detach_device | |
| 2005 | + * @dev: valid struct device pointer | |
| 2006 | + * | |
| 2007 | + * Detaches the provided device from a previously attached map. | |
| 2008 | + * This voids the dma operations (dma_map_ops pointer) | |
| 2009 | + */ | |
| 2010 | +void arm_iommu_detach_device(struct device *dev) | |
| 2011 | +{ | |
| 2012 | + __arm_iommu_detach_device(dev); | |
| 2013 | + set_dma_ops(dev, NULL); | |
| 2014 | +} | |
| 1992 | 2015 | EXPORT_SYMBOL_GPL(arm_iommu_detach_device); |
| 1993 | 2016 | |
| 1994 | 2017 | static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent) |
| @@ -2011,7 +2034,7 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, · 16 unmodified lines | ||
| 2011 | 2034 | return false; |
| 2012 | 2035 | } |
| 2013 | 2036 | |
| 2014 | − if (arm_iommu_attach_device(dev, mapping)) { | |
| 2037 | + if (__arm_iommu_attach_device(dev, mapping)) { | |
| 2015 | 2038 | pr_warn("Failed to attached device %s to IOMMU_mapping\n", |
| 2016 | 2039 | dev_name(dev)); |
| 2017 | 2040 | arm_iommu_release_mapping(mapping); |
| @@ -2025,7 +2048,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) · 7 unmodified lines | ||
| 2025 | 2048 | { |
| 2026 | 2049 | struct dma_iommu_mapping *mapping = dev->archdata.mapping; |
| 2027 | 2050 | |
| 2028 | − arm_iommu_detach_device(dev); | |
| 2051 | + __arm_iommu_detach_device(dev); | |
| 2029 | 2052 | arm_iommu_release_mapping(mapping); |
| 2030 | 2053 | } |
| 2031 | 2054 | |
| @@ -45,6 +45,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) · 44 unmodified lines | ||
| 45 | 45 | vcpu->arch.hcr_el2 &= ~HCR_RW; |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu) | |
| 49 | +{ | |
| 50 | + return vcpu->arch.hcr_el2; | |
| 51 | +} | |
| 52 | + | |
| 53 | +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr) | |
| 54 | +{ | |
| 55 | + vcpu->arch.hcr_el2 = hcr; | |
| 56 | +} | |
| 57 | + | |
| 48 | 58 | static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) |
| 49 | 59 | { |
| 50 | 60 | return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc; |
| @@ -116,9 +116,6 @@ struct kvm_vcpu_arch { · 115 unmodified lines | ||
| 116 | 116 | * Anything that is not used directly from assembly code goes |
| 117 | 117 | * here. |
| 118 | 118 | */ |
| 119 | − /* dcache set/way operation pending */ | |
| 120 | − int last_pcpu; | |
| 121 | − cpumask_t require_dcache_flush; | |
| 122 | 119 | |
| 123 | 120 | /* Don't run the guest */ |
| 124 | 121 | bool pause; |
| @@ -243,24 +243,46 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) · 242 unmodified lines | ||
| 243 | 243 | return (vcpu_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101; |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | −static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, | |
| 247 | − unsigned long size, | |
| 248 | − bool ipa_uncached) | |
| 246 | +static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn, | |
| 247 | + unsigned long size, | |
| 248 | + bool ipa_uncached) | |
| 249 | 249 | { |
| 250 | + void *va = page_address(pfn_to_page(pfn)); | |
| 251 | + | |
| 250 | 252 | if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached) |
| 251 | − kvm_flush_dcache_to_poc((void *)hva, size); | |
| 253 | + kvm_flush_dcache_to_poc(va, size); | |
| 252 | 254 | |
| 253 | 255 | if (!icache_is_aliasing()) { /* PIPT */ |
| 254 | − flush_icache_range(hva, hva + size); | |
| 256 | + flush_icache_range((unsigned long)va, | |
| 257 | + (unsigned long)va + size); | |
| 255 | 258 | } else if (!icache_is_aivivt()) { /* non ASID-tagged VIVT */ |
| 256 | 259 | /* any kind of VIPT cache */ |
| 257 | 260 | __flush_icache_all(); |
| 258 | 261 | } |
| 259 | 262 | } |
| 260 | 263 | |
| 264 | +static inline void __kvm_flush_dcache_pte(pte_t pte) | |
| 265 | +{ | |
| 266 | + struct page *page = pte_page(pte); | |
| 267 | + kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE); | |
| 268 | +} | |
| 269 | + | |
| 270 | +static inline void __kvm_flush_dcache_pmd(pmd_t pmd) | |
| 271 | +{ | |
| 272 | + struct page *page = pmd_page(pmd); | |
| 273 | + kvm_flush_dcache_to_poc(page_address(page), PMD_SIZE); | |
| 274 | +} | |
| 275 | + | |
| 276 | +static inline void __kvm_flush_dcache_pud(pud_t pud) | |
| 277 | +{ | |
| 278 | + struct page *page = pud_page(pud); | |
| 279 | + kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE); | |
| 280 | +} | |
| 281 | + | |
| 261 | 282 | #define kvm_virt_to_phys(x) __virt_to_phys((unsigned long)(x)) |
| 262 | 283 | |
| 263 | −void stage2_flush_vm(struct kvm *kvm); | |
| 284 | +void kvm_set_way_flush(struct kvm_vcpu *vcpu); | |
| 285 | +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled); | |
| 264 | 286 | |
| 265 | 287 | #endif /* __ASSEMBLY__ */ |
| 266 | 288 | #endif /* __ARM64_KVM_MMU_H__ */ |
| @@ -69,68 +69,31 @@ static u32 get_ccsidr(u32 csselr) · 68 unmodified lines | ||
| 69 | 69 | return ccsidr; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | −static void do_dc_cisw(u32 val) | |
| 73 | −{ | |
| 74 | − asm volatile("dc cisw, %x0" : : "r" (val)); | |
| 75 | − dsb(ish); | |
| 76 | −} | |
| 77 | − | |
| 78 | −static void do_dc_csw(u32 val) | |
| 79 | −{ | |
| 80 | − asm volatile("dc csw, %x0" : : "r" (val)); | |
| 81 | − dsb(ish); | |
| 82 | −} | |
| 83 | − | |
| 84 | −/* See note at ARM ARM B1.14.4 */ | |
| 72 | +/* | |
| 73 | + * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized). | |
| 74 | + */ | |
| 85 | 75 | static bool access_dcsw(struct kvm_vcpu *vcpu, |
| 86 | 76 | const struct sys_reg_params *p, |
| 87 | 77 | const struct sys_reg_desc *r) |
| 88 | 78 | { |
| 89 | − unsigned long val; | |
| 90 | − int cpu; | |
| 91 | − | |
| 92 | 79 | if (!p->is_write) |
| 93 | 80 | return read_from_write_only(vcpu, p); |
| 94 | 81 | |
| 95 | − cpu = get_cpu(); | |
| 96 | − | |
| 97 | − cpumask_setall(&vcpu->arch.require_dcache_flush); | |
| 98 | − cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush); | |
| 99 | − | |
| 100 | − /* If we were already preempted, take the long way around */ | |
| 101 | − if (cpu != vcpu->arch.last_pcpu) { | |
| 102 | − flush_cache_all(); | |
| 103 | − goto done; | |
| 104 | − } | |
| 105 | − | |
| 106 | − val = *vcpu_reg(vcpu, p->Rt); | |
| 107 | − | |
| 108 | − switch (p->CRm) { | |
| 109 | − case 6: /* Upgrade DCISW to DCCISW, as per HCR.SWIO */ | |
| 110 | − case 14: /* DCCISW */ | |
| 111 | − do_dc_cisw(val); | |
| 112 | − break; | |
| 113 | − | |
| 114 | − case 10: /* DCCSW */ | |
| 115 | − do_dc_csw(val); | |
| 116 | − break; | |
| 117 | − } | |
| 118 | − | |
| 119 | −done: | |
| 120 | − put_cpu(); | |
| 121 | − | |
| 82 | + kvm_set_way_flush(vcpu); | |
| 122 | 83 | return true; |
| 123 | 84 | } |
| 124 | 85 | |
| 125 | 86 | /* |
| 126 | 87 | * Generic accessor for VM registers. Only called as long as HCR_TVM |
| 127 | − * is set. | |
| 88 | + * is set. If the guest enables the MMU, we stop trapping the VM | |
| 89 | + * sys_regs and leave it in complete control of the caches. | |
| 128 | 90 | */ |
| 129 | 91 | static bool access_vm_reg(struct kvm_vcpu *vcpu, |
| 130 | 92 | const struct sys_reg_params *p, |
| 131 | 93 | const struct sys_reg_desc *r) |
| 132 | 94 | { |
| 133 | 95 | unsigned long val; |
| 96 | + bool was_enabled = vcpu_has_cache_enabled(vcpu); | |
| 134 | 97 | |
| 135 | 98 | BUG_ON(!p->is_write); |
| 136 | 99 | |
| @@ -143,25 +106,7 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu, · 6 unmodified lines | ||
| 143 | 106 | vcpu_cp15_64_low(vcpu, r->reg) = val & 0xffffffffUL; |
| 144 | 107 | } |
| 145 | 108 | |
| 146 | − return true; | |
| 147 | −} | |
| 148 | − | |
| 149 | −/* | |
| 150 | − * SCTLR_EL1 accessor. Only called as long as HCR_TVM is set. If the | |
| 151 | − * guest enables the MMU, we stop trapping the VM sys_regs and leave | |
| 152 | − * it in complete control of the caches. | |
| 153 | − */ | |
| 154 | −static bool access_sctlr(struct kvm_vcpu *vcpu, | |
| 155 | − const struct sys_reg_params *p, | |
| 156 | − const struct sys_reg_desc *r) | |
| 157 | −{ | |
| 158 | − access_vm_reg(vcpu, p, r); | |
| 159 | − | |
| 160 | − if (vcpu_has_cache_enabled(vcpu)) { /* MMU+Caches enabled? */ | |
| 161 | − vcpu->arch.hcr_el2 &= ~HCR_TVM; | |
| 162 | − stage2_flush_vm(vcpu->kvm); | |
| 163 | − } | |
| 164 | − | |
| 109 | + kvm_toggle_cache(vcpu, was_enabled); | |
| 165 | 110 | return true; |
| 166 | 111 | } |
| 167 | 112 | |
| @@ -377,7 +322,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 209 unmodified lines | ||
| 377 | 322 | NULL, reset_mpidr, MPIDR_EL1 }, |
| 378 | 323 | /* SCTLR_EL1 */ |
| 379 | 324 | { Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b000), |
| 380 | − access_sctlr, reset_val, SCTLR_EL1, 0x00C50078 }, | |
| 325 | + access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 }, | |
| 381 | 326 | /* CPACR_EL1 */ |
| 382 | 327 | { Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b010), |
| 383 | 328 | NULL, reset_val, CPACR_EL1, 0 }, |
| @@ -657,7 +602,7 @@ static const struct sys_reg_desc cp14_64_regs[] = { · 273 unmodified lines | ||
| 657 | 602 | * register). |
| 658 | 603 | */ |
| 659 | 604 | static const struct sys_reg_desc cp15_regs[] = { |
| 660 | − { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_sctlr, NULL, c1_SCTLR }, | |
| 605 | + { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_vm_reg, NULL, c1_SCTLR }, | |
| 661 | 606 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, |
| 662 | 607 | { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, |
| 663 | 608 | { Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, c2_TTBCR }, |
| @@ -142,6 +142,8 @@ good_area: · 141 unmodified lines | ||
| 142 | 142 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 143 | 143 | if (fault & VM_FAULT_OOM) |
| 144 | 144 | goto out_of_memory; |
| 145 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 146 | + goto bad_area; | |
| 145 | 147 | else if (fault & VM_FAULT_SIGBUS) |
| 146 | 148 | goto do_sigbus; |
| 147 | 149 | BUG(); |
| @@ -176,6 +176,8 @@ retry: · 175 unmodified lines | ||
| 176 | 176 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 177 | 177 | if (fault & VM_FAULT_OOM) |
| 178 | 178 | goto out_of_memory; |
| 179 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 180 | + goto bad_area; | |
| 179 | 181 | else if (fault & VM_FAULT_SIGBUS) |
| 180 | 182 | goto do_sigbus; |
| 181 | 183 | BUG(); |
| @@ -168,6 +168,8 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear · 167 unmodified lines | ||
| 168 | 168 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 169 | 169 | if (fault & VM_FAULT_OOM) |
| 170 | 170 | goto out_of_memory; |
| 171 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 172 | + goto bad_area; | |
| 171 | 173 | else if (fault & VM_FAULT_SIGBUS) |
| 172 | 174 | goto do_sigbus; |
| 173 | 175 | BUG(); |
| @@ -172,6 +172,8 @@ retry: · 171 unmodified lines | ||
| 172 | 172 | */ |
| 173 | 173 | if (fault & VM_FAULT_OOM) { |
| 174 | 174 | goto out_of_memory; |
| 175 | + } else if (fault & VM_FAULT_SIGSEGV) { | |
| 176 | + goto bad_area; | |
| 175 | 177 | } else if (fault & VM_FAULT_SIGBUS) { |
| 176 | 178 | signal = SIGBUS; |
| 177 | 179 | goto bad_area; |
| @@ -200,6 +200,8 @@ good_area: · 199 unmodified lines | ||
| 200 | 200 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 201 | 201 | if (fault & VM_FAULT_OOM) |
| 202 | 202 | goto out_of_memory; |
| 203 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 204 | + goto bad_area; | |
| 203 | 205 | else if (fault & VM_FAULT_SIGBUS) |
| 204 | 206 | goto do_sigbus; |
| 205 | 207 | BUG(); |
| @@ -145,6 +145,8 @@ good_area: · 144 unmodified lines | ||
| 145 | 145 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 146 | 146 | if (fault & VM_FAULT_OOM) |
| 147 | 147 | goto out_of_memory; |
| 148 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 149 | + goto map_err; | |
| 148 | 150 | else if (fault & VM_FAULT_SIGBUS) |
| 149 | 151 | goto bus_err; |
| 150 | 152 | BUG(); |
| @@ -141,6 +141,8 @@ good_area: · 140 unmodified lines | ||
| 141 | 141 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 142 | 142 | if (fault & VM_FAULT_OOM) |
| 143 | 143 | goto out_of_memory; |
| 144 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 145 | + goto bad_area; | |
| 144 | 146 | else if (fault & VM_FAULT_SIGBUS) |
| 145 | 147 | goto do_sigbus; |
| 146 | 148 | BUG(); |
| @@ -224,6 +224,8 @@ good_area: · 223 unmodified lines | ||
| 224 | 224 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 225 | 225 | if (fault & VM_FAULT_OOM) |
| 226 | 226 | goto out_of_memory; |
| 227 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 228 | + goto bad_area; | |
| 227 | 229 | else if (fault & VM_FAULT_SIGBUS) |
| 228 | 230 | goto do_sigbus; |
| 229 | 231 | BUG(); |
| @@ -158,6 +158,8 @@ good_area: · 157 unmodified lines | ||
| 158 | 158 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 159 | 159 | if (fault & VM_FAULT_OOM) |
| 160 | 160 | goto out_of_memory; |
| 161 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 162 | + goto bad_area; | |
| 161 | 163 | else if (fault & VM_FAULT_SIGBUS) |
| 162 | 164 | goto do_sigbus; |
| 163 | 165 | BUG(); |
| @@ -262,6 +262,8 @@ good_area: · 261 unmodified lines | ||
| 262 | 262 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 263 | 263 | if (fault & VM_FAULT_OOM) |
| 264 | 264 | goto out_of_memory; |
| 265 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 266 | + goto bad_area; | |
| 265 | 267 | else if (fault & VM_FAULT_SIGBUS) |
| 266 | 268 | goto do_sigbus; |
| 267 | 269 | BUG(); |
| @@ -135,6 +135,8 @@ survive: · 134 unmodified lines | ||
| 135 | 135 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 136 | 136 | if (fault & VM_FAULT_OOM) |
| 137 | 137 | goto out_of_memory; |
| 138 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 139 | + goto bad_area; | |
| 138 | 140 | else if (fault & VM_FAULT_SIGBUS) |
| 139 | 141 | goto do_sigbus; |
| 140 | 142 | BUG(); |
| @@ -171,6 +171,8 @@ good_area: · 170 unmodified lines | ||
| 171 | 171 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 172 | 172 | if (fault & VM_FAULT_OOM) |
| 173 | 173 | goto out_of_memory; |
| 174 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 175 | + goto bad_area; | |
| 174 | 176 | else if (fault & VM_FAULT_SIGBUS) |
| 175 | 177 | goto do_sigbus; |
| 176 | 178 | BUG(); |
| @@ -256,6 +256,8 @@ good_area: · 255 unmodified lines | ||
| 256 | 256 | */ |
| 257 | 257 | if (fault & VM_FAULT_OOM) |
| 258 | 258 | goto out_of_memory; |
| 259 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 260 | + goto bad_area; | |
| 259 | 261 | else if (fault & VM_FAULT_SIGBUS) |
| 260 | 262 | goto bad_area; |
| 261 | 263 | BUG(); |
| @@ -76,7 +76,7 @@ int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea, · 75 unmodified lines | ||
| 76 | 76 | if (*flt & VM_FAULT_OOM) { |
| 77 | 77 | ret = -ENOMEM; |
| 78 | 78 | goto out_unlock; |
| 79 | − } else if (*flt & VM_FAULT_SIGBUS) { | |
| 79 | + } else if (*flt & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) { | |
| 80 | 80 | ret = -EFAULT; |
| 81 | 81 | goto out_unlock; |
| 82 | 82 | } |
| @@ -437,6 +437,8 @@ good_area: · 436 unmodified lines | ||
| 437 | 437 | */ |
| 438 | 438 | fault = handle_mm_fault(mm, vma, address, flags); |
| 439 | 439 | if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { |
| 440 | + if (fault & VM_FAULT_SIGSEGV) | |
| 441 | + goto bad_area; | |
| 440 | 442 | rc = mm_fault_error(regs, address, fault); |
| 441 | 443 | if (rc >= MM_FAULT_RETURN) |
| 442 | 444 | goto bail; |
| @@ -304,7 +304,7 @@ int pnv_save_sprs_for_winkle(void) · 303 unmodified lines | ||
| 304 | 304 | * all cpus at boot. Get these reg values of current cpu and use the |
| 305 | 305 | * same accross all cpus. |
| 306 | 306 | */ |
| 307 | − uint64_t lpcr_val = mfspr(SPRN_LPCR); | |
| 307 | + uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; | |
| 308 | 308 | uint64_t hid0_val = mfspr(SPRN_HID0); |
| 309 | 309 | uint64_t hid1_val = mfspr(SPRN_HID1); |
| 310 | 310 | uint64_t hid4_val = mfspr(SPRN_HID4); |
| @@ -337,6 +337,7 @@ static inline void disable_surveillance(void) · 336 unmodified lines | ||
| 337 | 337 | args.token = rtas_token("set-indicator"); |
| 338 | 338 | if (args.token == RTAS_UNKNOWN_SERVICE) |
| 339 | 339 | return; |
| 340 | + args.token = cpu_to_be32(args.token); | |
| 340 | 341 | args.nargs = cpu_to_be32(3); |
| 341 | 342 | args.nret = cpu_to_be32(1); |
| 342 | 343 | args.rets = &args.args[3]; |
| @@ -374,6 +374,12 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault) · 373 unmodified lines | ||
| 374 | 374 | do_no_context(regs); |
| 375 | 375 | else |
| 376 | 376 | pagefault_out_of_memory(); |
| 377 | + } else if (fault & VM_FAULT_SIGSEGV) { | |
| 378 | + /* Kernel mode? Handle exceptions or die */ | |
| 379 | + if (!user_mode(regs)) | |
| 380 | + do_no_context(regs); | |
| 381 | + else | |
| 382 | + do_sigsegv(regs, SEGV_MAPERR); | |
| 377 | 383 | } else if (fault & VM_FAULT_SIGBUS) { |
| 378 | 384 | /* Kernel mode? Handle exceptions or die */ |
| 379 | 385 | if (!user_mode(regs)) |
| @@ -114,6 +114,8 @@ good_area: · 113 unmodified lines | ||
| 114 | 114 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 115 | 115 | if (fault & VM_FAULT_OOM) |
| 116 | 116 | goto out_of_memory; |
| 117 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 118 | + goto bad_area; | |
| 117 | 119 | else if (fault & VM_FAULT_SIGBUS) |
| 118 | 120 | goto do_sigbus; |
| 119 | 121 | BUG(); |
| @@ -353,6 +353,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, · 352 unmodified lines | ||
| 353 | 353 | } else { |
| 354 | 354 | if (fault & VM_FAULT_SIGBUS) |
| 355 | 355 | do_sigbus(regs, error_code, address); |
| 356 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 357 | + bad_area(regs, error_code, address); | |
| 356 | 358 | else |
| 357 | 359 | BUG(); |
| 358 | 360 | } |
| @@ -249,6 +249,8 @@ good_area: · 248 unmodified lines | ||
| 249 | 249 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 250 | 250 | if (fault & VM_FAULT_OOM) |
| 251 | 251 | goto out_of_memory; |
| 252 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 253 | + goto bad_area; | |
| 252 | 254 | else if (fault & VM_FAULT_SIGBUS) |
| 253 | 255 | goto do_sigbus; |
| 254 | 256 | BUG(); |
| @@ -446,6 +446,8 @@ good_area: · 445 unmodified lines | ||
| 446 | 446 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 447 | 447 | if (fault & VM_FAULT_OOM) |
| 448 | 448 | goto out_of_memory; |
| 449 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 450 | + goto bad_area; | |
| 449 | 451 | else if (fault & VM_FAULT_SIGBUS) |
| 450 | 452 | goto do_sigbus; |
| 451 | 453 | BUG(); |
| @@ -442,6 +442,8 @@ good_area: · 441 unmodified lines | ||
| 442 | 442 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 443 | 443 | if (fault & VM_FAULT_OOM) |
| 444 | 444 | goto out_of_memory; |
| 445 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 446 | + goto bad_area; | |
| 445 | 447 | else if (fault & VM_FAULT_SIGBUS) |
| 446 | 448 | goto do_sigbus; |
| 447 | 449 | BUG(); |
| @@ -80,6 +80,8 @@ good_area: · 79 unmodified lines | ||
| 80 | 80 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 81 | 81 | if (fault & VM_FAULT_OOM) { |
| 82 | 82 | goto out_of_memory; |
| 83 | + } else if (fault & VM_FAULT_SIGSEGV) { | |
| 84 | + goto out; | |
| 83 | 85 | } else if (fault & VM_FAULT_SIGBUS) { |
| 84 | 86 | err = -EACCES; |
| 85 | 87 | goto out; |
| @@ -90,7 +90,7 @@ suffix-$(CONFIG_KERNEL_LZO) := lzo · 89 unmodified lines | ||
| 90 | 90 | suffix-$(CONFIG_KERNEL_LZ4) := lz4 |
| 91 | 91 | |
| 92 | 92 | RUN_SIZE = $(shell $(OBJDUMP) -h vmlinux | \ |
| 93 | − perl $(srctree)/arch/x86/tools/calc_run_size.pl) | |
| 93 | + $(CONFIG_SHELL) $(srctree)/arch/x86/tools/calc_run_size.sh) | |
| 94 | 94 | quiet_cmd_mkpiggy = MKPIGGY $@ |
| 95 | 95 | cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) |
| 96 | 96 | |
| @@ -2431,6 +2431,7 @@ __init int intel_pmu_init(void) · 2430 unmodified lines | ||
| 2431 | 2431 | break; |
| 2432 | 2432 | |
| 2433 | 2433 | case 55: /* 22nm Atom "Silvermont" */ |
| 2434 | + case 76: /* 14nm Atom "Airmont" */ | |
| 2434 | 2435 | case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */ |
| 2435 | 2436 | memcpy(hw_cache_event_ids, slm_hw_cache_event_ids, |
| 2436 | 2437 | sizeof(hw_cache_event_ids)); |
| @@ -142,7 +142,7 @@ static inline u64 rapl_scale(u64 v) · 141 unmodified lines | ||
| 142 | 142 | * or use ldexp(count, -32). |
| 143 | 143 | * Watts = Joules/Time delta |
| 144 | 144 | */ |
| 145 | − return v << (32 - __this_cpu_read(rapl_pmu->hw_unit)); | |
| 145 | + return v << (32 - __this_cpu_read(rapl_pmu)->hw_unit); | |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | static u64 rapl_event_update(struct perf_event *event) |
| @@ -840,7 +840,6 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id · 839 unmodified lines | ||
| 840 | 840 | box->phys_id = phys_id; |
| 841 | 841 | box->pci_dev = pdev; |
| 842 | 842 | box->pmu = pmu; |
| 843 | − uncore_box_init(box); | |
| 844 | 843 | pci_set_drvdata(pdev, box); |
| 845 | 844 | |
| 846 | 845 | raw_spin_lock(&uncore_box_lock); |
| @@ -1004,10 +1003,8 @@ static int uncore_cpu_starting(int cpu) · 157 unmodified lines | ||
| 1004 | 1003 | pmu = &type->pmus[j]; |
| 1005 | 1004 | box = *per_cpu_ptr(pmu->box, cpu); |
| 1006 | 1005 | /* called by uncore_cpu_init? */ |
| 1007 | − if (box && box->phys_id >= 0) { | |
| 1008 | − uncore_box_init(box); | |
| 1006 | + if (box && box->phys_id >= 0) | |
| 1009 | 1007 | continue; |
| 1010 | − } | |
| 1011 | 1008 | |
| 1012 | 1009 | for_each_online_cpu(k) { |
| 1013 | 1010 | exist = *per_cpu_ptr(pmu->box, k); |
| @@ -1023,10 +1020,8 @@ static int uncore_cpu_starting(int cpu) · 9 unmodified lines | ||
| 1023 | 1020 | } |
| 1024 | 1021 | } |
| 1025 | 1022 | |
| 1026 | − if (box) { | |
| 1023 | + if (box) | |
| 1027 | 1024 | box->phys_id = phys_id; |
| 1028 | − uncore_box_init(box); | |
| 1029 | − } | |
| 1030 | 1025 | } |
| 1031 | 1026 | } |
| 1032 | 1027 | return 0; |
| @@ -257,6 +257,14 @@ static inline int uncore_num_counters(struct intel_uncore_box *box) · 256 unmodified lines | ||
| 257 | 257 | return box->pmu->type->num_counters; |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | +static inline void uncore_box_init(struct intel_uncore_box *box) | |
| 261 | +{ | |
| 262 | + if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { | |
| 263 | + if (box->pmu->type->ops->init_box) | |
| 264 | + box->pmu->type->ops->init_box(box); | |
| 265 | + } | |
| 266 | +} | |
| 267 | + | |
| 260 | 268 | static inline void uncore_disable_box(struct intel_uncore_box *box) |
| 261 | 269 | { |
| 262 | 270 | if (box->pmu->type->ops->disable_box) |
| @@ -265,6 +273,8 @@ static inline void uncore_disable_box(struct intel_uncore_box *box) · 2 unmodified lines | ||
| 265 | 273 | |
| 266 | 274 | static inline void uncore_enable_box(struct intel_uncore_box *box) |
| 267 | 275 | { |
| 276 | + uncore_box_init(box); | |
| 277 | + | |
| 268 | 278 | if (box->pmu->type->ops->enable_box) |
| 269 | 279 | box->pmu->type->ops->enable_box(box); |
| 270 | 280 | } |
| @@ -287,14 +297,6 @@ static inline u64 uncore_read_counter(struct intel_uncore_box *box, · 16 unmodified lines | ||
| 287 | 297 | return box->pmu->type->ops->read_counter(box, event); |
| 288 | 298 | } |
| 289 | 299 | |
| 290 | −static inline void uncore_box_init(struct intel_uncore_box *box) | |
| 291 | −{ | |
| 292 | − if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { | |
| 293 | − if (box->pmu->type->ops->init_box) | |
| 294 | − box->pmu->type->ops->init_box(box); | |
| 295 | − } | |
| 296 | −} | |
| 297 | − | |
| 298 | 300 | static inline bool uncore_box_is_fake(struct intel_uncore_box *box) |
| 299 | 301 | { |
| 300 | 302 | return (box->phys_id < 0); |
| @@ -192,6 +192,9 @@ static void recalculate_apic_map(struct kvm *kvm) · 191 unmodified lines | ||
| 192 | 192 | u16 cid, lid; |
| 193 | 193 | u32 ldr, aid; |
| 194 | 194 | |
| 195 | + if (!kvm_apic_present(vcpu)) | |
| 196 | + continue; | |
| 197 | + | |
| 195 | 198 | aid = kvm_apic_id(apic); |
| 196 | 199 | ldr = kvm_apic_get_reg(apic, APIC_LDR); |
| 197 | 200 | cid = apic_cluster_id(new, ldr); |
| @@ -898,6 +898,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, · 897 unmodified lines | ||
| 898 | 898 | if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| |
| 899 | 899 | VM_FAULT_HWPOISON_LARGE)) |
| 900 | 900 | do_sigbus(regs, error_code, address, fault); |
| 901 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 902 | + bad_area_nosemaphore(regs, error_code, address); | |
| 901 | 903 | else |
| 902 | 904 | BUG(); |
| 903 | 905 | } |
| @@ -1,39 +0,0 @@ | ||
| 1 | −#!/usr/bin/perl | |
| 2 | −# | |
| 3 | −# Calculate the amount of space needed to run the kernel, including room for | |
| 4 | −# the .bss and .brk sections. | |
| 5 | −# | |
| 6 | −# Usage: | |
| 7 | −# objdump -h a.out | perl calc_run_size.pl | |
| 8 | −use strict; | |
| 9 | − | |
| 10 | −my $mem_size = 0; | |
| 11 | −my $file_offset = 0; | |
| 12 | − | |
| 13 | −my $sections=" *[0-9]+ \.(?:bss|brk) +"; | |
| 14 | −while (<>) { | |
| 15 | − if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) { | |
| 16 | − my $size = hex($1); | |
| 17 | − my $offset = hex($2); | |
| 18 | − $mem_size += $size; | |
| 19 | − if ($file_offset == 0) { | |
| 20 | − $file_offset = $offset; | |
| 21 | − } elsif ($file_offset != $offset) { | |
| 22 | − # BFD linker shows the same file offset in ELF. | |
| 23 | − # Gold linker shows them as consecutive. | |
| 24 | − next if ($file_offset + $mem_size == $offset + $size); | |
| 25 | − | |
| 26 | − printf STDERR "file_offset: 0x%lx\n", $file_offset; | |
| 27 | − printf STDERR "mem_size: 0x%lx\n", $mem_size; | |
| 28 | − printf STDERR "offset: 0x%lx\n", $offset; | |
| 29 | − printf STDERR "size: 0x%lx\n", $size; | |
| 30 | − | |
| 31 | − die ".bss and .brk are non-contiguous\n"; | |
| 32 | − } | |
| 33 | − } | |
| 34 | −} | |
| 35 | − | |
| 36 | −if ($file_offset == 0) { | |
| 37 | − die "Never found .bss or .brk file offset\n"; | |
| 38 | −} | |
| 39 | −printf("%d\n", $mem_size + $file_offset); | |
| @@ -0,0 +1,42 @@ | ||
| 1 | +#!/bin/sh | |
| 2 | +# | |
| 3 | +# Calculate the amount of space needed to run the kernel, including room for | |
| 4 | +# the .bss and .brk sections. | |
| 5 | +# | |
| 6 | +# Usage: | |
| 7 | +# objdump -h a.out | sh calc_run_size.sh | |
| 8 | + | |
| 9 | +NUM='\([0-9a-fA-F]*[ \t]*\)' | |
| 10 | +OUT=$(sed -n 's/^[ \t0-9]*.b[sr][sk][ \t]*'"$NUM$NUM$NUM$NUM"'.*/\1\4/p') | |
| 11 | +if [ -z "$OUT" ] ; then | |
| 12 | + echo "Never found .bss or .brk file offset" >&2 | |
| 13 | + exit 1 | |
| 14 | +fi | |
| 15 | + | |
| 16 | +OUT=$(echo ${OUT# }) | |
| 17 | +sizeA=$(printf "%d" 0x${OUT%% *}) | |
| 18 | +OUT=${OUT#* } | |
| 19 | +offsetA=$(printf "%d" 0x${OUT%% *}) | |
| 20 | +OUT=${OUT#* } | |
| 21 | +sizeB=$(printf "%d" 0x${OUT%% *}) | |
| 22 | +OUT=${OUT#* } | |
| 23 | +offsetB=$(printf "%d" 0x${OUT%% *}) | |
| 24 | + | |
| 25 | +run_size=$(( $offsetA + $sizeA + $sizeB )) | |
| 26 | + | |
| 27 | +# BFD linker shows the same file offset in ELF. | |
| 28 | +if [ "$offsetA" -ne "$offsetB" ] ; then | |
| 29 | + # Gold linker shows them as consecutive. | |
| 30 | + endB=$(( $offsetB + $sizeB )) | |
| 31 | + if [ "$endB" != "$run_size" ] ; then | |
| 32 | + printf "sizeA: 0x%x\n" $sizeA >&2 | |
| 33 | + printf "offsetA: 0x%x\n" $offsetA >&2 | |
| 34 | + printf "sizeB: 0x%x\n" $sizeB >&2 | |
| 35 | + printf "offsetB: 0x%x\n" $offsetB >&2 | |
| 36 | + echo ".bss and .brk are non-contiguous" >&2 | |
| 37 | + exit 1 | |
| 38 | + fi | |
| 39 | +fi | |
| 40 | + | |
| 41 | +printf "%d\n" $run_size | |
| 42 | +exit 0 | |
| @@ -117,6 +117,8 @@ good_area: · 116 unmodified lines | ||
| 117 | 117 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 118 | 118 | if (fault & VM_FAULT_OOM) |
| 119 | 119 | goto out_of_memory; |
| 120 | + else if (fault & VM_FAULT_SIGSEGV) | |
| 121 | + goto bad_area; | |
| 120 | 122 | else if (fault & VM_FAULT_SIGBUS) |
| 121 | 123 | goto do_sigbus; |
| 122 | 124 | BUG(); |
| @@ -134,8 +134,6 @@ source "drivers/staging/Kconfig" · 133 unmodified lines | ||
| 134 | 134 | |
| 135 | 135 | source "drivers/platform/Kconfig" |
| 136 | 136 | |
| 137 | −source "drivers/soc/Kconfig" | |
| 138 | − | |
| 139 | 137 | source "drivers/clk/Kconfig" |
| 140 | 138 | |
| 141 | 139 | source "drivers/hwspinlock/Kconfig" |
| @@ -2098,32 +2098,26 @@ static void rbd_dev_parent_put(struct rbd_device *rbd_dev) · 2097 unmodified lines | ||
| 2098 | 2098 | * If an image has a non-zero parent overlap, get a reference to its |
| 2099 | 2099 | * parent. |
| 2100 | 2100 | * |
| 2101 | − * We must get the reference before checking for the overlap to | |
| 2102 | − * coordinate properly with zeroing the parent overlap in | |
| 2103 | − * rbd_dev_v2_parent_info() when an image gets flattened. We | |
| 2104 | − * drop it again if there is no overlap. | |
| 2105 | − * | |
| 2106 | 2101 | * Returns true if the rbd device has a parent with a non-zero |
| 2107 | 2102 | * overlap and a reference for it was successfully taken, or |
| 2108 | 2103 | * false otherwise. |
| 2109 | 2104 | */ |
| 2110 | 2105 | static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) |
| 2111 | 2106 | { |
| 2112 | − int counter; | |
| 2107 | + int counter = 0; | |
| 2113 | 2108 | |
| 2114 | 2109 | if (!rbd_dev->parent_spec) |
| 2115 | 2110 | return false; |
| 2116 | 2111 | |
| 2117 | − counter = atomic_inc_return_safe(&rbd_dev->parent_ref); | |
| 2118 | − if (counter > 0 && rbd_dev->parent_overlap) | |
| 2119 | − return true; | |
| 2120 | − | |
| 2121 | − /* Image was flattened, but parent is not yet torn down */ | |
| 2112 | + down_read(&rbd_dev->header_rwsem); | |
| 2113 | + if (rbd_dev->parent_overlap) | |
| 2114 | + counter = atomic_inc_return_safe(&rbd_dev->parent_ref); | |
| 2115 | + up_read(&rbd_dev->header_rwsem); | |
| 2122 | 2116 | |
| 2123 | 2117 | if (counter < 0) |
| 2124 | 2118 | rbd_warn(rbd_dev, "parent reference overflow"); |
| 2125 | 2119 | |
| 2126 | − return false; | |
| 2120 | + return counter > 0; | |
| 2127 | 2121 | } |
| 2128 | 2122 | |
| 2129 | 2123 | /* |
| @@ -4239,7 +4233,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) · 2109 unmodified lines | ||
| 4239 | 4233 | */ |
| 4240 | 4234 | if (rbd_dev->parent_overlap) { |
| 4241 | 4235 | rbd_dev->parent_overlap = 0; |
| 4242 | − smp_mb(); | |
| 4243 | 4236 | rbd_dev_parent_put(rbd_dev); |
| 4244 | 4237 | pr_info("%s: clone image has been flattened\n", |
| 4245 | 4238 | rbd_dev->disk->disk_name); |
| @@ -4285,7 +4278,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) · 39 unmodified lines | ||
| 4285 | 4278 | * treat it specially. |
| 4286 | 4279 | */ |
| 4287 | 4280 | rbd_dev->parent_overlap = overlap; |
| 4288 | − smp_mb(); | |
| 4289 | 4281 | if (!overlap) { |
| 4290 | 4282 | |
| 4291 | 4283 | /* A null parent_spec indicates it's the initial probe */ |
| @@ -5114,10 +5106,7 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) · 822 unmodified lines | ||
| 5114 | 5106 | { |
| 5115 | 5107 | struct rbd_image_header *header; |
| 5116 | 5108 | |
| 5117 | − /* Drop parent reference unless it's already been done (or none) */ | |
| 5118 | − | |
| 5119 | − if (rbd_dev->parent_overlap) | |
| 5120 | − rbd_dev_parent_put(rbd_dev); | |
| 5109 | + rbd_dev_parent_put(rbd_dev); | |
| 5121 | 5110 | |
| 5122 | 5111 | /* Free dynamic fields from the header, then zero it out */ |
| 5123 | 5112 | |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/slab.h> |
| 27 | 27 | #include "kfd_priv.h" |
| 28 | 28 | #include "kfd_device_queue_manager.h" |
| 29 | +#include "kfd_pm4_headers.h" | |
| 29 | 30 | |
| 30 | 31 | #define MQD_SIZE_ALIGNED 768 |
| 31 | 32 | |
| @@ -169,9 +170,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, · 137 unmodified lines | ||
| 169 | 170 | kfd->shared_resources = *gpu_resources; |
| 170 | 171 | |
| 171 | 172 | /* calculate max size of mqds needed for queues */ |
| 172 | − size = max_num_of_processes * | |
| 173 | − max_num_of_queues_per_process * | |
| 174 | − kfd->device_info->mqd_size_aligned; | |
| 173 | + size = max_num_of_queues_per_device * | |
| 174 | + kfd->device_info->mqd_size_aligned; | |
| 175 | 175 | |
| 176 | 176 | /* add another 512KB for all other allocations on gart */ |
| 177 | 177 | size += 512 * 1024; |
| @@ -183,6 +183,13 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, · 182 unmodified lines | ||
| 183 | 183 | |
| 184 | 184 | mutex_lock(&dqm->lock); |
| 185 | 185 | |
| 186 | + if (dqm->total_queue_count >= max_num_of_queues_per_device) { | |
| 187 | + pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n", | |
| 188 | + dqm->total_queue_count); | |
| 189 | + mutex_unlock(&dqm->lock); | |
| 190 | + return -EPERM; | |
| 191 | + } | |
| 192 | + | |
| 186 | 193 | if (list_empty(&qpd->queues_list)) { |
| 187 | 194 | retval = allocate_vmid(dqm, qpd, q); |
| 188 | 195 | if (retval != 0) { |
| @@ -207,6 +214,14 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, · 18 unmodified lines | ||
| 207 | 214 | list_add(&q->list, &qpd->queues_list); |
| 208 | 215 | dqm->queue_count++; |
| 209 | 216 | |
| 217 | + /* | |
| 218 | + * Unconditionally increment this counter, regardless of the queue's | |
| 219 | + * type or whether the queue is active. | |
| 220 | + */ | |
| 221 | + dqm->total_queue_count++; | |
| 222 | + pr_debug("Total of %d queues are accountable so far\n", | |
| 223 | + dqm->total_queue_count); | |
| 224 | + | |
| 210 | 225 | mutex_unlock(&dqm->lock); |
| 211 | 226 | return 0; |
| 212 | 227 | } |
| @@ -326,6 +341,15 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, · 113 unmodified lines | ||
| 326 | 341 | if (list_empty(&qpd->queues_list)) |
| 327 | 342 | deallocate_vmid(dqm, qpd, q); |
| 328 | 343 | dqm->queue_count--; |
| 344 | + | |
| 345 | + /* | |
| 346 | + * Unconditionally decrement this counter, regardless of the queue's | |
| 347 | + * type | |
| 348 | + */ | |
| 349 | + dqm->total_queue_count--; | |
| 350 | + pr_debug("Total of %d queues are accountable so far\n", | |
| 351 | + dqm->total_queue_count); | |
| 352 | + | |
| 329 | 353 | out: |
| 330 | 354 | mutex_unlock(&dqm->lock); |
| 331 | 355 | return retval; |
| @@ -541,10 +565,14 @@ static int init_pipelines(struct device_queue_manager *dqm, · 209 unmodified lines | ||
| 541 | 565 | |
| 542 | 566 | for (i = 0; i < pipes_num; i++) { |
| 543 | 567 | inx = i + first_pipe; |
| 568 | + /* | |
| 569 | + * HPD buffer on GTT is allocated by amdkfd, no need to waste | |
| 570 | + * space in GTT for pipelines we don't initialize | |
| 571 | + */ | |
| 544 | 572 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; |
| 545 | 573 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); |
| 546 | 574 | /* = log2(bytes/4)-1 */ |
| 547 | − kfd2kgd->init_pipeline(dqm->dev->kgd, i, | |
| 575 | + kfd2kgd->init_pipeline(dqm->dev->kgd, inx, | |
| 548 | 576 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); |
| 549 | 577 | } |
| 550 | 578 | |
| @@ -560,7 +588,7 @@ static int init_scheduler(struct device_queue_manager *dqm) · 9 unmodified lines | ||
| 560 | 588 | |
| 561 | 589 | pr_debug("kfd: In %s\n", __func__); |
| 562 | 590 | |
| 563 | − retval = init_pipelines(dqm, get_pipes_num(dqm), KFD_DQM_FIRST_PIPE); | |
| 591 | + retval = init_pipelines(dqm, get_pipes_num(dqm), get_first_pipe(dqm)); | |
| 564 | 592 | if (retval != 0) |
| 565 | 593 | return retval; |
| 566 | 594 | |
| @@ -752,6 +780,21 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, · 185 unmodified lines | ||
| 752 | 780 | pr_debug("kfd: In func %s\n", __func__); |
| 753 | 781 | |
| 754 | 782 | mutex_lock(&dqm->lock); |
| 783 | + if (dqm->total_queue_count >= max_num_of_queues_per_device) { | |
| 784 | + pr_warn("amdkfd: Can't create new kernel queue because %d queues were already created\n", | |
| 785 | + dqm->total_queue_count); | |
| 786 | + mutex_unlock(&dqm->lock); | |
| 787 | + return -EPERM; | |
| 788 | + } | |
| 789 | + | |
| 790 | + /* | |
| 791 | + * Unconditionally increment this counter, regardless of the queue's | |
| 792 | + * type or whether the queue is active. | |
| 793 | + */ | |
| 794 | + dqm->total_queue_count++; | |
| 795 | + pr_debug("Total of %d queues are accountable so far\n", | |
| 796 | + dqm->total_queue_count); | |
| 797 | + | |
| 755 | 798 | list_add(&kq->list, &qpd->priv_queue_list); |
| 756 | 799 | dqm->queue_count++; |
| 757 | 800 | qpd->is_debug = true; |
| @@ -775,6 +818,13 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, · 17 unmodified lines | ||
| 775 | 818 | dqm->queue_count--; |
| 776 | 819 | qpd->is_debug = false; |
| 777 | 820 | execute_queues_cpsch(dqm, false); |
| 821 | + /* | |
| 822 | + * Unconditionally decrement this counter, regardless of the queue's | |
| 823 | + * type. | |
| 824 | + */ | |
| 825 | + dqm->total_queue_count++; | |
| 826 | + pr_debug("Total of %d queues are accountable so far\n", | |
| 827 | + dqm->total_queue_count); | |
| 778 | 828 | mutex_unlock(&dqm->lock); |
| 779 | 829 | } |
| 780 | 830 | |
| @@ -793,6 +843,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, · 12 unmodified lines | ||
| 793 | 843 | |
| 794 | 844 | mutex_lock(&dqm->lock); |
| 795 | 845 | |
| 846 | + if (dqm->total_queue_count >= max_num_of_queues_per_device) { | |
| 847 | + pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n", | |
| 848 | + dqm->total_queue_count); | |
| 849 | + retval = -EPERM; | |
| 850 | + goto out; | |
| 851 | + } | |
| 852 | + | |
| 796 | 853 | mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); |
| 797 | 854 | if (mqd == NULL) { |
| 798 | 855 | mutex_unlock(&dqm->lock); |
| @@ -810,6 +867,15 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, · 11 unmodified lines | ||
| 810 | 867 | retval = execute_queues_cpsch(dqm, false); |
| 811 | 868 | } |
| 812 | 869 | |
| 870 | + /* | |
| 871 | + * Unconditionally increment this counter, regardless of the queue's | |
| 872 | + * type or whether the queue is active. | |
| 873 | + */ | |
| 874 | + dqm->total_queue_count++; | |
| 875 | + | |
| 876 | + pr_debug("Total of %d queues are accountable so far\n", | |
| 877 | + dqm->total_queue_count); | |
| 878 | + | |
| 813 | 879 | out: |
| 814 | 880 | mutex_unlock(&dqm->lock); |
| 815 | 881 | return retval; |
| @@ -930,6 +996,14 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, · 114 unmodified lines | ||
| 930 | 996 | |
| 931 | 997 | mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); |
| 932 | 998 | |
| 999 | + /* | |
| 1000 | + * Unconditionally decrement this counter, regardless of the queue's | |
| 1001 | + * type | |
| 1002 | + */ | |
| 1003 | + dqm->total_queue_count--; | |
| 1004 | + pr_debug("Total of %d queues are accountable so far\n", | |
| 1005 | + dqm->total_queue_count); | |
| 1006 | + | |
| 933 | 1007 | mutex_unlock(&dqm->lock); |
| 934 | 1008 | |
| 935 | 1009 | return 0; |
| @@ -130,6 +130,7 @@ struct device_queue_manager { · 129 unmodified lines | ||
| 130 | 130 | struct list_head queues; |
| 131 | 131 | unsigned int processes_count; |
| 132 | 132 | unsigned int queue_count; |
| 133 | + unsigned int total_queue_count; | |
| 133 | 134 | unsigned int next_pipe_to_allocate; |
| 134 | 135 | unsigned int *allocated_queues; |
| 135 | 136 | unsigned int vmid_bitmap; |
| @@ -50,15 +50,10 @@ module_param(sched_policy, int, 0444); · 49 unmodified lines | ||
| 50 | 50 | MODULE_PARM_DESC(sched_policy, |
| 51 | 51 | "Kernel cmdline parameter that defines the amdkfd scheduling policy"); |
| 52 | 52 | |
| 53 | −int max_num_of_processes = KFD_MAX_NUM_OF_PROCESSES_DEFAULT; | |
| 54 | −module_param(max_num_of_processes, int, 0444); | |
| 55 | −MODULE_PARM_DESC(max_num_of_processes, | |
| 56 | − "Kernel cmdline parameter that defines the amdkfd maximum number of supported processes"); | |
| 57 | − | |
| 58 | −int max_num_of_queues_per_process = KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT; | |
| 59 | −module_param(max_num_of_queues_per_process, int, 0444); | |
| 60 | −MODULE_PARM_DESC(max_num_of_queues_per_process, | |
| 61 | − "Kernel cmdline parameter that defines the amdkfd maximum number of supported queues per process"); | |
| 53 | +int max_num_of_queues_per_device = KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT; | |
| 54 | +module_param(max_num_of_queues_per_device, int, 0444); | |
| 55 | +MODULE_PARM_DESC(max_num_of_queues_per_device, | |
| 56 | + "Maximum number of supported queues per device (1 = Minimum, 4096 = default)"); | |
| 62 | 57 | |
| 63 | 58 | bool kgd2kfd_init(unsigned interface_version, |
| 64 | 59 | const struct kfd2kgd_calls *f2g, |
| @@ -100,16 +95,10 @@ static int __init kfd_module_init(void) · 35 unmodified lines | ||
| 100 | 95 | } |
| 101 | 96 | |
| 102 | 97 | /* Verify module parameters */ |
| 103 | − if ((max_num_of_processes < 0) || | |
| 104 | − (max_num_of_processes > KFD_MAX_NUM_OF_PROCESSES)) { | |
| 105 | − pr_err("kfd: max_num_of_processes must be between 0 to KFD_MAX_NUM_OF_PROCESSES\n"); | |
| 106 | − return -1; | |
| 107 | − } | |
| 108 | − | |
| 109 | − if ((max_num_of_queues_per_process < 0) || | |
| 110 | − (max_num_of_queues_per_process > | |
| 111 | − KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)) { | |
| 112 | − pr_err("kfd: max_num_of_queues_per_process must be between 0 to KFD_MAX_NUM_OF_QUEUES_PER_PROCESS\n"); | |
| 98 | + if ((max_num_of_queues_per_device < 0) || | |
| 99 | + (max_num_of_queues_per_device > | |
| 100 | + KFD_MAX_NUM_OF_QUEUES_PER_DEVICE)) { | |
| 101 | + pr_err("kfd: max_num_of_queues_per_device must be between 0 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n"); | |
| 113 | 102 | return -1; |
| 114 | 103 | } |
| 115 | 104 | |
| @@ -30,7 +30,7 @@ static DEFINE_MUTEX(pasid_mutex); · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | int kfd_pasid_init(void) |
| 32 | 32 | { |
| 33 | − pasid_limit = max_num_of_processes; | |
| 33 | + pasid_limit = KFD_MAX_NUM_OF_PROCESSES; | |
| 34 | 34 | |
| 35 | 35 | pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL); |
| 36 | 36 | if (!pasid_bitmap) |
| @@ -52,20 +52,19 @@ · 51 unmodified lines | ||
| 52 | 52 | #define kfd_alloc_struct(ptr_to_struct) \ |
| 53 | 53 | ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) |
| 54 | 54 | |
| 55 | −/* Kernel module parameter to specify maximum number of supported processes */ | |
| 56 | −extern int max_num_of_processes; | |
| 57 | − | |
| 58 | −#define KFD_MAX_NUM_OF_PROCESSES_DEFAULT 32 | |
| 59 | 55 | #define KFD_MAX_NUM_OF_PROCESSES 512 |
| 56 | +#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 | |
| 60 | 57 | |
| 61 | 58 | /* |
| 62 | − * Kernel module parameter to specify maximum number of supported queues | |
| 63 | − * per process | |
| 59 | + * Kernel module parameter to specify maximum number of supported queues per | |
| 60 | + * device | |
| 64 | 61 | */ |
| 65 | −extern int max_num_of_queues_per_process; | |
| 62 | +extern int max_num_of_queues_per_device; | |
| 66 | 63 | |
| 67 | −#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT 128 | |
| 68 | −#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 | |
| 64 | +#define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT 4096 | |
| 65 | +#define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \ | |
| 66 | + (KFD_MAX_NUM_OF_PROCESSES * \ | |
| 67 | + KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) | |
| 69 | 68 | |
| 70 | 69 | #define KFD_KERNEL_QUEUE_SIZE 2048 |
| 71 | 70 | |
| @@ -54,11 +54,11 @@ static int find_available_queue_slot(struct process_queue_manager *pqm, · 53 unmodified lines | ||
| 54 | 54 | pr_debug("kfd: in %s\n", __func__); |
| 55 | 55 | |
| 56 | 56 | found = find_first_zero_bit(pqm->queue_slot_bitmap, |
| 57 | − max_num_of_queues_per_process); | |
| 57 | + KFD_MAX_NUM_OF_QUEUES_PER_PROCESS); | |
| 58 | 58 | |
| 59 | 59 | pr_debug("kfd: the new slot id %lu\n", found); |
| 60 | 60 | |
| 61 | − if (found >= max_num_of_queues_per_process) { | |
| 61 | + if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) { | |
| 62 | 62 | pr_info("amdkfd: Can not open more queues for process with pasid %d\n", |
| 63 | 63 | pqm->process->pasid); |
| 64 | 64 | return -ENOMEM; |
| @@ -76,7 +76,7 @@ int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) · 11 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | INIT_LIST_HEAD(&pqm->queues); |
| 78 | 78 | pqm->queue_slot_bitmap = |
| 79 | − kzalloc(DIV_ROUND_UP(max_num_of_queues_per_process, | |
| 79 | + kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, | |
| 80 | 80 | BITS_PER_BYTE), GFP_KERNEL); |
| 81 | 81 | if (pqm->queue_slot_bitmap == NULL) |
| 82 | 82 | return -ENOMEM; |
| @@ -203,6 +203,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, · 120 unmodified lines | ||
| 203 | 203 | pqn->kq = NULL; |
| 204 | 204 | retval = dev->dqm->create_queue(dev->dqm, q, &pdd->qpd, |
| 205 | 205 | &q->properties.vmid); |
| 206 | + pr_debug("DQM returned %d for create_queue\n", retval); | |
| 206 | 207 | print_queue(q); |
| 207 | 208 | break; |
| 208 | 209 | case KFD_QUEUE_TYPE_DIQ: |
| @@ -222,7 +223,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, · 13 unmodified lines | ||
| 222 | 223 | } |
| 223 | 224 | |
| 224 | 225 | if (retval != 0) { |
| 225 | − pr_err("kfd: error dqm create queue\n"); | |
| 226 | + pr_debug("Error dqm create queue\n"); | |
| 226 | 227 | goto err_create_queue; |
| 227 | 228 | } |
| 228 | 229 | |
| @@ -241,7 +242,10 @@ int pqm_create_queue(struct process_queue_manager *pqm, · 12 unmodified lines | ||
| 241 | 242 | err_create_queue: |
| 242 | 243 | kfree(pqn); |
| 243 | 244 | err_allocate_pqn: |
| 245 | + /* check if queues list is empty unregister process from device */ | |
| 244 | 246 | clear_bit(*qid, pqm->queue_slot_bitmap); |
| 247 | + if (list_empty(&pqm->queues)) | |
| 248 | + dev->dqm->unregister_process(dev->dqm, &pdd->qpd); | |
| 245 | 249 | return retval; |
| 246 | 250 | } |
| 247 | 251 | |
| @@ -145,6 +145,31 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_ · 144 unmodified lines | ||
| 145 | 145 | } |
| 146 | 146 | EXPORT_SYMBOL(drm_fb_helper_add_one_connector); |
| 147 | 147 | |
| 148 | +static void remove_from_modeset(struct drm_mode_set *set, | |
| 149 | + struct drm_connector *connector) | |
| 150 | +{ | |
| 151 | + int i, j; | |
| 152 | + | |
| 153 | + for (i = 0; i < set->num_connectors; i++) { | |
| 154 | + if (set->connectors[i] == connector) | |
| 155 | + break; | |
| 156 | + } | |
| 157 | + | |
| 158 | + if (i == set->num_connectors) | |
| 159 | + return; | |
| 160 | + | |
| 161 | + for (j = i + 1; j < set->num_connectors; j++) { | |
| 162 | + set->connectors[j - 1] = set->connectors[j]; | |
| 163 | + } | |
| 164 | + set->num_connectors--; | |
| 165 | + | |
| 166 | + /* because i915 is pissy about this.. | |
| 167 | + * TODO maybe need to makes sure we set it back to !=NULL somewhere? | |
| 168 | + */ | |
| 169 | + if (set->num_connectors == 0) | |
| 170 | + set->fb = NULL; | |
| 171 | +} | |
| 172 | + | |
| 148 | 173 | int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, |
| 149 | 174 | struct drm_connector *connector) |
| 150 | 175 | { |
| @@ -167,6 +192,11 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, · 16 unmodified lines | ||
| 167 | 192 | } |
| 168 | 193 | fb_helper->connector_count--; |
| 169 | 194 | kfree(fb_helper_connector); |
| 195 | + | |
| 196 | + /* also cleanup dangling references to the connector: */ | |
| 197 | + for (i = 0; i < fb_helper->crtc_count; i++) | |
| 198 | + remove_from_modeset(&fb_helper->crtc_info[i].mode_set, connector); | |
| 199 | + | |
| 170 | 200 | return 0; |
| 171 | 201 | } |
| 172 | 202 | EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | struct tda998x_priv { |
| 33 | 33 | struct i2c_client *cec; |
| 34 | 34 | struct i2c_client *hdmi; |
| 35 | + struct mutex mutex; | |
| 36 | + struct delayed_work dwork; | |
| 35 | 37 | uint16_t rev; |
| 36 | 38 | uint8_t current_page; |
| 37 | 39 | int dpms; |
| @@ -402,9 +404,10 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) · 364 unmodified lines | ||
| 402 | 404 | uint8_t addr = REG2ADDR(reg); |
| 403 | 405 | int ret; |
| 404 | 406 | |
| 407 | + mutex_lock(&priv->mutex); | |
| 405 | 408 | ret = set_page(priv, reg); |
| 406 | 409 | if (ret < 0) |
| 407 | − return ret; | |
| 410 | + goto out; | |
| 408 | 411 | |
| 409 | 412 | ret = i2c_master_send(client, &addr, sizeof(addr)); |
| 410 | 413 | if (ret < 0) |
| @@ -414,10 +417,12 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) · 3 unmodified lines | ||
| 414 | 417 | if (ret < 0) |
| 415 | 418 | goto fail; |
| 416 | 419 | |
| 417 | − return ret; | |
| 420 | + goto out; | |
| 418 | 421 | |
| 419 | 422 | fail: |
| 420 | 423 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); |
| 424 | +out: | |
| 425 | + mutex_unlock(&priv->mutex); | |
| 421 | 426 | return ret; |
| 422 | 427 | } |
| 423 | 428 | |
| @@ -431,13 +436,16 @@ reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) · 7 unmodified lines | ||
| 431 | 436 | buf[0] = REG2ADDR(reg); |
| 432 | 437 | memcpy(&buf[1], p, cnt); |
| 433 | 438 | |
| 439 | + mutex_lock(&priv->mutex); | |
| 434 | 440 | ret = set_page(priv, reg); |
| 435 | 441 | if (ret < 0) |
| 436 | − return; | |
| 442 | + goto out; | |
| 437 | 443 | |
| 438 | 444 | ret = i2c_master_send(client, buf, cnt + 1); |
| 439 | 445 | if (ret < 0) |
| 440 | 446 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 447 | +out: | |
| 448 | + mutex_unlock(&priv->mutex); | |
| 441 | 449 | } |
| 442 | 450 | |
| 443 | 451 | static int |
| @@ -459,13 +467,16 @@ reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) · 15 unmodified lines | ||
| 459 | 467 | uint8_t buf[] = {REG2ADDR(reg), val}; |
| 460 | 468 | int ret; |
| 461 | 469 | |
| 470 | + mutex_lock(&priv->mutex); | |
| 462 | 471 | ret = set_page(priv, reg); |
| 463 | 472 | if (ret < 0) |
| 464 | − return; | |
| 473 | + goto out; | |
| 465 | 474 | |
| 466 | 475 | ret = i2c_master_send(client, buf, sizeof(buf)); |
| 467 | 476 | if (ret < 0) |
| 468 | 477 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 478 | +out: | |
| 479 | + mutex_unlock(&priv->mutex); | |
| 469 | 480 | } |
| 470 | 481 | |
| 471 | 482 | static void |
| @@ -475,13 +486,16 @@ reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) · 3 unmodified lines | ||
| 475 | 486 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; |
| 476 | 487 | int ret; |
| 477 | 488 | |
| 489 | + mutex_lock(&priv->mutex); | |
| 478 | 490 | ret = set_page(priv, reg); |
| 479 | 491 | if (ret < 0) |
| 480 | − return; | |
| 492 | + goto out; | |
| 481 | 493 | |
| 482 | 494 | ret = i2c_master_send(client, buf, sizeof(buf)); |
| 483 | 495 | if (ret < 0) |
| 484 | 496 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 497 | +out: | |
| 498 | + mutex_unlock(&priv->mutex); | |
| 485 | 499 | } |
| 486 | 500 | |
| 487 | 501 | static void |
| @@ -536,6 +550,17 @@ tda998x_reset(struct tda998x_priv *priv) · 48 unmodified lines | ||
| 536 | 550 | reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); |
| 537 | 551 | } |
| 538 | 552 | |
| 553 | +/* handle HDMI connect/disconnect */ | |
| 554 | +static void tda998x_hpd(struct work_struct *work) | |
| 555 | +{ | |
| 556 | + struct delayed_work *dwork = to_delayed_work(work); | |
| 557 | + struct tda998x_priv *priv = | |
| 558 | + container_of(dwork, struct tda998x_priv, dwork); | |
| 559 | + | |
| 560 | + if (priv->encoder && priv->encoder->dev) | |
| 561 | + drm_kms_helper_hotplug_event(priv->encoder->dev); | |
| 562 | +} | |
| 563 | + | |
| 539 | 564 | /* |
| 540 | 565 | * only 2 interrupts may occur: screen plug/unplug and EDID read |
| 541 | 566 | */ |
| @@ -559,8 +584,7 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data) · 17 unmodified lines | ||
| 559 | 584 | priv->wq_edid_wait = 0; |
| 560 | 585 | wake_up(&priv->wq_edid); |
| 561 | 586 | } else if (cec != 0) { /* HPD change */ |
| 562 | − if (priv->encoder && priv->encoder->dev) | |
| 563 | − drm_helper_hpd_irq_event(priv->encoder->dev); | |
| 587 | + schedule_delayed_work(&priv->dwork, HZ/10); | |
| 564 | 588 | } |
| 565 | 589 | return IRQ_HANDLED; |
| 566 | 590 | } |
| @@ -1170,8 +1194,10 @@ static void tda998x_destroy(struct tda998x_priv *priv) · 603 unmodified lines | ||
| 1170 | 1194 | /* disable all IRQs and free the IRQ handler */ |
| 1171 | 1195 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); |
| 1172 | 1196 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); |
| 1173 | − if (priv->hdmi->irq) | |
| 1197 | + if (priv->hdmi->irq) { | |
| 1174 | 1198 | free_irq(priv->hdmi->irq, priv); |
| 1199 | + cancel_delayed_work_sync(&priv->dwork); | |
| 1200 | + } | |
| 1175 | 1201 | |
| 1176 | 1202 | i2c_unregister_device(priv->cec); |
| 1177 | 1203 | } |
| @@ -1255,6 +1281,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) · 77 unmodified lines | ||
| 1255 | 1281 | struct device_node *np = client->dev.of_node; |
| 1256 | 1282 | u32 video; |
| 1257 | 1283 | int rev_lo, rev_hi, ret; |
| 1284 | + unsigned short cec_addr; | |
| 1258 | 1285 | |
| 1259 | 1286 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); |
| 1260 | 1287 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); |
| @@ -1262,12 +1289,16 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) · 1 unmodified line | ||
| 1262 | 1289 | |
| 1263 | 1290 | priv->current_page = 0xff; |
| 1264 | 1291 | priv->hdmi = client; |
| 1265 | − priv->cec = i2c_new_dummy(client->adapter, 0x34); | |
| 1292 | + /* CEC I2C address bound to TDA998x I2C addr by configuration pins */ | |
| 1293 | + cec_addr = 0x34 + (client->addr & 0x03); | |
| 1294 | + priv->cec = i2c_new_dummy(client->adapter, cec_addr); | |
| 1266 | 1295 | if (!priv->cec) |
| 1267 | 1296 | return -ENODEV; |
| 1268 | 1297 | |
| 1269 | 1298 | priv->dpms = DRM_MODE_DPMS_OFF; |
| 1270 | 1299 | |
| 1300 | + mutex_init(&priv->mutex); /* protect the page access */ | |
| 1301 | + | |
| 1271 | 1302 | /* wake up the device: */ |
| 1272 | 1303 | cec_write(priv, REG_CEC_ENAMODS, |
| 1273 | 1304 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); |
| @@ -1323,8 +1354,9 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) · 49 unmodified lines | ||
| 1323 | 1354 | if (client->irq) { |
| 1324 | 1355 | int irqf_trigger; |
| 1325 | 1356 | |
| 1326 | − /* init read EDID waitqueue */ | |
| 1357 | + /* init read EDID waitqueue and HDP work */ | |
| 1327 | 1358 | init_waitqueue_head(&priv->wq_edid); |
| 1359 | + INIT_DELAYED_WORK(&priv->dwork, tda998x_hpd); | |
| 1328 | 1360 | |
| 1329 | 1361 | /* clear pending interrupts */ |
| 1330 | 1362 | reg_read(priv, REG_INT_FLAGS_0); |
| @@ -462,19 +462,13 @@ void intel_detect_pch(struct drm_device *dev) · 461 unmodified lines | ||
| 462 | 462 | } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { |
| 463 | 463 | dev_priv->pch_type = PCH_LPT; |
| 464 | 464 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); |
| 465 | − WARN_ON(!IS_HASWELL(dev)); | |
| 466 | − WARN_ON(IS_HSW_ULT(dev)); | |
| 467 | − } else if (IS_BROADWELL(dev)) { | |
| 468 | − dev_priv->pch_type = PCH_LPT; | |
| 469 | − dev_priv->pch_id = | |
| 470 | − INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; | |
| 471 | − DRM_DEBUG_KMS("This is Broadwell, assuming " | |
| 472 | − "LynxPoint LP PCH\n"); | |
| 465 | + WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); | |
| 466 | + WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); | |
| 473 | 467 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { |
| 474 | 468 | dev_priv->pch_type = PCH_LPT; |
| 475 | 469 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); |
| 476 | − WARN_ON(!IS_HASWELL(dev)); | |
| 477 | − WARN_ON(!IS_HSW_ULT(dev)); | |
| 470 | + WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); | |
| 471 | + WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); | |
| 478 | 472 | } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { |
| 479 | 473 | dev_priv->pch_type = PCH_SPT; |
| 480 | 474 | DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); |
| @@ -2159,8 +2159,7 @@ struct drm_i915_cmd_table { · 2158 unmodified lines | ||
| 2159 | 2159 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ |
| 2160 | 2160 | (INTEL_DEVID(dev) & 0xFF00) == 0x0C00) |
| 2161 | 2161 | #define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \ |
| 2162 | − ((INTEL_DEVID(dev) & 0xf) == 0x2 || \ | |
| 2163 | − (INTEL_DEVID(dev) & 0xf) == 0x6 || \ | |
| 2162 | + ((INTEL_DEVID(dev) & 0xf) == 0x6 || \ | |
| 2164 | 2163 | (INTEL_DEVID(dev) & 0xf) == 0xe)) |
| 2165 | 2164 | #define IS_BDW_GT3(dev) (IS_BROADWELL(dev) && \ |
| 2166 | 2165 | (INTEL_DEVID(dev) & 0x00F0) == 0x0020) |
| @@ -3148,6 +3148,13 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, · 3147 unmodified lines | ||
| 3148 | 3148 | u32 size = i915_gem_obj_ggtt_size(obj); |
| 3149 | 3149 | uint64_t val; |
| 3150 | 3150 | |
| 3151 | + /* Adjust fence size to match tiled area */ | |
| 3152 | + if (obj->tiling_mode != I915_TILING_NONE) { | |
| 3153 | + uint32_t row_size = obj->stride * | |
| 3154 | + (obj->tiling_mode == I915_TILING_Y ? 32 : 8); | |
| 3155 | + size = (size / row_size) * row_size; | |
| 3156 | + } | |
| 3157 | + | |
| 3151 | 3158 | val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & |
| 3152 | 3159 | 0xfffff000) << 32; |
| 3153 | 3160 | val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; |
| @@ -4884,25 +4891,18 @@ i915_gem_init_hw(struct drm_device *dev) · 1730 unmodified lines | ||
| 4884 | 4891 | for (i = 0; i < NUM_L3_SLICES(dev); i++) |
| 4885 | 4892 | i915_gem_l3_remap(&dev_priv->ring[RCS], i); |
| 4886 | 4893 | |
| 4887 | − /* | |
| 4888 | − * XXX: Contexts should only be initialized once. Doing a switch to the | |
| 4889 | − * default context switch however is something we'd like to do after | |
| 4890 | − * reset or thaw (the latter may not actually be necessary for HW, but | |
| 4891 | − * goes with our code better). Context switching requires rings (for | |
| 4892 | − * the do_switch), but before enabling PPGTT. So don't move this. | |
| 4893 | − */ | |
| 4894 | − ret = i915_gem_context_enable(dev_priv); | |
| 4894 | + ret = i915_ppgtt_init_hw(dev); | |
| 4895 | 4895 | if (ret && ret != -EIO) { |
| 4896 | − DRM_ERROR("Context enable failed %d\n", ret); | |
| 4896 | + DRM_ERROR("PPGTT enable failed %d\n", ret); | |
| 4897 | 4897 | i915_gem_cleanup_ringbuffer(dev); |
| 4898 | − | |
| 4899 | − return ret; | |
| 4900 | 4898 | } |
| 4901 | 4899 | |
| 4902 | − ret = i915_ppgtt_init_hw(dev); | |
| 4900 | + ret = i915_gem_context_enable(dev_priv); | |
| 4903 | 4901 | if (ret && ret != -EIO) { |
| 4904 | − DRM_ERROR("PPGTT enable failed %d\n", ret); | |
| 4902 | + DRM_ERROR("Context enable failed %d\n", ret); | |
| 4905 | 4903 | i915_gem_cleanup_ringbuffer(dev); |
| 4904 | + | |
| 4905 | + return ret; | |
| 4906 | 4906 | } |
| 4907 | 4907 | |
| 4908 | 4908 | return ret; |
| @@ -962,7 +962,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) · 961 unmodified lines | ||
| 962 | 962 | |
| 963 | 963 | WARN_ON(panel->backlight.max == 0); |
| 964 | 964 | |
| 965 | − if (panel->backlight.level == 0) { | |
| 965 | + if (panel->backlight.level <= panel->backlight.min) { | |
| 966 | 966 | panel->backlight.level = panel->backlight.max; |
| 967 | 967 | if (panel->backlight.device) |
| 968 | 968 | panel->backlight.device->props.brightness = |
| @@ -816,7 +816,6 @@ void cik_sdma_vm_write_pages(struct radeon_device *rdev, · 815 unmodified lines | ||
| 816 | 816 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
| 817 | 817 | if (flags & R600_PTE_SYSTEM) { |
| 818 | 818 | value = radeon_vm_map_gart(rdev, addr); |
| 819 | − value &= 0xFFFFFFFFFFFFF000ULL; | |
| 820 | 819 | } else if (flags & R600_PTE_VALID) { |
| 821 | 820 | value = addr; |
| 822 | 821 | } else { |
| @@ -372,7 +372,6 @@ void cayman_dma_vm_write_pages(struct radeon_device *rdev, · 371 unmodified lines | ||
| 372 | 372 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
| 373 | 373 | if (flags & R600_PTE_SYSTEM) { |
| 374 | 374 | value = radeon_vm_map_gart(rdev, addr); |
| 375 | − value &= 0xFFFFFFFFFFFFF000ULL; | |
| 376 | 375 | } else if (flags & R600_PTE_VALID) { |
| 377 | 376 | value = addr; |
| 378 | 377 | } else { |
| @@ -644,6 +644,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) · 643 unmodified lines | ||
| 644 | 644 | return r; |
| 645 | 645 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
| 646 | 646 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
| 647 | + rdev->asic->gart.get_page_entry = &r100_pci_gart_get_page_entry; | |
| 647 | 648 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
| 648 | 649 | return radeon_gart_table_ram_alloc(rdev); |
| 649 | 650 | } |
| @@ -681,11 +682,16 @@ void r100_pci_gart_disable(struct radeon_device *rdev) · 31 unmodified lines | ||
| 681 | 682 | WREG32(RADEON_AIC_HI_ADDR, 0); |
| 682 | 683 | } |
| 683 | 684 | |
| 685 | +uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags) | |
| 686 | +{ | |
| 687 | + return addr; | |
| 688 | +} | |
| 689 | + | |
| 684 | 690 | void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, |
| 685 | − uint64_t addr, uint32_t flags) | |
| 691 | + uint64_t entry) | |
| 686 | 692 | { |
| 687 | 693 | u32 *gtt = rdev->gart.ptr; |
| 688 | − gtt[i] = cpu_to_le32(lower_32_bits(addr)); | |
| 694 | + gtt[i] = cpu_to_le32(lower_32_bits(entry)); | |
| 689 | 695 | } |
| 690 | 696 | |
| 691 | 697 | void r100_pci_gart_fini(struct radeon_device *rdev) |
| @@ -73,11 +73,8 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) · 72 unmodified lines | ||
| 73 | 73 | #define R300_PTE_WRITEABLE (1 << 2) |
| 74 | 74 | #define R300_PTE_READABLE (1 << 3) |
| 75 | 75 | |
| 76 | −void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, | |
| 77 | − uint64_t addr, uint32_t flags) | |
| 76 | +uint64_t rv370_pcie_gart_get_page_entry(uint64_t addr, uint32_t flags) | |
| 78 | 77 | { |
| 79 | − void __iomem *ptr = rdev->gart.ptr; | |
| 80 | − | |
| 81 | 78 | addr = (lower_32_bits(addr) >> 8) | |
| 82 | 79 | ((upper_32_bits(addr) & 0xff) << 24); |
| 83 | 80 | if (flags & RADEON_GART_PAGE_READ) |
| @@ -86,10 +83,18 @@ void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, · 2 unmodified lines | ||
| 86 | 83 | addr |= R300_PTE_WRITEABLE; |
| 87 | 84 | if (!(flags & RADEON_GART_PAGE_SNOOP)) |
| 88 | 85 | addr |= R300_PTE_UNSNOOPED; |
| 86 | + return addr; | |
| 87 | +} | |
| 88 | + | |
| 89 | +void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, | |
| 90 | + uint64_t entry) | |
| 91 | +{ | |
| 92 | + void __iomem *ptr = rdev->gart.ptr; | |
| 93 | + | |
| 89 | 94 | /* on x86 we want this to be CPU endian, on powerpc |
| 90 | 95 | * on powerpc without HW swappers, it'll get swapped on way |
| 91 | 96 | * into VRAM - so no need for cpu_to_le32 on VRAM tables */ |
| 92 | − writel(addr, ((void __iomem *)ptr) + (i * 4)); | |
| 97 | + writel(entry, ((void __iomem *)ptr) + (i * 4)); | |
| 93 | 98 | } |
| 94 | 99 | |
| 95 | 100 | int rv370_pcie_gart_init(struct radeon_device *rdev) |
| @@ -109,6 +114,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) · 13 unmodified lines | ||
| 109 | 114 | DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); |
| 110 | 115 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
| 111 | 116 | rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; |
| 117 | + rdev->asic->gart.get_page_entry = &rv370_pcie_gart_get_page_entry; | |
| 112 | 118 | rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; |
| 113 | 119 | return radeon_gart_table_vram_alloc(rdev); |
| 114 | 120 | } |
| @@ -242,6 +242,7 @@ bool radeon_get_bios(struct radeon_device *rdev); · 241 unmodified lines | ||
| 242 | 242 | * Dummy page |
| 243 | 243 | */ |
| 244 | 244 | struct radeon_dummy_page { |
| 245 | + uint64_t entry; | |
| 245 | 246 | struct page *page; |
| 246 | 247 | dma_addr_t addr; |
| 247 | 248 | }; |
| @@ -645,7 +646,7 @@ struct radeon_gart { · 397 unmodified lines | ||
| 645 | 646 | unsigned num_cpu_pages; |
| 646 | 647 | unsigned table_size; |
| 647 | 648 | struct page **pages; |
| 648 | − dma_addr_t *pages_addr; | |
| 649 | + uint64_t *pages_entry; | |
| 649 | 650 | bool ready; |
| 650 | 651 | }; |
| 651 | 652 | |
| @@ -1847,8 +1848,9 @@ struct radeon_asic { · 1195 unmodified lines | ||
| 1847 | 1848 | /* gart */ |
| 1848 | 1849 | struct { |
| 1849 | 1850 | void (*tlb_flush)(struct radeon_device *rdev); |
| 1851 | + uint64_t (*get_page_entry)(uint64_t addr, uint32_t flags); | |
| 1850 | 1852 | void (*set_page)(struct radeon_device *rdev, unsigned i, |
| 1851 | − uint64_t addr, uint32_t flags); | |
| 1853 | + uint64_t entry); | |
| 1852 | 1854 | } gart; |
| 1853 | 1855 | struct { |
| 1854 | 1856 | int (*init)(struct radeon_device *rdev); |
| @@ -2852,7 +2854,8 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) · 997 unmodified lines | ||
| 2852 | 2854 | #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) |
| 2853 | 2855 | #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) |
| 2854 | 2856 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) |
| 2855 | −#define radeon_gart_set_page(rdev, i, p, f) (rdev)->asic->gart.set_page((rdev), (i), (p), (f)) | |
| 2857 | +#define radeon_gart_get_page_entry(a, f) (rdev)->asic->gart.get_page_entry((a), (f)) | |
| 2858 | +#define radeon_gart_set_page(rdev, i, e) (rdev)->asic->gart.set_page((rdev), (i), (e)) | |
| 2856 | 2859 | #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) |
| 2857 | 2860 | #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) |
| 2858 | 2861 | #define radeon_asic_vm_copy_pages(rdev, ib, pe, src, count) ((rdev)->asic->vm.copy_pages((rdev), (ib), (pe), (src), (count))) |
| @@ -159,11 +159,13 @@ void radeon_agp_disable(struct radeon_device *rdev) · 158 unmodified lines | ||
| 159 | 159 | DRM_INFO("Forcing AGP to PCIE mode\n"); |
| 160 | 160 | rdev->flags |= RADEON_IS_PCIE; |
| 161 | 161 | rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; |
| 162 | + rdev->asic->gart.get_page_entry = &rv370_pcie_gart_get_page_entry; | |
| 162 | 163 | rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; |
| 163 | 164 | } else { |
| 164 | 165 | DRM_INFO("Forcing AGP to PCI mode\n"); |
| 165 | 166 | rdev->flags |= RADEON_IS_PCI; |
| 166 | 167 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
| 168 | + rdev->asic->gart.get_page_entry = &r100_pci_gart_get_page_entry; | |
| 167 | 169 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
| 168 | 170 | } |
| 169 | 171 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
| @@ -199,6 +201,7 @@ static struct radeon_asic r100_asic = { · 29 unmodified lines | ||
| 199 | 201 | .mc_wait_for_idle = &r100_mc_wait_for_idle, |
| 200 | 202 | .gart = { |
| 201 | 203 | .tlb_flush = &r100_pci_gart_tlb_flush, |
| 204 | + .get_page_entry = &r100_pci_gart_get_page_entry, | |
| 202 | 205 | .set_page = &r100_pci_gart_set_page, |
| 203 | 206 | }, |
| 204 | 207 | .ring = { |
| @@ -265,6 +268,7 @@ static struct radeon_asic r200_asic = { · 60 unmodified lines | ||
| 265 | 268 | .mc_wait_for_idle = &r100_mc_wait_for_idle, |
| 266 | 269 | .gart = { |
| 267 | 270 | .tlb_flush = &r100_pci_gart_tlb_flush, |
| 271 | + .get_page_entry = &r100_pci_gart_get_page_entry, | |
| 268 | 272 | .set_page = &r100_pci_gart_set_page, |
| 269 | 273 | }, |
| 270 | 274 | .ring = { |
| @@ -359,6 +363,7 @@ static struct radeon_asic r300_asic = { · 88 unmodified lines | ||
| 359 | 363 | .mc_wait_for_idle = &r300_mc_wait_for_idle, |
| 360 | 364 | .gart = { |
| 361 | 365 | .tlb_flush = &r100_pci_gart_tlb_flush, |
| 366 | + .get_page_entry = &r100_pci_gart_get_page_entry, | |
| 362 | 367 | .set_page = &r100_pci_gart_set_page, |
| 363 | 368 | }, |
| 364 | 369 | .ring = { |
| @@ -425,6 +430,7 @@ static struct radeon_asic r300_asic_pcie = { · 60 unmodified lines | ||
| 425 | 430 | .mc_wait_for_idle = &r300_mc_wait_for_idle, |
| 426 | 431 | .gart = { |
| 427 | 432 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| 433 | + .get_page_entry = &rv370_pcie_gart_get_page_entry, | |
| 428 | 434 | .set_page = &rv370_pcie_gart_set_page, |
| 429 | 435 | }, |
| 430 | 436 | .ring = { |
| @@ -491,6 +497,7 @@ static struct radeon_asic r420_asic = { · 60 unmodified lines | ||
| 491 | 497 | .mc_wait_for_idle = &r300_mc_wait_for_idle, |
| 492 | 498 | .gart = { |
| 493 | 499 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| 500 | + .get_page_entry = &rv370_pcie_gart_get_page_entry, | |
| 494 | 501 | .set_page = &rv370_pcie_gart_set_page, |
| 495 | 502 | }, |
| 496 | 503 | .ring = { |
| @@ -557,6 +564,7 @@ static struct radeon_asic rs400_asic = { · 60 unmodified lines | ||
| 557 | 564 | .mc_wait_for_idle = &rs400_mc_wait_for_idle, |
| 558 | 565 | .gart = { |
| 559 | 566 | .tlb_flush = &rs400_gart_tlb_flush, |
| 567 | + .get_page_entry = &rs400_gart_get_page_entry, | |
| 560 | 568 | .set_page = &rs400_gart_set_page, |
| 561 | 569 | }, |
| 562 | 570 | .ring = { |
| @@ -623,6 +631,7 @@ static struct radeon_asic rs600_asic = { · 60 unmodified lines | ||
| 623 | 631 | .mc_wait_for_idle = &rs600_mc_wait_for_idle, |
| 624 | 632 | .gart = { |
| 625 | 633 | .tlb_flush = &rs600_gart_tlb_flush, |
| 634 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 626 | 635 | .set_page = &rs600_gart_set_page, |
| 627 | 636 | }, |
| 628 | 637 | .ring = { |
| @@ -691,6 +700,7 @@ static struct radeon_asic rs690_asic = { · 62 unmodified lines | ||
| 691 | 700 | .mc_wait_for_idle = &rs690_mc_wait_for_idle, |
| 692 | 701 | .gart = { |
| 693 | 702 | .tlb_flush = &rs400_gart_tlb_flush, |
| 703 | + .get_page_entry = &rs400_gart_get_page_entry, | |
| 694 | 704 | .set_page = &rs400_gart_set_page, |
| 695 | 705 | }, |
| 696 | 706 | .ring = { |
| @@ -759,6 +769,7 @@ static struct radeon_asic rv515_asic = { · 62 unmodified lines | ||
| 759 | 769 | .mc_wait_for_idle = &rv515_mc_wait_for_idle, |
| 760 | 770 | .gart = { |
| 761 | 771 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| 772 | + .get_page_entry = &rv370_pcie_gart_get_page_entry, | |
| 762 | 773 | .set_page = &rv370_pcie_gart_set_page, |
| 763 | 774 | }, |
| 764 | 775 | .ring = { |
| @@ -825,6 +836,7 @@ static struct radeon_asic r520_asic = { · 60 unmodified lines | ||
| 825 | 836 | .mc_wait_for_idle = &r520_mc_wait_for_idle, |
| 826 | 837 | .gart = { |
| 827 | 838 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| 839 | + .get_page_entry = &rv370_pcie_gart_get_page_entry, | |
| 828 | 840 | .set_page = &rv370_pcie_gart_set_page, |
| 829 | 841 | }, |
| 830 | 842 | .ring = { |
| @@ -919,6 +931,7 @@ static struct radeon_asic r600_asic = { · 88 unmodified lines | ||
| 919 | 931 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 920 | 932 | .gart = { |
| 921 | 933 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
| 934 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 922 | 935 | .set_page = &rs600_gart_set_page, |
| 923 | 936 | }, |
| 924 | 937 | .ring = { |
| @@ -1004,6 +1017,7 @@ static struct radeon_asic rv6xx_asic = { · 79 unmodified lines | ||
| 1004 | 1017 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1005 | 1018 | .gart = { |
| 1006 | 1019 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
| 1020 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1007 | 1021 | .set_page = &rs600_gart_set_page, |
| 1008 | 1022 | }, |
| 1009 | 1023 | .ring = { |
| @@ -1095,6 +1109,7 @@ static struct radeon_asic rs780_asic = { · 85 unmodified lines | ||
| 1095 | 1109 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1096 | 1110 | .gart = { |
| 1097 | 1111 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
| 1112 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1098 | 1113 | .set_page = &rs600_gart_set_page, |
| 1099 | 1114 | }, |
| 1100 | 1115 | .ring = { |
| @@ -1199,6 +1214,7 @@ static struct radeon_asic rv770_asic = { · 98 unmodified lines | ||
| 1199 | 1214 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1200 | 1215 | .gart = { |
| 1201 | 1216 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
| 1217 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1202 | 1218 | .set_page = &rs600_gart_set_page, |
| 1203 | 1219 | }, |
| 1204 | 1220 | .ring = { |
| @@ -1317,6 +1333,7 @@ static struct radeon_asic evergreen_asic = { · 112 unmodified lines | ||
| 1317 | 1333 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1318 | 1334 | .gart = { |
| 1319 | 1335 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| 1336 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1320 | 1337 | .set_page = &rs600_gart_set_page, |
| 1321 | 1338 | }, |
| 1322 | 1339 | .ring = { |
| @@ -1409,6 +1426,7 @@ static struct radeon_asic sumo_asic = { · 86 unmodified lines | ||
| 1409 | 1426 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1410 | 1427 | .gart = { |
| 1411 | 1428 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| 1429 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1412 | 1430 | .set_page = &rs600_gart_set_page, |
| 1413 | 1431 | }, |
| 1414 | 1432 | .ring = { |
| @@ -1500,6 +1518,7 @@ static struct radeon_asic btc_asic = { · 85 unmodified lines | ||
| 1500 | 1518 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1501 | 1519 | .gart = { |
| 1502 | 1520 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| 1521 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1503 | 1522 | .set_page = &rs600_gart_set_page, |
| 1504 | 1523 | }, |
| 1505 | 1524 | .ring = { |
| @@ -1635,6 +1654,7 @@ static struct radeon_asic cayman_asic = { · 129 unmodified lines | ||
| 1635 | 1654 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1636 | 1655 | .gart = { |
| 1637 | 1656 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
| 1657 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1638 | 1658 | .set_page = &rs600_gart_set_page, |
| 1639 | 1659 | }, |
| 1640 | 1660 | .vm = { |
| @@ -1738,6 +1758,7 @@ static struct radeon_asic trinity_asic = { · 97 unmodified lines | ||
| 1738 | 1758 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| 1739 | 1759 | .gart = { |
| 1740 | 1760 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
| 1761 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1741 | 1762 | .set_page = &rs600_gart_set_page, |
| 1742 | 1763 | }, |
| 1743 | 1764 | .vm = { |
| @@ -1871,6 +1892,7 @@ static struct radeon_asic si_asic = { · 127 unmodified lines | ||
| 1871 | 1892 | .get_gpu_clock_counter = &si_get_gpu_clock_counter, |
| 1872 | 1893 | .gart = { |
| 1873 | 1894 | .tlb_flush = &si_pcie_gart_tlb_flush, |
| 1895 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 1874 | 1896 | .set_page = &rs600_gart_set_page, |
| 1875 | 1897 | }, |
| 1876 | 1898 | .vm = { |
| @@ -2032,6 +2054,7 @@ static struct radeon_asic ci_asic = { · 155 unmodified lines | ||
| 2032 | 2054 | .get_gpu_clock_counter = &cik_get_gpu_clock_counter, |
| 2033 | 2055 | .gart = { |
| 2034 | 2056 | .tlb_flush = &cik_pcie_gart_tlb_flush, |
| 2057 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 2035 | 2058 | .set_page = &rs600_gart_set_page, |
| 2036 | 2059 | }, |
| 2037 | 2060 | .vm = { |
| @@ -2139,6 +2162,7 @@ static struct radeon_asic kv_asic = { · 101 unmodified lines | ||
| 2139 | 2162 | .get_gpu_clock_counter = &cik_get_gpu_clock_counter, |
| 2140 | 2163 | .gart = { |
| 2141 | 2164 | .tlb_flush = &cik_pcie_gart_tlb_flush, |
| 2165 | + .get_page_entry = &rs600_gart_get_page_entry, | |
| 2142 | 2166 | .set_page = &rs600_gart_set_page, |
| 2143 | 2167 | }, |
| 2144 | 2168 | .vm = { |
| @@ -67,8 +67,9 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); · 66 unmodified lines | ||
| 67 | 67 | int r100_asic_reset(struct radeon_device *rdev); |
| 68 | 68 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); |
| 69 | 69 | void r100_pci_gart_tlb_flush(struct radeon_device *rdev); |
| 70 | +uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags); | |
| 70 | 71 | void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, |
| 71 | − uint64_t addr, uint32_t flags); | |
| 72 | + uint64_t entry); | |
| 72 | 73 | void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); |
| 73 | 74 | int r100_irq_set(struct radeon_device *rdev); |
| 74 | 75 | int r100_irq_process(struct radeon_device *rdev); |
| @@ -172,8 +173,9 @@ extern void r300_fence_ring_emit(struct radeon_device *rdev, · 97 unmodified lines | ||
| 172 | 173 | struct radeon_fence *fence); |
| 173 | 174 | extern int r300_cs_parse(struct radeon_cs_parser *p); |
| 174 | 175 | extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); |
| 176 | +extern uint64_t rv370_pcie_gart_get_page_entry(uint64_t addr, uint32_t flags); | |
| 175 | 177 | extern void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, |
| 176 | − uint64_t addr, uint32_t flags); | |
| 178 | + uint64_t entry); | |
| 177 | 179 | extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); |
| 178 | 180 | extern int rv370_get_pcie_lanes(struct radeon_device *rdev); |
| 179 | 181 | extern void r300_set_reg_safe(struct radeon_device *rdev); |
| @@ -208,8 +210,9 @@ extern void rs400_fini(struct radeon_device *rdev); · 28 unmodified lines | ||
| 208 | 210 | extern int rs400_suspend(struct radeon_device *rdev); |
| 209 | 211 | extern int rs400_resume(struct radeon_device *rdev); |
| 210 | 212 | void rs400_gart_tlb_flush(struct radeon_device *rdev); |
| 213 | +uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags); | |
| 211 | 214 | void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, |
| 212 | − uint64_t addr, uint32_t flags); | |
| 215 | + uint64_t entry); | |
| 213 | 216 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 214 | 217 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 215 | 218 | int rs400_gart_init(struct radeon_device *rdev); |
| @@ -232,8 +235,9 @@ int rs600_irq_process(struct radeon_device *rdev); · 16 unmodified lines | ||
| 232 | 235 | void rs600_irq_disable(struct radeon_device *rdev); |
| 233 | 236 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); |
| 234 | 237 | void rs600_gart_tlb_flush(struct radeon_device *rdev); |
| 238 | +uint64_t rs600_gart_get_page_entry(uint64_t addr, uint32_t flags); | |
| 235 | 239 | void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, |
| 236 | − uint64_t addr, uint32_t flags); | |
| 240 | + uint64_t entry); | |
| 237 | 241 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 238 | 242 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 239 | 243 | void rs600_bandwidth_update(struct radeon_device *rdev); |
| @@ -774,6 +774,8 @@ int radeon_dummy_page_init(struct radeon_device *rdev) · 773 unmodified lines | ||
| 774 | 774 | rdev->dummy_page.page = NULL; |
| 775 | 775 | return -ENOMEM; |
| 776 | 776 | } |
| 777 | + rdev->dummy_page.entry = radeon_gart_get_page_entry(rdev->dummy_page.addr, | |
| 778 | + RADEON_GART_PAGE_DUMMY); | |
| 777 | 779 | return 0; |
| 778 | 780 | } |
| 779 | 781 | |
| @@ -165,6 +165,19 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) · 164 unmodified lines | ||
| 165 | 165 | radeon_bo_unpin(rdev->gart.robj); |
| 166 | 166 | radeon_bo_unreserve(rdev->gart.robj); |
| 167 | 167 | rdev->gart.table_addr = gpu_addr; |
| 168 | + | |
| 169 | + if (!r) { | |
| 170 | + int i; | |
| 171 | + | |
| 172 | + /* We might have dropped some GART table updates while it wasn't | |
| 173 | + * mapped, restore all entries | |
| 174 | + */ | |
| 175 | + for (i = 0; i < rdev->gart.num_gpu_pages; i++) | |
| 176 | + radeon_gart_set_page(rdev, i, rdev->gart.pages_entry[i]); | |
| 177 | + mb(); | |
| 178 | + radeon_gart_tlb_flush(rdev); | |
| 179 | + } | |
| 180 | + | |
| 168 | 181 | return r; |
| 169 | 182 | } |
| 170 | 183 | |
| @@ -228,7 +241,6 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, · 57 unmodified lines | ||
| 228 | 241 | unsigned t; |
| 229 | 242 | unsigned p; |
| 230 | 243 | int i, j; |
| 231 | − u64 page_base; | |
| 232 | 244 | |
| 233 | 245 | if (!rdev->gart.ready) { |
| 234 | 246 | WARN(1, "trying to unbind memory from uninitialized GART !\n"); |
| @@ -239,14 +251,12 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, · 4 unmodified lines | ||
| 239 | 251 | for (i = 0; i < pages; i++, p++) { |
| 240 | 252 | if (rdev->gart.pages[p]) { |
| 241 | 253 | rdev->gart.pages[p] = NULL; |
| 242 | − rdev->gart.pages_addr[p] = rdev->dummy_page.addr; | |
| 243 | − page_base = rdev->gart.pages_addr[p]; | |
| 244 | 254 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| 255 | + rdev->gart.pages_entry[t] = rdev->dummy_page.entry; | |
| 245 | 256 | if (rdev->gart.ptr) { |
| 246 | − radeon_gart_set_page(rdev, t, page_base, | |
| 247 | − RADEON_GART_PAGE_DUMMY); | |
| 257 | + radeon_gart_set_page(rdev, t, | |
| 258 | + rdev->dummy_page.entry); | |
| 248 | 259 | } |
| 249 | − page_base += RADEON_GPU_PAGE_SIZE; | |
| 250 | 260 | } |
| 251 | 261 | } |
| 252 | 262 | } |
| @@ -274,7 +284,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, · 21 unmodified lines | ||
| 274 | 284 | { |
| 275 | 285 | unsigned t; |
| 276 | 286 | unsigned p; |
| 277 | − uint64_t page_base; | |
| 287 | + uint64_t page_base, page_entry; | |
| 278 | 288 | int i, j; |
| 279 | 289 | |
| 280 | 290 | if (!rdev->gart.ready) { |
| @@ -285,14 +295,15 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, · 4 unmodified lines | ||
| 285 | 295 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
| 286 | 296 | |
| 287 | 297 | for (i = 0; i < pages; i++, p++) { |
| 288 | − rdev->gart.pages_addr[p] = dma_addr[i]; | |
| 289 | 298 | rdev->gart.pages[p] = pagelist[i]; |
| 290 | − if (rdev->gart.ptr) { | |
| 291 | − page_base = rdev->gart.pages_addr[p]; | |
| 292 | − for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | |
| 293 | − radeon_gart_set_page(rdev, t, page_base, flags); | |
| 294 | − page_base += RADEON_GPU_PAGE_SIZE; | |
| 299 | + page_base = dma_addr[i]; | |
| 300 | + for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | |
| 301 | + page_entry = radeon_gart_get_page_entry(page_base, flags); | |
| 302 | + rdev->gart.pages_entry[t] = page_entry; | |
| 303 | + if (rdev->gart.ptr) { | |
| 304 | + radeon_gart_set_page(rdev, t, page_entry); | |
| 295 | 305 | } |
| 306 | + page_base += RADEON_GPU_PAGE_SIZE; | |
| 296 | 307 | } |
| 297 | 308 | } |
| 298 | 309 | mb(); |
| @@ -334,16 +345,15 @@ int radeon_gart_init(struct radeon_device *rdev) · 35 unmodified lines | ||
| 334 | 345 | radeon_gart_fini(rdev); |
| 335 | 346 | return -ENOMEM; |
| 336 | 347 | } |
| 337 | − rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * | |
| 338 | − rdev->gart.num_cpu_pages); | |
| 339 | − if (rdev->gart.pages_addr == NULL) { | |
| 348 | + rdev->gart.pages_entry = vmalloc(sizeof(uint64_t) * | |
| 349 | + rdev->gart.num_gpu_pages); | |
| 350 | + if (rdev->gart.pages_entry == NULL) { | |
| 340 | 351 | radeon_gart_fini(rdev); |
| 341 | 352 | return -ENOMEM; |
| 342 | 353 | } |
| 343 | 354 | /* set GART entry to point to the dummy page by default */ |
| 344 | − for (i = 0; i < rdev->gart.num_cpu_pages; i++) { | |
| 345 | − rdev->gart.pages_addr[i] = rdev->dummy_page.addr; | |
| 346 | − } | |
| 355 | + for (i = 0; i < rdev->gart.num_gpu_pages; i++) | |
| 356 | + rdev->gart.pages_entry[i] = rdev->dummy_page.entry; | |
| 347 | 357 | return 0; |
| 348 | 358 | } |
| 349 | 359 | |
| @@ -356,15 +366,15 @@ int radeon_gart_init(struct radeon_device *rdev) · 6 unmodified lines | ||
| 356 | 366 | */ |
| 357 | 367 | void radeon_gart_fini(struct radeon_device *rdev) |
| 358 | 368 | { |
| 359 | − if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { | |
| 369 | + if (rdev->gart.ready) { | |
| 360 | 370 | /* unbind pages */ |
| 361 | 371 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
| 362 | 372 | } |
| 363 | 373 | rdev->gart.ready = false; |
| 364 | 374 | vfree(rdev->gart.pages); |
| 365 | − vfree(rdev->gart.pages_addr); | |
| 375 | + vfree(rdev->gart.pages_entry); | |
| 366 | 376 | rdev->gart.pages = NULL; |
| 367 | − rdev->gart.pages_addr = NULL; | |
| 377 | + rdev->gart.pages_entry = NULL; | |
| 368 | 378 | |
| 369 | 379 | radeon_dummy_page_fini(rdev); |
| 370 | 380 | } |
| @@ -436,7 +436,7 @@ static int kgd_init_memory(struct kgd_dev *kgd) · 435 unmodified lines | ||
| 436 | 436 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, |
| 437 | 437 | uint32_t hpd_size, uint64_t hpd_gpu_addr) |
| 438 | 438 | { |
| 439 | − uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1; | |
| 439 | + uint32_t mec = (pipe_id / CIK_PIPE_PER_MEC) + 1; | |
| 440 | 440 | uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); |
| 441 | 441 | |
| 442 | 442 | lock_srbm(kgd, mec, pipe, 0, 0); |
| @@ -587,10 +587,8 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) · 586 unmodified lines | ||
| 587 | 587 | uint64_t result; |
| 588 | 588 | |
| 589 | 589 | /* page table offset */ |
| 590 | − result = rdev->gart.pages_addr[addr >> PAGE_SHIFT]; | |
| 591 | − | |
| 592 | − /* in case cpu page size != gpu page size*/ | |
| 593 | − result |= addr & (~PAGE_MASK); | |
| 590 | + result = rdev->gart.pages_entry[addr >> RADEON_GPU_PAGE_SHIFT]; | |
| 591 | + result &= ~RADEON_GPU_PAGE_MASK; | |
| 594 | 592 | |
| 595 | 593 | return result; |
| 596 | 594 | } |
| @@ -212,11 +212,9 @@ void rs400_gart_fini(struct radeon_device *rdev) · 211 unmodified lines | ||
| 212 | 212 | #define RS400_PTE_WRITEABLE (1 << 2) |
| 213 | 213 | #define RS400_PTE_READABLE (1 << 3) |
| 214 | 214 | |
| 215 | −void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | |
| 216 | − uint64_t addr, uint32_t flags) | |
| 215 | +uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags) | |
| 217 | 216 | { |
| 218 | 217 | uint32_t entry; |
| 219 | − u32 *gtt = rdev->gart.ptr; | |
| 220 | 218 | |
| 221 | 219 | entry = (lower_32_bits(addr) & PAGE_MASK) | |
| 222 | 220 | ((upper_32_bits(addr) & 0xff) << 4); |
| @@ -226,8 +224,14 @@ void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, · 3 unmodified lines | ||
| 226 | 224 | entry |= RS400_PTE_WRITEABLE; |
| 227 | 225 | if (!(flags & RADEON_GART_PAGE_SNOOP)) |
| 228 | 226 | entry |= RS400_PTE_UNSNOOPED; |
| 229 | − entry = cpu_to_le32(entry); | |
| 230 | − gtt[i] = entry; | |
| 227 | + return entry; | |
| 228 | +} | |
| 229 | + | |
| 230 | +void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | |
| 231 | + uint64_t entry) | |
| 232 | +{ | |
| 233 | + u32 *gtt = rdev->gart.ptr; | |
| 234 | + gtt[i] = cpu_to_le32(lower_32_bits(entry)); | |
| 231 | 235 | } |
| 232 | 236 | |
| 233 | 237 | int rs400_mc_wait_for_idle(struct radeon_device *rdev) |
| @@ -625,11 +625,8 @@ static void rs600_gart_fini(struct radeon_device *rdev) · 624 unmodified lines | ||
| 625 | 625 | radeon_gart_table_vram_free(rdev); |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | −void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, | |
| 629 | − uint64_t addr, uint32_t flags) | |
| 628 | +uint64_t rs600_gart_get_page_entry(uint64_t addr, uint32_t flags) | |
| 630 | 629 | { |
| 631 | − void __iomem *ptr = (void *)rdev->gart.ptr; | |
| 632 | − | |
| 633 | 630 | addr = addr & 0xFFFFFFFFFFFFF000ULL; |
| 634 | 631 | addr |= R600_PTE_SYSTEM; |
| 635 | 632 | if (flags & RADEON_GART_PAGE_VALID) |
| @@ -640,7 +637,14 @@ void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, · 4 unmodified lines | ||
| 640 | 637 | addr |= R600_PTE_WRITEABLE; |
| 641 | 638 | if (flags & RADEON_GART_PAGE_SNOOP) |
| 642 | 639 | addr |= R600_PTE_SNOOPED; |
| 643 | − writeq(addr, ptr + (i * 8)); | |
| 640 | + return addr; | |
| 641 | +} | |
| 642 | + | |
| 643 | +void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, | |
| 644 | + uint64_t entry) | |
| 645 | +{ | |
| 646 | + void __iomem *ptr = (void *)rdev->gart.ptr; | |
| 647 | + writeq(entry, ptr + (i * 8)); | |
| 644 | 648 | } |
| 645 | 649 | |
| 646 | 650 | int rs600_irq_set(struct radeon_device *rdev) |
| @@ -123,7 +123,6 @@ void si_dma_vm_write_pages(struct radeon_device *rdev, · 122 unmodified lines | ||
| 123 | 123 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
| 124 | 124 | if (flags & R600_PTE_SYSTEM) { |
| 125 | 125 | value = radeon_vm_map_gart(rdev, addr); |
| 126 | − value &= 0xFFFFFFFFFFFFF000ULL; | |
| 127 | 126 | } else if (flags & R600_PTE_VALID) { |
| 128 | 127 | value = addr; |
| 129 | 128 | } else { |
| @@ -406,11 +406,9 @@ int vmw_3d_resource_inc(struct vmw_private *dev_priv, · 405 unmodified lines | ||
| 406 | 406 | if (unlikely(ret != 0)) |
| 407 | 407 | --dev_priv->num_3d_resources; |
| 408 | 408 | } else if (unhide_svga) { |
| 409 | − mutex_lock(&dev_priv->hw_mutex); | |
| 410 | 409 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
| 411 | 410 | vmw_read(dev_priv, SVGA_REG_ENABLE) & |
| 412 | 411 | ~SVGA_REG_ENABLE_HIDE); |
| 413 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 414 | 412 | } |
| 415 | 413 | |
| 416 | 414 | mutex_unlock(&dev_priv->release_mutex); |
| @@ -433,13 +431,10 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv, · 16 unmodified lines | ||
| 433 | 431 | mutex_lock(&dev_priv->release_mutex); |
| 434 | 432 | if (unlikely(--dev_priv->num_3d_resources == 0)) |
| 435 | 433 | vmw_release_device(dev_priv); |
| 436 | − else if (hide_svga) { | |
| 437 | − mutex_lock(&dev_priv->hw_mutex); | |
| 434 | + else if (hide_svga) | |
| 438 | 435 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
| 439 | 436 | vmw_read(dev_priv, SVGA_REG_ENABLE) | |
| 440 | 437 | SVGA_REG_ENABLE_HIDE); |
| 441 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 442 | − } | |
| 443 | 438 | |
| 444 | 439 | n3d = (int32_t) dev_priv->num_3d_resources; |
| 445 | 440 | mutex_unlock(&dev_priv->release_mutex); |
| @@ -600,12 +595,14 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 154 unmodified lines | ||
| 600 | 595 | dev_priv->dev = dev; |
| 601 | 596 | dev_priv->vmw_chipset = chipset; |
| 602 | 597 | dev_priv->last_read_seqno = (uint32_t) -100; |
| 603 | − mutex_init(&dev_priv->hw_mutex); | |
| 604 | 598 | mutex_init(&dev_priv->cmdbuf_mutex); |
| 605 | 599 | mutex_init(&dev_priv->release_mutex); |
| 606 | 600 | mutex_init(&dev_priv->binding_mutex); |
| 607 | 601 | rwlock_init(&dev_priv->resource_lock); |
| 608 | 602 | ttm_lock_init(&dev_priv->reservation_sem); |
| 603 | + spin_lock_init(&dev_priv->hw_lock); | |
| 604 | + spin_lock_init(&dev_priv->waiter_lock); | |
| 605 | + spin_lock_init(&dev_priv->cap_lock); | |
| 609 | 606 | |
| 610 | 607 | for (i = vmw_res_context; i < vmw_res_max; ++i) { |
| 611 | 608 | idr_init(&dev_priv->res_idr[i]); |
| @@ -626,14 +623,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 14 unmodified lines | ||
| 626 | 623 | |
| 627 | 624 | dev_priv->enable_fb = enable_fbdev; |
| 628 | 625 | |
| 629 | − mutex_lock(&dev_priv->hw_mutex); | |
| 630 | − | |
| 631 | 626 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
| 632 | 627 | svga_id = vmw_read(dev_priv, SVGA_REG_ID); |
| 633 | 628 | if (svga_id != SVGA_ID_2) { |
| 634 | 629 | ret = -ENOSYS; |
| 635 | 630 | DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); |
| 636 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 637 | 631 | goto out_err0; |
| 638 | 632 | } |
| 639 | 633 | |
| @@ -683,10 +677,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 43 unmodified lines | ||
| 683 | 677 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
| 684 | 678 | |
| 685 | 679 | ret = vmw_dma_masks(dev_priv); |
| 686 | − if (unlikely(ret != 0)) { | |
| 687 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 680 | + if (unlikely(ret != 0)) | |
| 688 | 681 | goto out_err0; |
| 689 | − } | |
| 690 | 682 | |
| 691 | 683 | /* |
| 692 | 684 | * Limit back buffer size to VRAM size. Remove this once |
| @@ -695,8 +687,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 2 unmodified lines | ||
| 695 | 687 | if (dev_priv->prim_bb_mem > dev_priv->vram_size) |
| 696 | 688 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
| 697 | 689 | |
| 698 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 699 | − | |
| 700 | 690 | vmw_print_capabilities(dev_priv->capabilities); |
| 701 | 691 | |
| 702 | 692 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { |
| @@ -1160,9 +1150,7 @@ static int vmw_master_set(struct drm_device *dev, · 457 unmodified lines | ||
| 1160 | 1150 | if (unlikely(ret != 0)) |
| 1161 | 1151 | return ret; |
| 1162 | 1152 | vmw_kms_save_vga(dev_priv); |
| 1163 | − mutex_lock(&dev_priv->hw_mutex); | |
| 1164 | 1153 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); |
| 1165 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 1166 | 1154 | } |
| 1167 | 1155 | |
| 1168 | 1156 | if (active) { |
| @@ -1196,9 +1184,7 @@ out_no_active_lock: · 27 unmodified lines | ||
| 1196 | 1184 | if (!dev_priv->enable_fb) { |
| 1197 | 1185 | vmw_kms_restore_vga(dev_priv); |
| 1198 | 1186 | vmw_3d_resource_dec(dev_priv, true); |
| 1199 | − mutex_lock(&dev_priv->hw_mutex); | |
| 1200 | 1187 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
| 1201 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 1202 | 1188 | } |
| 1203 | 1189 | return ret; |
| 1204 | 1190 | } |
| @@ -1233,9 +1219,7 @@ static void vmw_master_drop(struct drm_device *dev, · 28 unmodified lines | ||
| 1233 | 1219 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); |
| 1234 | 1220 | vmw_kms_restore_vga(dev_priv); |
| 1235 | 1221 | vmw_3d_resource_dec(dev_priv, true); |
| 1236 | − mutex_lock(&dev_priv->hw_mutex); | |
| 1237 | 1222 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
| 1238 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 1239 | 1223 | } |
| 1240 | 1224 | |
| 1241 | 1225 | dev_priv->active_master = &dev_priv->fbdev_master; |
| @@ -1367,10 +1351,8 @@ static void vmw_pm_complete(struct device *kdev) · 125 unmodified lines | ||
| 1367 | 1351 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1368 | 1352 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1369 | 1353 | |
| 1370 | − mutex_lock(&dev_priv->hw_mutex); | |
| 1371 | 1354 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
| 1372 | 1355 | (void) vmw_read(dev_priv, SVGA_REG_ID); |
| 1373 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 1374 | 1356 | |
| 1375 | 1357 | /** |
| 1376 | 1358 | * Reclaim 3d reference held by fbdev and potentially |
| @@ -399,7 +399,8 @@ struct vmw_private { · 398 unmodified lines | ||
| 399 | 399 | uint32_t memory_size; |
| 400 | 400 | bool has_gmr; |
| 401 | 401 | bool has_mob; |
| 402 | − struct mutex hw_mutex; | |
| 402 | + spinlock_t hw_lock; | |
| 403 | + spinlock_t cap_lock; | |
| 403 | 404 | |
| 404 | 405 | /* |
| 405 | 406 | * VGA registers. |
| @@ -449,8 +450,9 @@ struct vmw_private { · 43 unmodified lines | ||
| 449 | 450 | atomic_t marker_seq; |
| 450 | 451 | wait_queue_head_t fence_queue; |
| 451 | 452 | wait_queue_head_t fifo_queue; |
| 452 | − int fence_queue_waiters; /* Protected by hw_mutex */ | |
| 453 | − int goal_queue_waiters; /* Protected by hw_mutex */ | |
| 453 | + spinlock_t waiter_lock; | |
| 454 | + int fence_queue_waiters; /* Protected by waiter_lock */ | |
| 455 | + int goal_queue_waiters; /* Protected by waiter_lock */ | |
| 454 | 456 | atomic_t fifo_queue_waiters; |
| 455 | 457 | uint32_t last_read_seqno; |
| 456 | 458 | spinlock_t irq_lock; |
| @@ -553,20 +555,35 @@ static inline struct vmw_master *vmw_master(struct drm_master *master) · 96 unmodified lines | ||
| 553 | 555 | return (struct vmw_master *) master->driver_priv; |
| 554 | 556 | } |
| 555 | 557 | |
| 558 | +/* | |
| 559 | + * The locking here is fine-grained, so that it is performed once | |
| 560 | + * for every read- and write operation. This is of course costly, but we | |
| 561 | + * don't perform much register access in the timing critical paths anyway. | |
| 562 | + * Instead we have the extra benefit of being sure that we don't forget | |
| 563 | + * the hw lock around register accesses. | |
| 564 | + */ | |
| 556 | 565 | static inline void vmw_write(struct vmw_private *dev_priv, |
| 557 | 566 | unsigned int offset, uint32_t value) |
| 558 | 567 | { |
| 568 | + unsigned long irq_flags; | |
| 569 | + | |
| 570 | + spin_lock_irqsave(&dev_priv->hw_lock, irq_flags); | |
| 559 | 571 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); |
| 560 | 572 | outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); |
| 573 | + spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags); | |
| 561 | 574 | } |
| 562 | 575 | |
| 563 | 576 | static inline uint32_t vmw_read(struct vmw_private *dev_priv, |
| 564 | 577 | unsigned int offset) |
| 565 | 578 | { |
| 566 | − uint32_t val; | |
| 579 | + unsigned long irq_flags; | |
| 580 | + u32 val; | |
| 567 | 581 | |
| 582 | + spin_lock_irqsave(&dev_priv->hw_lock, irq_flags); | |
| 568 | 583 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); |
| 569 | 584 | val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); |
| 585 | + spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags); | |
| 586 | + | |
| 570 | 587 | return val; |
| 571 | 588 | } |
| 572 | 589 | |
| @@ -35,7 +35,7 @@ struct vmw_fence_manager { · 34 unmodified lines | ||
| 35 | 35 | struct vmw_private *dev_priv; |
| 36 | 36 | spinlock_t lock; |
| 37 | 37 | struct list_head fence_list; |
| 38 | − struct work_struct work, ping_work; | |
| 38 | + struct work_struct work; | |
| 39 | 39 | u32 user_fence_size; |
| 40 | 40 | u32 fence_size; |
| 41 | 41 | u32 event_fence_action_size; |
| @@ -134,14 +134,6 @@ static const char *vmw_fence_get_timeline_name(struct fence *f) · 92 unmodified lines | ||
| 134 | 134 | return "svga"; |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | −static void vmw_fence_ping_func(struct work_struct *work) | |
| 138 | −{ | |
| 139 | − struct vmw_fence_manager *fman = | |
| 140 | − container_of(work, struct vmw_fence_manager, ping_work); | |
| 141 | − | |
| 142 | − vmw_fifo_ping_host(fman->dev_priv, SVGA_SYNC_GENERIC); | |
| 143 | −} | |
| 144 | − | |
| 145 | 137 | static bool vmw_fence_enable_signaling(struct fence *f) |
| 146 | 138 | { |
| 147 | 139 | struct vmw_fence_obj *fence = |
| @@ -155,11 +147,7 @@ static bool vmw_fence_enable_signaling(struct fence *f) · 7 unmodified lines | ||
| 155 | 147 | if (seqno - fence->base.seqno < VMW_FENCE_WRAP) |
| 156 | 148 | return false; |
| 157 | 149 | |
| 158 | − if (mutex_trylock(&dev_priv->hw_mutex)) { | |
| 159 | − vmw_fifo_ping_host_locked(dev_priv, SVGA_SYNC_GENERIC); | |
| 160 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 161 | − } else | |
| 162 | − schedule_work(&fman->ping_work); | |
| 150 | + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); | |
| 163 | 151 | |
| 164 | 152 | return true; |
| 165 | 153 | } |
| @@ -305,7 +293,6 @@ struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv) · 139 unmodified lines | ||
| 305 | 293 | INIT_LIST_HEAD(&fman->fence_list); |
| 306 | 294 | INIT_LIST_HEAD(&fman->cleanup_list); |
| 307 | 295 | INIT_WORK(&fman->work, &vmw_fence_work_func); |
| 308 | − INIT_WORK(&fman->ping_work, &vmw_fence_ping_func); | |
| 309 | 296 | fman->fifo_down = true; |
| 310 | 297 | fman->user_fence_size = ttm_round_pot(sizeof(struct vmw_user_fence)); |
| 311 | 298 | fman->fence_size = ttm_round_pot(sizeof(struct vmw_fence_obj)); |
| @@ -323,7 +310,6 @@ void vmw_fence_manager_takedown(struct vmw_fence_manager *fman) · 11 unmodified lines | ||
| 323 | 310 | bool lists_empty; |
| 324 | 311 | |
| 325 | 312 | (void) cancel_work_sync(&fman->work); |
| 326 | − (void) cancel_work_sync(&fman->ping_work); | |
| 327 | 313 | |
| 328 | 314 | spin_lock_irqsave(&fman->lock, irq_flags); |
| 329 | 315 | lists_empty = list_empty(&fman->fence_list) && |
| @@ -44,10 +44,10 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) · 43 unmodified lines | ||
| 44 | 44 | if (!dev_priv->has_mob) |
| 45 | 45 | return false; |
| 46 | 46 | |
| 47 | − mutex_lock(&dev_priv->hw_mutex); | |
| 47 | + spin_lock(&dev_priv->cap_lock); | |
| 48 | 48 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_3D); |
| 49 | 49 | result = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
| 50 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 50 | + spin_unlock(&dev_priv->cap_lock); | |
| 51 | 51 | |
| 52 | 52 | return (result != 0); |
| 53 | 53 | } |
| @@ -120,7 +120,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) · 66 unmodified lines | ||
| 120 | 120 | DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); |
| 121 | 121 | DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); |
| 122 | 122 | |
| 123 | − mutex_lock(&dev_priv->hw_mutex); | |
| 124 | 123 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
| 125 | 124 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
| 126 | 125 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); |
| @@ -143,7 +142,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) · 16 unmodified lines | ||
| 143 | 142 | mb(); |
| 144 | 143 | |
| 145 | 144 | vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); |
| 146 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 147 | 145 | |
| 148 | 146 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); |
| 149 | 147 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); |
| @@ -160,31 +158,28 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) · 10 unmodified lines | ||
| 160 | 158 | return vmw_fifo_send_fence(dev_priv, &dummy); |
| 161 | 159 | } |
| 162 | 160 | |
| 163 | −void vmw_fifo_ping_host_locked(struct vmw_private *dev_priv, uint32_t reason) | |
| 161 | +void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) | |
| 164 | 162 | { |
| 165 | 163 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
| 164 | + static DEFINE_SPINLOCK(ping_lock); | |
| 165 | + unsigned long irq_flags; | |
| 166 | 166 | |
| 167 | + /* | |
| 168 | + * The ping_lock is needed because we don't have an atomic | |
| 169 | + * test-and-set of the SVGA_FIFO_BUSY register. | |
| 170 | + */ | |
| 171 | + spin_lock_irqsave(&ping_lock, irq_flags); | |
| 167 | 172 | if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { |
| 168 | 173 | iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); |
| 169 | 174 | vmw_write(dev_priv, SVGA_REG_SYNC, reason); |
| 170 | 175 | } |
| 171 | −} | |
| 172 | − | |
| 173 | −void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) | |
| 174 | −{ | |
| 175 | − mutex_lock(&dev_priv->hw_mutex); | |
| 176 | − | |
| 177 | − vmw_fifo_ping_host_locked(dev_priv, reason); | |
| 178 | − | |
| 179 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 176 | + spin_unlock_irqrestore(&ping_lock, irq_flags); | |
| 180 | 177 | } |
| 181 | 178 | |
| 182 | 179 | void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) |
| 183 | 180 | { |
| 184 | 181 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
| 185 | 182 | |
| 186 | − mutex_lock(&dev_priv->hw_mutex); | |
| 187 | − | |
| 188 | 183 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); |
| 189 | 184 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) |
| 190 | 185 | ; |
| @@ -198,7 +193,6 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) · 7 unmodified lines | ||
| 198 | 193 | vmw_write(dev_priv, SVGA_REG_TRACES, |
| 199 | 194 | dev_priv->traces_state); |
| 200 | 195 | |
| 201 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 202 | 196 | vmw_marker_queue_takedown(&fifo->marker_queue); |
| 203 | 197 | |
| 204 | 198 | if (likely(fifo->static_buffer != NULL)) { |
| @@ -271,7 +265,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, · 66 unmodified lines | ||
| 271 | 265 | return vmw_fifo_wait_noirq(dev_priv, bytes, |
| 272 | 266 | interruptible, timeout); |
| 273 | 267 | |
| 274 | − mutex_lock(&dev_priv->hw_mutex); | |
| 268 | + spin_lock(&dev_priv->waiter_lock); | |
| 275 | 269 | if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) { |
| 276 | 270 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
| 277 | 271 | outl(SVGA_IRQFLAG_FIFO_PROGRESS, |
| @@ -280,7 +274,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, · 2 unmodified lines | ||
| 280 | 274 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 281 | 275 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 282 | 276 | } |
| 283 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 277 | + spin_unlock(&dev_priv->waiter_lock); | |
| 284 | 278 | |
| 285 | 279 | if (interruptible) |
| 286 | 280 | ret = wait_event_interruptible_timeout |
| @@ -296,14 +290,14 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, · 9 unmodified lines | ||
| 296 | 290 | else if (likely(ret > 0)) |
| 297 | 291 | ret = 0; |
| 298 | 292 | |
| 299 | − mutex_lock(&dev_priv->hw_mutex); | |
| 293 | + spin_lock(&dev_priv->waiter_lock); | |
| 300 | 294 | if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) { |
| 301 | 295 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
| 302 | 296 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_FIFO_PROGRESS; |
| 303 | 297 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 304 | 298 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 305 | 299 | } |
| 306 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 300 | + spin_unlock(&dev_priv->waiter_lock); | |
| 307 | 301 | |
| 308 | 302 | return ret; |
| 309 | 303 | } |
| @@ -135,13 +135,13 @@ static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, · 134 unmodified lines | ||
| 135 | 135 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); |
| 136 | 136 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; |
| 137 | 137 | |
| 138 | − mutex_lock(&dev_priv->hw_mutex); | |
| 138 | + spin_lock(&dev_priv->cap_lock); | |
| 139 | 139 | for (i = 0; i < max_size; ++i) { |
| 140 | 140 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
| 141 | 141 | compat_cap->pairs[i][0] = i; |
| 142 | 142 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
| 143 | 143 | } |
| 144 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 144 | + spin_unlock(&dev_priv->cap_lock); | |
| 145 | 145 | |
| 146 | 146 | return 0; |
| 147 | 147 | } |
| @@ -191,12 +191,12 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, · 43 unmodified lines | ||
| 191 | 191 | if (num > SVGA3D_DEVCAP_MAX) |
| 192 | 192 | num = SVGA3D_DEVCAP_MAX; |
| 193 | 193 | |
| 194 | − mutex_lock(&dev_priv->hw_mutex); | |
| 194 | + spin_lock(&dev_priv->cap_lock); | |
| 195 | 195 | for (i = 0; i < num; ++i) { |
| 196 | 196 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
| 197 | 197 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
| 198 | 198 | } |
| 199 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 199 | + spin_unlock(&dev_priv->cap_lock); | |
| 200 | 200 | } else if (gb_objects) { |
| 201 | 201 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); |
| 202 | 202 | if (unlikely(ret != 0)) |
| @@ -62,13 +62,8 @@ irqreturn_t vmw_irq_handler(int irq, void *arg) · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) |
| 64 | 64 | { |
| 65 | − uint32_t busy; | |
| 66 | 65 | |
| 67 | − mutex_lock(&dev_priv->hw_mutex); | |
| 68 | − busy = vmw_read(dev_priv, SVGA_REG_BUSY); | |
| 69 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 70 | − | |
| 71 | − return (busy == 0); | |
| 66 | + return (vmw_read(dev_priv, SVGA_REG_BUSY) == 0); | |
| 72 | 67 | } |
| 73 | 68 | |
| 74 | 69 | void vmw_update_seqno(struct vmw_private *dev_priv, |
| @@ -184,7 +179,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, · 109 unmodified lines | ||
| 184 | 179 | |
| 185 | 180 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) |
| 186 | 181 | { |
| 187 | − mutex_lock(&dev_priv->hw_mutex); | |
| 182 | + spin_lock(&dev_priv->waiter_lock); | |
| 188 | 183 | if (dev_priv->fence_queue_waiters++ == 0) { |
| 189 | 184 | unsigned long irq_flags; |
| 190 | 185 | |
| @@ -195,12 +190,12 @@ void vmw_seqno_waiter_add(struct vmw_private *dev_priv) · 4 unmodified lines | ||
| 195 | 190 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 196 | 191 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 197 | 192 | } |
| 198 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 193 | + spin_unlock(&dev_priv->waiter_lock); | |
| 199 | 194 | } |
| 200 | 195 | |
| 201 | 196 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) |
| 202 | 197 | { |
| 203 | − mutex_lock(&dev_priv->hw_mutex); | |
| 198 | + spin_lock(&dev_priv->waiter_lock); | |
| 204 | 199 | if (--dev_priv->fence_queue_waiters == 0) { |
| 205 | 200 | unsigned long irq_flags; |
| 206 | 201 | |
| @@ -209,13 +204,13 @@ void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) · 2 unmodified lines | ||
| 209 | 204 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 210 | 205 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 211 | 206 | } |
| 212 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 207 | + spin_unlock(&dev_priv->waiter_lock); | |
| 213 | 208 | } |
| 214 | 209 | |
| 215 | 210 | |
| 216 | 211 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) |
| 217 | 212 | { |
| 218 | − mutex_lock(&dev_priv->hw_mutex); | |
| 213 | + spin_lock(&dev_priv->waiter_lock); | |
| 219 | 214 | if (dev_priv->goal_queue_waiters++ == 0) { |
| 220 | 215 | unsigned long irq_flags; |
| 221 | 216 | |
| @@ -226,12 +221,12 @@ void vmw_goal_waiter_add(struct vmw_private *dev_priv) · 4 unmodified lines | ||
| 226 | 221 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 227 | 222 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 228 | 223 | } |
| 229 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 224 | + spin_unlock(&dev_priv->waiter_lock); | |
| 230 | 225 | } |
| 231 | 226 | |
| 232 | 227 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) |
| 233 | 228 | { |
| 234 | − mutex_lock(&dev_priv->hw_mutex); | |
| 229 | + spin_lock(&dev_priv->waiter_lock); | |
| 235 | 230 | if (--dev_priv->goal_queue_waiters == 0) { |
| 236 | 231 | unsigned long irq_flags; |
| 237 | 232 | |
| @@ -240,7 +235,7 @@ void vmw_goal_waiter_remove(struct vmw_private *dev_priv) · 2 unmodified lines | ||
| 240 | 235 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 241 | 236 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 242 | 237 | } |
| 243 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 238 | + spin_unlock(&dev_priv->waiter_lock); | |
| 244 | 239 | } |
| 245 | 240 | |
| 246 | 241 | int vmw_wait_seqno(struct vmw_private *dev_priv, |
| @@ -315,9 +310,7 @@ void vmw_irq_uninstall(struct drm_device *dev) · 68 unmodified lines | ||
| 315 | 310 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
| 316 | 311 | return; |
| 317 | 312 | |
| 318 | − mutex_lock(&dev_priv->hw_mutex); | |
| 319 | 313 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); |
| 320 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 321 | 314 | |
| 322 | 315 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
| 323 | 316 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
| @@ -1828,9 +1828,7 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force) · 1827 unmodified lines | ||
| 1828 | 1828 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1829 | 1829 | struct vmw_display_unit *du = vmw_connector_to_du(connector); |
| 1830 | 1830 | |
| 1831 | − mutex_lock(&dev_priv->hw_mutex); | |
| 1832 | 1831 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); |
| 1833 | − mutex_unlock(&dev_priv->hw_mutex); | |
| 1834 | 1832 | |
| 1835 | 1833 | return ((vmw_connector_to_du(connector)->unit < num_displays && |
| 1836 | 1834 | du->pref_active) ? |
| @@ -881,6 +881,7 @@ config I2C_XLR · 880 unmodified lines | ||
| 881 | 881 | config I2C_RCAR |
| 882 | 882 | tristate "Renesas R-Car I2C Controller" |
| 883 | 883 | depends on ARCH_SHMOBILE || COMPILE_TEST |
| 884 | + select I2C_SLAVE | |
| 884 | 885 | help |
| 885 | 886 | If you say yes to this option, support will be included for the |
| 886 | 887 | R-Car I2C controller. |
| @@ -785,14 +785,16 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, · 784 unmodified lines | ||
| 785 | 785 | int ret; |
| 786 | 786 | |
| 787 | 787 | pm_runtime_get_sync(&adap->dev); |
| 788 | − clk_prepare_enable(i2c->clk); | |
| 788 | + ret = clk_enable(i2c->clk); | |
| 789 | + if (ret) | |
| 790 | + return ret; | |
| 789 | 791 | |
| 790 | 792 | for (retry = 0; retry < adap->retries; retry++) { |
| 791 | 793 | |
| 792 | 794 | ret = s3c24xx_i2c_doxfer(i2c, msgs, num); |
| 793 | 795 | |
| 794 | 796 | if (ret != -EAGAIN) { |
| 795 | − clk_disable_unprepare(i2c->clk); | |
| 797 | + clk_disable(i2c->clk); | |
| 796 | 798 | pm_runtime_put(&adap->dev); |
| 797 | 799 | return ret; |
| 798 | 800 | } |
| @@ -802,7 +804,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, · 3 unmodified lines | ||
| 802 | 804 | udelay(100); |
| 803 | 805 | } |
| 804 | 806 | |
| 805 | − clk_disable_unprepare(i2c->clk); | |
| 807 | + clk_disable(i2c->clk); | |
| 806 | 808 | pm_runtime_put(&adap->dev); |
| 807 | 809 | return -EREMOTEIO; |
| 808 | 810 | } |
| @@ -1197,7 +1199,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) · 388 unmodified lines | ||
| 1197 | 1199 | |
| 1198 | 1200 | clk_prepare_enable(i2c->clk); |
| 1199 | 1201 | ret = s3c24xx_i2c_init(i2c); |
| 1200 | − clk_disable_unprepare(i2c->clk); | |
| 1202 | + clk_disable(i2c->clk); | |
| 1201 | 1203 | if (ret != 0) { |
| 1202 | 1204 | dev_err(&pdev->dev, "I2C controller init failed\n"); |
| 1203 | 1205 | return ret; |
| @@ -1210,6 +1212,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 1210 | 1212 | i2c->irq = ret = platform_get_irq(pdev, 0); |
| 1211 | 1213 | if (ret <= 0) { |
| 1212 | 1214 | dev_err(&pdev->dev, "cannot find IRQ\n"); |
| 1215 | + clk_unprepare(i2c->clk); | |
| 1213 | 1216 | return ret; |
| 1214 | 1217 | } |
| 1215 | 1218 | |
| @@ -1218,6 +1221,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 1218 | 1221 | |
| 1219 | 1222 | if (ret != 0) { |
| 1220 | 1223 | dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); |
| 1224 | + clk_unprepare(i2c->clk); | |
| 1221 | 1225 | return ret; |
| 1222 | 1226 | } |
| 1223 | 1227 | } |
| @@ -1225,6 +1229,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 1225 | 1229 | ret = s3c24xx_i2c_register_cpufreq(i2c); |
| 1226 | 1230 | if (ret < 0) { |
| 1227 | 1231 | dev_err(&pdev->dev, "failed to register cpufreq notifier\n"); |
| 1232 | + clk_unprepare(i2c->clk); | |
| 1228 | 1233 | return ret; |
| 1229 | 1234 | } |
| 1230 | 1235 | |
| @@ -1241,6 +1246,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 1241 | 1246 | if (ret < 0) { |
| 1242 | 1247 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); |
| 1243 | 1248 | s3c24xx_i2c_deregister_cpufreq(i2c); |
| 1249 | + clk_unprepare(i2c->clk); | |
| 1244 | 1250 | return ret; |
| 1245 | 1251 | } |
| 1246 | 1252 | |
| @@ -1262,6 +1268,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) · 15 unmodified lines | ||
| 1262 | 1268 | { |
| 1263 | 1269 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); |
| 1264 | 1270 | |
| 1271 | + clk_unprepare(i2c->clk); | |
| 1272 | + | |
| 1265 | 1273 | pm_runtime_disable(&i2c->adap.dev); |
| 1266 | 1274 | pm_runtime_disable(&pdev->dev); |
| 1267 | 1275 | |
| @@ -1293,13 +1301,16 @@ static int s3c24xx_i2c_resume_noirq(struct device *dev) · 25 unmodified lines | ||
| 1293 | 1301 | { |
| 1294 | 1302 | struct platform_device *pdev = to_platform_device(dev); |
| 1295 | 1303 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); |
| 1304 | + int ret; | |
| 1296 | 1305 | |
| 1297 | 1306 | if (!IS_ERR(i2c->sysreg)) |
| 1298 | 1307 | regmap_write(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, i2c->sys_i2c_cfg); |
| 1299 | 1308 | |
| 1300 | − clk_prepare_enable(i2c->clk); | |
| 1309 | + ret = clk_enable(i2c->clk); | |
| 1310 | + if (ret) | |
| 1311 | + return ret; | |
| 1301 | 1312 | s3c24xx_i2c_init(i2c); |
| 1302 | − clk_disable_unprepare(i2c->clk); | |
| 1313 | + clk_disable(i2c->clk); | |
| 1303 | 1314 | i2c->suspended = 0; |
| 1304 | 1315 | |
| 1305 | 1316 | return 0; |
| @@ -139,6 +139,7 @@ struct sh_mobile_i2c_data { · 138 unmodified lines | ||
| 139 | 139 | int pos; |
| 140 | 140 | int sr; |
| 141 | 141 | bool send_stop; |
| 142 | + bool stop_after_dma; | |
| 142 | 143 | |
| 143 | 144 | struct resource *res; |
| 144 | 145 | struct dma_chan *dma_tx; |
| @@ -407,7 +408,7 @@ static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd) · 262 unmodified lines | ||
| 407 | 408 | |
| 408 | 409 | if (pd->pos == pd->msg->len) { |
| 409 | 410 | /* Send stop if we haven't yet (DMA case) */ |
| 410 | − if (pd->send_stop && (iic_rd(pd, ICCR) & ICCR_BBSY)) | |
| 411 | + if (pd->send_stop && pd->stop_after_dma) | |
| 411 | 412 | i2c_op(pd, OP_TX_STOP, 0); |
| 412 | 413 | return 1; |
| 413 | 414 | } |
| @@ -449,6 +450,13 @@ static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd) · 35 unmodified lines | ||
| 449 | 450 | real_pos = pd->pos - 2; |
| 450 | 451 | |
| 451 | 452 | if (pd->pos == pd->msg->len) { |
| 453 | + if (pd->stop_after_dma) { | |
| 454 | + /* Simulate PIO end condition after DMA transfer */ | |
| 455 | + i2c_op(pd, OP_RX_STOP, 0); | |
| 456 | + pd->pos++; | |
| 457 | + break; | |
| 458 | + } | |
| 459 | + | |
| 452 | 460 | if (real_pos < 0) { |
| 453 | 461 | i2c_op(pd, OP_RX_STOP, 0); |
| 454 | 462 | break; |
| @@ -536,6 +544,7 @@ static void sh_mobile_i2c_dma_callback(void *data) · 81 unmodified lines | ||
| 536 | 544 | |
| 537 | 545 | sh_mobile_i2c_dma_unmap(pd); |
| 538 | 546 | pd->pos = pd->msg->len; |
| 547 | + pd->stop_after_dma = true; | |
| 539 | 548 | |
| 540 | 549 | iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); |
| 541 | 550 | } |
| @@ -726,6 +735,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, · 184 unmodified lines | ||
| 726 | 735 | bool do_start = pd->send_stop || !i; |
| 727 | 736 | msg = &msgs[i]; |
| 728 | 737 | pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP; |
| 738 | + pd->stop_after_dma = false; | |
| 729 | 739 | |
| 730 | 740 | err = start_ch(pd, msg, do_start); |
| 731 | 741 | if (err) |
| @@ -2972,6 +2972,7 @@ trace: · 2971 unmodified lines | ||
| 2972 | 2972 | } |
| 2973 | 2973 | EXPORT_SYMBOL(i2c_smbus_xfer); |
| 2974 | 2974 | |
| 2975 | +#if IS_ENABLED(CONFIG_I2C_SLAVE) | |
| 2975 | 2976 | int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) |
| 2976 | 2977 | { |
| 2977 | 2978 | int ret; |
| @@ -3019,6 +3020,7 @@ int i2c_slave_unregister(struct i2c_client *client) · 41 unmodified lines | ||
| 3019 | 3020 | return ret; |
| 3020 | 3021 | } |
| 3021 | 3022 | EXPORT_SYMBOL_GPL(i2c_slave_unregister); |
| 3023 | +#endif | |
| 3022 | 3024 | |
| 3023 | 3025 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); |
| 3024 | 3026 | MODULE_DESCRIPTION("I2C-Bus main module"); |
| @@ -74,7 +74,7 @@ static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj · 73 unmodified lines | ||
| 74 | 74 | struct eeprom_data *eeprom; |
| 75 | 75 | unsigned long flags; |
| 76 | 76 | |
| 77 | − if (off + count >= attr->size) | |
| 77 | + if (off + count > attr->size) | |
| 78 | 78 | return -EFBIG; |
| 79 | 79 | |
| 80 | 80 | eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
| @@ -92,7 +92,7 @@ static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kob · 11 unmodified lines | ||
| 92 | 92 | struct eeprom_data *eeprom; |
| 93 | 93 | unsigned long flags; |
| 94 | 94 | |
| 95 | − if (off + count >= attr->size) | |
| 95 | + if (off + count > attr->size) | |
| 96 | 96 | return -EFBIG; |
| 97 | 97 | |
| 98 | 98 | eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
| @@ -1097,6 +1097,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, · 1096 unmodified lines | ||
| 1097 | 1097 | * Asus UX31 0x361f00 20, 15, 0e clickpad |
| 1098 | 1098 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad |
| 1099 | 1099 | * Avatar AVIU-145A2 0x361f00 ? clickpad |
| 1100 | + * Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons | |
| 1101 | + * Fujitsu LIFEBOOK E554 0x570f01 40, 14, 0c 2 hw buttons | |
| 1100 | 1102 | * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) |
| 1101 | 1103 | * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons |
| 1102 | 1104 | * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) |
| @@ -1475,6 +1477,20 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { · 372 unmodified lines | ||
| 1475 | 1477 | DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), |
| 1476 | 1478 | }, |
| 1477 | 1479 | }, |
| 1480 | + { | |
| 1481 | + /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ | |
| 1482 | + .matches = { | |
| 1483 | + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | |
| 1484 | + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"), | |
| 1485 | + }, | |
| 1486 | + }, | |
| 1487 | + { | |
| 1488 | + /* Fujitsu LIFEBOOK E544 does not work with crc_enabled == 0 */ | |
| 1489 | + .matches = { | |
| 1490 | + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | |
| 1491 | + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"), | |
| 1492 | + }, | |
| 1493 | + }, | |
| 1478 | 1494 | #endif |
| 1479 | 1495 | { } |
| 1480 | 1496 | }; |
| @@ -135,8 +135,9 @@ static const struct min_max_quirk min_max_pnpid_table[] = { · 134 unmodified lines | ||
| 135 | 135 | 1232, 5710, 1156, 4696 |
| 136 | 136 | }, |
| 137 | 137 | { |
| 138 | − (const char * const []){"LEN0034", "LEN0036", "LEN0039", | |
| 139 | − "LEN2002", "LEN2004", NULL}, | |
| 138 | + (const char * const []){"LEN0034", "LEN0036", "LEN0037", | |
| 139 | + "LEN0039", "LEN2002", "LEN2004", | |
| 140 | + NULL}, | |
| 140 | 141 | 1024, 5112, 2024, 4832 |
| 141 | 142 | }, |
| 142 | 143 | { |
| @@ -165,7 +166,7 @@ static const char * const topbuttonpad_pnp_ids[] = { · 22 unmodified lines | ||
| 165 | 166 | "LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */ |
| 166 | 167 | "LEN0035", /* X240 */ |
| 167 | 168 | "LEN0036", /* T440 */ |
| 168 | − "LEN0037", | |
| 169 | + "LEN0037", /* X1 Carbon 2nd */ | |
| 169 | 170 | "LEN0038", |
| 170 | 171 | "LEN0039", /* T440s */ |
| 171 | 172 | "LEN0041", |
| @@ -151,6 +151,14 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { · 150 unmodified lines | ||
| 151 | 151 | DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), |
| 152 | 152 | }, |
| 153 | 153 | }, |
| 154 | + { | |
| 155 | + /* Medion Akoya E7225 */ | |
| 156 | + .matches = { | |
| 157 | + DMI_MATCH(DMI_SYS_VENDOR, "Medion"), | |
| 158 | + DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"), | |
| 159 | + DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), | |
| 160 | + }, | |
| 161 | + }, | |
| 154 | 162 | { |
| 155 | 163 | /* Blue FB5601 */ |
| 156 | 164 | .matches = { |
| @@ -315,6 +315,7 @@ static const struct iommu_ops gart_iommu_ops = { · 314 unmodified lines | ||
| 315 | 315 | .attach_dev = gart_iommu_attach_dev, |
| 316 | 316 | .detach_dev = gart_iommu_detach_dev, |
| 317 | 317 | .map = gart_iommu_map, |
| 318 | + .map_sg = default_iommu_map_sg, | |
| 318 | 319 | .unmap = gart_iommu_unmap, |
| 319 | 320 | .iova_to_phys = gart_iommu_iova_to_phys, |
| 320 | 321 | .pgsize_bitmap = GART_IOMMU_PGSIZES, |
| @@ -395,7 +396,7 @@ static int tegra_gart_probe(struct platform_device *pdev) · 74 unmodified lines | ||
| 395 | 396 | do_gart_setup(gart, NULL); |
| 396 | 397 | |
| 397 | 398 | gart_handle = gart; |
| 398 | − bus_set_iommu(&platform_bus_type, &gart_iommu_ops); | |
| 399 | + | |
| 399 | 400 | return 0; |
| 400 | 401 | } |
| 401 | 402 | |
| @@ -683,7 +683,7 @@ static struct dm_cache_metadata *metadata_open(struct block_device *bdev, · 682 unmodified lines | ||
| 683 | 683 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
| 684 | 684 | if (!cmd) { |
| 685 | 685 | DMERR("could not allocate metadata struct"); |
| 686 | − return NULL; | |
| 686 | + return ERR_PTR(-ENOMEM); | |
| 687 | 687 | } |
| 688 | 688 | |
| 689 | 689 | atomic_set(&cmd->ref_count, 1); |
| @@ -745,7 +745,7 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev, · 55 unmodified lines | ||
| 745 | 745 | return cmd; |
| 746 | 746 | |
| 747 | 747 | cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size); |
| 748 | − if (cmd) { | |
| 748 | + if (!IS_ERR(cmd)) { | |
| 749 | 749 | mutex_lock(&table_lock); |
| 750 | 750 | cmd2 = lookup(bdev); |
| 751 | 751 | if (cmd2) { |
| @@ -780,9 +780,10 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, · 28 unmodified lines | ||
| 780 | 780 | { |
| 781 | 781 | struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, |
| 782 | 782 | may_format_device, policy_hint_size); |
| 783 | − if (cmd && !same_params(cmd, data_block_size)) { | |
| 783 | + | |
| 784 | + if (!IS_ERR(cmd) && !same_params(cmd, data_block_size)) { | |
| 784 | 785 | dm_cache_metadata_close(cmd); |
| 785 | − return NULL; | |
| 786 | + return ERR_PTR(-EINVAL); | |
| 786 | 787 | } |
| 787 | 788 | |
| 788 | 789 | return cmd; |
| @@ -3385,6 +3385,12 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv) · 3384 unmodified lines | ||
| 3385 | 3385 | struct pool_c *pt = ti->private; |
| 3386 | 3386 | struct pool *pool = pt->pool; |
| 3387 | 3387 | |
| 3388 | + if (get_pool_mode(pool) >= PM_READ_ONLY) { | |
| 3389 | + DMERR("%s: unable to service pool target messages in READ_ONLY or FAIL mode", | |
| 3390 | + dm_device_name(pool->pool_md)); | |
| 3391 | + return -EINVAL; | |
| 3392 | + } | |
| 3393 | + | |
| 3388 | 3394 | if (!strcasecmp(argv[0], "create_thin")) |
| 3389 | 3395 | r = process_create_thin_mesg(argc, argv, pool); |
| 3390 | 3396 | |
| @@ -615,6 +615,9 @@ static void c_can_stop(struct net_device *dev) · 614 unmodified lines | ||
| 615 | 615 | |
| 616 | 616 | c_can_irq_control(priv, false); |
| 617 | 617 | |
| 618 | + /* put ctrl to init on stop to end ongoing transmission */ | |
| 619 | + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_INIT); | |
| 620 | + | |
| 618 | 621 | /* deactivate pins */ |
| 619 | 622 | pinctrl_pm_select_sleep_state(dev->dev.parent); |
| 620 | 623 | priv->can.state = CAN_STATE_STOPPED; |
| @@ -587,7 +587,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, · 586 unmodified lines | ||
| 587 | 587 | usb_sndbulkpipe(dev->udev, |
| 588 | 588 | dev->bulk_out->bEndpointAddress), |
| 589 | 589 | buf, msg->len, |
| 590 | − kvaser_usb_simple_msg_callback, priv); | |
| 590 | + kvaser_usb_simple_msg_callback, netdev); | |
| 591 | 591 | usb_anchor_urb(urb, &priv->tx_submitted); |
| 592 | 592 | |
| 593 | 593 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -662,11 +662,6 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, · 68 unmodified lines | ||
| 662 | 662 | priv = dev->nets[channel]; |
| 663 | 663 | stats = &priv->netdev->stats; |
| 664 | 664 | |
| 665 | − if (status & M16C_STATE_BUS_RESET) { | |
| 666 | − kvaser_usb_unlink_tx_urbs(priv); | |
| 667 | − return; | |
| 668 | − } | |
| 669 | − | |
| 670 | 665 | skb = alloc_can_err_skb(priv->netdev, &cf); |
| 671 | 666 | if (!skb) { |
| 672 | 667 | stats->rx_dropped++; |
| @@ -677,7 +672,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, · 4 unmodified lines | ||
| 677 | 672 | |
| 678 | 673 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); |
| 679 | 674 | |
| 680 | − if (status & M16C_STATE_BUS_OFF) { | |
| 675 | + if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { | |
| 681 | 676 | cf->can_id |= CAN_ERR_BUSOFF; |
| 682 | 677 | |
| 683 | 678 | priv->can.can_stats.bus_off++; |
| @@ -703,9 +698,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, · 19 unmodified lines | ||
| 703 | 698 | } |
| 704 | 699 | |
| 705 | 700 | new_state = CAN_STATE_ERROR_PASSIVE; |
| 706 | − } | |
| 707 | − | |
| 708 | − if (status == M16C_STATE_BUS_ERROR) { | |
| 701 | + } else if (status & M16C_STATE_BUS_ERROR) { | |
| 709 | 702 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && |
| 710 | 703 | ((txerr >= 96) || (rxerr >= 96))) { |
| 711 | 704 | cf->can_id |= CAN_ERR_CRTL; |
| @@ -715,7 +708,8 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, · 3 unmodified lines | ||
| 715 | 708 | |
| 716 | 709 | priv->can.can_stats.error_warning++; |
| 717 | 710 | new_state = CAN_STATE_ERROR_WARNING; |
| 718 | − } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) { | |
| 711 | + } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) && | |
| 712 | + ((txerr < 96) && (rxerr < 96))) { | |
| 719 | 713 | cf->can_id |= CAN_ERR_PROT; |
| 720 | 714 | cf->data[2] = CAN_ERR_PROT_ACTIVE; |
| 721 | 715 | |
| @@ -1590,7 +1584,7 @@ static int kvaser_usb_probe(struct usb_interface *intf, · 868 unmodified lines | ||
| 1590 | 1584 | { |
| 1591 | 1585 | struct kvaser_usb *dev; |
| 1592 | 1586 | int err = -ENOMEM; |
| 1593 | − int i; | |
| 1587 | + int i, retry = 3; | |
| 1594 | 1588 | |
| 1595 | 1589 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); |
| 1596 | 1590 | if (!dev) |
| @@ -1608,7 +1602,15 @@ static int kvaser_usb_probe(struct usb_interface *intf, · 11 unmodified lines | ||
| 1608 | 1602 | |
| 1609 | 1603 | usb_set_intfdata(intf, dev); |
| 1610 | 1604 | |
| 1611 | − err = kvaser_usb_get_software_info(dev); | |
| 1605 | + /* On some x86 laptops, plugging a Kvaser device again after | |
| 1606 | + * an unplug makes the firmware always ignore the very first | |
| 1607 | + * command. For such a case, provide some room for retries | |
| 1608 | + * instead of completely exiting the driver. | |
| 1609 | + */ | |
| 1610 | + do { | |
| 1611 | + err = kvaser_usb_get_software_info(dev); | |
| 1612 | + } while (--retry && err == -ETIMEDOUT); | |
| 1613 | + | |
| 1612 | 1614 | if (err) { |
| 1613 | 1615 | dev_err(&intf->dev, |
| 1614 | 1616 | "Cannot get software infos, error %d\n", err); |
| @@ -767,16 +767,17 @@ · 766 unmodified lines | ||
| 767 | 767 | #define MTL_Q_RQOMR 0x40 |
| 768 | 768 | #define MTL_Q_RQMPOCR 0x44 |
| 769 | 769 | #define MTL_Q_RQDR 0x4c |
| 770 | +#define MTL_Q_RQFCR 0x50 | |
| 770 | 771 | #define MTL_Q_IER 0x70 |
| 771 | 772 | #define MTL_Q_ISR 0x74 |
| 772 | 773 | |
| 773 | 774 | /* MTL queue register entry bit positions and sizes */ |
| 775 | +#define MTL_Q_RQFCR_RFA_INDEX 1 | |
| 776 | +#define MTL_Q_RQFCR_RFA_WIDTH 6 | |
| 777 | +#define MTL_Q_RQFCR_RFD_INDEX 17 | |
| 778 | +#define MTL_Q_RQFCR_RFD_WIDTH 6 | |
| 774 | 779 | #define MTL_Q_RQOMR_EHFC_INDEX 7 |
| 775 | 780 | #define MTL_Q_RQOMR_EHFC_WIDTH 1 |
| 776 | −#define MTL_Q_RQOMR_RFA_INDEX 8 | |
| 777 | −#define MTL_Q_RQOMR_RFA_WIDTH 3 | |
| 778 | −#define MTL_Q_RQOMR_RFD_INDEX 13 | |
| 779 | −#define MTL_Q_RQOMR_RFD_WIDTH 3 | |
| 780 | 781 | #define MTL_Q_RQOMR_RQS_INDEX 16 |
| 781 | 782 | #define MTL_Q_RQOMR_RQS_WIDTH 9 |
| 782 | 783 | #define MTL_Q_RQOMR_RSF_INDEX 5 |
| @@ -2079,10 +2079,10 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata) · 2078 unmodified lines | ||
| 2079 | 2079 | |
| 2080 | 2080 | for (i = 0; i < pdata->rx_q_count; i++) { |
| 2081 | 2081 | /* Activate flow control when less than 4k left in fifo */ |
| 2082 | − XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2); | |
| 2082 | + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFA, 2); | |
| 2083 | 2083 | |
| 2084 | 2084 | /* De-activate flow control when more than 6k left in fifo */ |
| 2085 | − XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFD, 4); | |
| 2085 | + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFD, 4); | |
| 2086 | 2086 | } |
| 2087 | 2087 | } |
| 2088 | 2088 | |
| @@ -3175,7 +3175,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) · 3174 unmodified lines | ||
| 3175 | 3175 | } |
| 3176 | 3176 | #endif |
| 3177 | 3177 | if (!bnx2x_fp_lock_napi(fp)) |
| 3178 | − return work_done; | |
| 3178 | + return budget; | |
| 3179 | 3179 | |
| 3180 | 3180 | for_each_cos_in_tx_queue(fp, cos) |
| 3181 | 3181 | if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) |
| @@ -1335,7 +1335,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget) · 1334 unmodified lines | ||
| 1335 | 1335 | int err; |
| 1336 | 1336 | |
| 1337 | 1337 | if (!enic_poll_lock_napi(&enic->rq[rq])) |
| 1338 | − return work_done; | |
| 1338 | + return budget; | |
| 1339 | 1339 | /* Service RQ |
| 1340 | 1340 | */ |
| 1341 | 1341 | |
| @@ -192,6 +192,10 @@ static char mv643xx_eth_driver_version[] = "1.4"; · 191 unmodified lines | ||
| 192 | 192 | #define IS_TSO_HEADER(txq, addr) \ |
| 193 | 193 | ((addr >= txq->tso_hdrs_dma) && \ |
| 194 | 194 | (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE)) |
| 195 | + | |
| 196 | +#define DESC_DMA_MAP_SINGLE 0 | |
| 197 | +#define DESC_DMA_MAP_PAGE 1 | |
| 198 | + | |
| 195 | 199 | /* |
| 196 | 200 | * RX/TX descriptors. |
| 197 | 201 | */ |
| @@ -362,6 +366,7 @@ struct tx_queue { · 164 unmodified lines | ||
| 362 | 366 | dma_addr_t tso_hdrs_dma; |
| 363 | 367 | |
| 364 | 368 | struct tx_desc *tx_desc_area; |
| 369 | + char *tx_desc_mapping; /* array to track the type of the dma mapping */ | |
| 365 | 370 | dma_addr_t tx_desc_dma; |
| 366 | 371 | int tx_desc_area_size; |
| 367 | 372 | |
| @@ -750,6 +755,7 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq, · 382 unmodified lines | ||
| 750 | 755 | if (txq->tx_curr_desc == txq->tx_ring_size) |
| 751 | 756 | txq->tx_curr_desc = 0; |
| 752 | 757 | desc = &txq->tx_desc_area[tx_index]; |
| 758 | + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; | |
| 753 | 759 | |
| 754 | 760 | desc->l4i_chk = 0; |
| 755 | 761 | desc->byte_cnt = length; |
| @@ -879,14 +885,13 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) · 123 unmodified lines | ||
| 879 | 885 | skb_frag_t *this_frag; |
| 880 | 886 | int tx_index; |
| 881 | 887 | struct tx_desc *desc; |
| 882 | − void *addr; | |
| 883 | 888 | |
| 884 | 889 | this_frag = &skb_shinfo(skb)->frags[frag]; |
| 885 | − addr = page_address(this_frag->page.p) + this_frag->page_offset; | |
| 886 | 890 | tx_index = txq->tx_curr_desc++; |
| 887 | 891 | if (txq->tx_curr_desc == txq->tx_ring_size) |
| 888 | 892 | txq->tx_curr_desc = 0; |
| 889 | 893 | desc = &txq->tx_desc_area[tx_index]; |
| 894 | + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_PAGE; | |
| 890 | 895 | |
| 891 | 896 | /* |
| 892 | 897 | * The last fragment will generate an interrupt |
| @@ -902,8 +907,9 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) · 9 unmodified lines | ||
| 902 | 907 | |
| 903 | 908 | desc->l4i_chk = 0; |
| 904 | 909 | desc->byte_cnt = skb_frag_size(this_frag); |
| 905 | − desc->buf_ptr = dma_map_single(mp->dev->dev.parent, addr, | |
| 906 | − desc->byte_cnt, DMA_TO_DEVICE); | |
| 910 | + desc->buf_ptr = skb_frag_dma_map(mp->dev->dev.parent, | |
| 911 | + this_frag, 0, desc->byte_cnt, | |
| 912 | + DMA_TO_DEVICE); | |
| 907 | 913 | } |
| 908 | 914 | } |
| 909 | 915 | |
| @@ -936,6 +942,7 @@ static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb, · 26 unmodified lines | ||
| 936 | 942 | if (txq->tx_curr_desc == txq->tx_ring_size) |
| 937 | 943 | txq->tx_curr_desc = 0; |
| 938 | 944 | desc = &txq->tx_desc_area[tx_index]; |
| 945 | + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; | |
| 939 | 946 | |
| 940 | 947 | if (nr_frags) { |
| 941 | 948 | txq_submit_frag_skb(txq, skb); |
| @@ -1047,9 +1054,12 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) · 105 unmodified lines | ||
| 1047 | 1054 | int tx_index; |
| 1048 | 1055 | struct tx_desc *desc; |
| 1049 | 1056 | u32 cmd_sts; |
| 1057 | + char desc_dma_map; | |
| 1050 | 1058 | |
| 1051 | 1059 | tx_index = txq->tx_used_desc; |
| 1052 | 1060 | desc = &txq->tx_desc_area[tx_index]; |
| 1061 | + desc_dma_map = txq->tx_desc_mapping[tx_index]; | |
| 1062 | + | |
| 1053 | 1063 | cmd_sts = desc->cmd_sts; |
| 1054 | 1064 | |
| 1055 | 1065 | if (cmd_sts & BUFFER_OWNED_BY_DMA) { |
| @@ -1065,9 +1075,19 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) · 9 unmodified lines | ||
| 1065 | 1075 | reclaimed++; |
| 1066 | 1076 | txq->tx_desc_count--; |
| 1067 | 1077 | |
| 1068 | − if (!IS_TSO_HEADER(txq, desc->buf_ptr)) | |
| 1069 | − dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, | |
| 1070 | − desc->byte_cnt, DMA_TO_DEVICE); | |
| 1078 | + if (!IS_TSO_HEADER(txq, desc->buf_ptr)) { | |
| 1079 | + | |
| 1080 | + if (desc_dma_map == DESC_DMA_MAP_PAGE) | |
| 1081 | + dma_unmap_page(mp->dev->dev.parent, | |
| 1082 | + desc->buf_ptr, | |
| 1083 | + desc->byte_cnt, | |
| 1084 | + DMA_TO_DEVICE); | |
| 1085 | + else | |
| 1086 | + dma_unmap_single(mp->dev->dev.parent, | |
| 1087 | + desc->buf_ptr, | |
| 1088 | + desc->byte_cnt, | |
| 1089 | + DMA_TO_DEVICE); | |
| 1090 | + } | |
| 1071 | 1091 | |
| 1072 | 1092 | if (cmd_sts & TX_ENABLE_INTERRUPT) { |
| 1073 | 1093 | struct sk_buff *skb = __skb_dequeue(&txq->tx_skb); |
| @@ -1996,6 +2016,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) · 922 unmodified lines | ||
| 1996 | 2016 | struct tx_queue *txq = mp->txq + index; |
| 1997 | 2017 | struct tx_desc *tx_desc; |
| 1998 | 2018 | int size; |
| 2019 | + int ret; | |
| 1999 | 2020 | int i; |
| 2000 | 2021 | |
| 2001 | 2022 | txq->index = index; |
| @@ -2048,18 +2069,34 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) · 46 unmodified lines | ||
| 2048 | 2069 | nexti * sizeof(struct tx_desc); |
| 2049 | 2070 | } |
| 2050 | 2071 | |
| 2072 | + txq->tx_desc_mapping = kcalloc(txq->tx_ring_size, sizeof(char), | |
| 2073 | + GFP_KERNEL); | |
| 2074 | + if (!txq->tx_desc_mapping) { | |
| 2075 | + ret = -ENOMEM; | |
| 2076 | + goto err_free_desc_area; | |
| 2077 | + } | |
| 2078 | + | |
| 2051 | 2079 | /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ |
| 2052 | 2080 | txq->tso_hdrs = dma_alloc_coherent(mp->dev->dev.parent, |
| 2053 | 2081 | txq->tx_ring_size * TSO_HEADER_SIZE, |
| 2054 | 2082 | &txq->tso_hdrs_dma, GFP_KERNEL); |
| 2055 | 2083 | if (txq->tso_hdrs == NULL) { |
| 2056 | − dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | |
| 2057 | − txq->tx_desc_area, txq->tx_desc_dma); | |
| 2058 | − return -ENOMEM; | |
| 2084 | + ret = -ENOMEM; | |
| 2085 | + goto err_free_desc_mapping; | |
| 2059 | 2086 | } |
| 2060 | 2087 | skb_queue_head_init(&txq->tx_skb); |
| 2061 | 2088 | |
| 2062 | 2089 | return 0; |
| 2090 | + | |
| 2091 | +err_free_desc_mapping: | |
| 2092 | + kfree(txq->tx_desc_mapping); | |
| 2093 | +err_free_desc_area: | |
| 2094 | + if (index == 0 && size <= mp->tx_desc_sram_size) | |
| 2095 | + iounmap(txq->tx_desc_area); | |
| 2096 | + else | |
| 2097 | + dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | |
| 2098 | + txq->tx_desc_area, txq->tx_desc_dma); | |
| 2099 | + return ret; | |
| 2063 | 2100 | } |
| 2064 | 2101 | |
| 2065 | 2102 | static void txq_deinit(struct tx_queue *txq) |
| @@ -2077,6 +2114,8 @@ static void txq_deinit(struct tx_queue *txq) · 11 unmodified lines | ||
| 2077 | 2114 | else |
| 2078 | 2115 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, |
| 2079 | 2116 | txq->tx_desc_area, txq->tx_desc_dma); |
| 2117 | + kfree(txq->tx_desc_mapping); | |
| 2118 | + | |
| 2080 | 2119 | if (txq->tso_hdrs) |
| 2081 | 2120 | dma_free_coherent(mp->dev->dev.parent, |
| 2082 | 2121 | txq->tx_ring_size * TSO_HEADER_SIZE, |
| @@ -2388,7 +2388,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) · 2387 unmodified lines | ||
| 2388 | 2388 | |
| 2389 | 2389 | work_done = netxen_process_rcv_ring(sds_ring, budget); |
| 2390 | 2390 | |
| 2391 | − if ((work_done < budget) && tx_complete) { | |
| 2391 | + if (!tx_complete) | |
| 2392 | + work_done = budget; | |
| 2393 | + | |
| 2394 | + if (work_done < budget) { | |
| 2392 | 2395 | napi_complete(&sds_ring->napi); |
| 2393 | 2396 | if (test_bit(__NX_DEV_UP, &adapter->state)) |
| 2394 | 2397 | netxen_nic_enable_int(sds_ring); |
| @@ -396,6 +396,9 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { · 395 unmodified lines | ||
| 396 | 396 | [TSU_ADRL31] = 0x01fc, |
| 397 | 397 | }; |
| 398 | 398 | |
| 399 | +static void sh_eth_rcv_snd_disable(struct net_device *ndev); | |
| 400 | +static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev); | |
| 401 | + | |
| 399 | 402 | static bool sh_eth_is_gether(struct sh_eth_private *mdp) |
| 400 | 403 | { |
| 401 | 404 | return mdp->reg_offset == sh_eth_offset_gigabit; |
| @@ -1120,6 +1123,7 @@ static void sh_eth_ring_format(struct net_device *ndev) · 718 unmodified lines | ||
| 1120 | 1123 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; |
| 1121 | 1124 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; |
| 1122 | 1125 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; |
| 1126 | + dma_addr_t dma_addr; | |
| 1123 | 1127 | |
| 1124 | 1128 | mdp->cur_rx = 0; |
| 1125 | 1129 | mdp->cur_tx = 0; |
| @@ -1133,7 +1137,6 @@ static void sh_eth_ring_format(struct net_device *ndev) · 7 unmodified lines | ||
| 1133 | 1137 | /* skb */ |
| 1134 | 1138 | mdp->rx_skbuff[i] = NULL; |
| 1135 | 1139 | skb = netdev_alloc_skb(ndev, skbuff_size); |
| 1136 | − mdp->rx_skbuff[i] = skb; | |
| 1137 | 1140 | if (skb == NULL) |
| 1138 | 1141 | break; |
| 1139 | 1142 | sh_eth_set_receive_align(skb); |
| @@ -1142,9 +1145,15 @@ static void sh_eth_ring_format(struct net_device *ndev) · 2 unmodified lines | ||
| 1142 | 1145 | rxdesc = &mdp->rx_ring[i]; |
| 1143 | 1146 | /* The size of the buffer is a multiple of 16 bytes. */ |
| 1144 | 1147 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); |
| 1145 | − dma_map_single(&ndev->dev, skb->data, rxdesc->buffer_length, | |
| 1146 | − DMA_FROM_DEVICE); | |
| 1147 | − rxdesc->addr = virt_to_phys(skb->data); | |
| 1148 | + dma_addr = dma_map_single(&ndev->dev, skb->data, | |
| 1149 | + rxdesc->buffer_length, | |
| 1150 | + DMA_FROM_DEVICE); | |
| 1151 | + if (dma_mapping_error(&ndev->dev, dma_addr)) { | |
| 1152 | + kfree_skb(skb); | |
| 1153 | + break; | |
| 1154 | + } | |
| 1155 | + mdp->rx_skbuff[i] = skb; | |
| 1156 | + rxdesc->addr = dma_addr; | |
| 1148 | 1157 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); |
| 1149 | 1158 | |
| 1150 | 1159 | /* Rx descriptor address set */ |
| @@ -1316,8 +1325,10 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) · 165 unmodified lines | ||
| 1316 | 1325 | RFLR); |
| 1317 | 1326 | |
| 1318 | 1327 | sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); |
| 1319 | − if (start) | |
| 1328 | + if (start) { | |
| 1329 | + mdp->irq_enabled = true; | |
| 1320 | 1330 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
| 1331 | + } | |
| 1321 | 1332 | |
| 1322 | 1333 | /* PAUSE Prohibition */ |
| 1323 | 1334 | val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | |
| @@ -1356,6 +1367,33 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) · 32 unmodified lines | ||
| 1356 | 1367 | return ret; |
| 1357 | 1368 | } |
| 1358 | 1369 | |
| 1370 | +static void sh_eth_dev_exit(struct net_device *ndev) | |
| 1371 | +{ | |
| 1372 | + struct sh_eth_private *mdp = netdev_priv(ndev); | |
| 1373 | + int i; | |
| 1374 | + | |
| 1375 | + /* Deactivate all TX descriptors, so DMA should stop at next | |
| 1376 | + * packet boundary if it's currently running | |
| 1377 | + */ | |
| 1378 | + for (i = 0; i < mdp->num_tx_ring; i++) | |
| 1379 | + mdp->tx_ring[i].status &= ~cpu_to_edmac(mdp, TD_TACT); | |
| 1380 | + | |
| 1381 | + /* Disable TX FIFO egress to MAC */ | |
| 1382 | + sh_eth_rcv_snd_disable(ndev); | |
| 1383 | + | |
| 1384 | + /* Stop RX DMA at next packet boundary */ | |
| 1385 | + sh_eth_write(ndev, 0, EDRRR); | |
| 1386 | + | |
| 1387 | + /* Aside from TX DMA, we can't tell when the hardware is | |
| 1388 | + * really stopped, so we need to reset to make sure. | |
| 1389 | + * Before doing that, wait for long enough to *probably* | |
| 1390 | + * finish transmitting the last packet and poll stats. | |
| 1391 | + */ | |
| 1392 | + msleep(2); /* max frame time at 10 Mbps < 1250 us */ | |
| 1393 | + sh_eth_get_stats(ndev); | |
| 1394 | + sh_eth_reset(ndev); | |
| 1395 | +} | |
| 1396 | + | |
| 1359 | 1397 | /* free Tx skb function */ |
| 1360 | 1398 | static int sh_eth_txfree(struct net_device *ndev) |
| 1361 | 1399 | { |
| @@ -1400,6 +1438,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) · 38 unmodified lines | ||
| 1400 | 1438 | u16 pkt_len = 0; |
| 1401 | 1439 | u32 desc_status; |
| 1402 | 1440 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; |
| 1441 | + dma_addr_t dma_addr; | |
| 1403 | 1442 | |
| 1404 | 1443 | boguscnt = min(boguscnt, *quota); |
| 1405 | 1444 | limit = boguscnt; |
| @@ -1447,9 +1486,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) · 41 unmodified lines | ||
| 1447 | 1486 | mdp->rx_skbuff[entry] = NULL; |
| 1448 | 1487 | if (mdp->cd->rpadir) |
| 1449 | 1488 | skb_reserve(skb, NET_IP_ALIGN); |
| 1450 | − dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, | |
| 1451 | − ALIGN(mdp->rx_buf_sz, 16), | |
| 1452 | − DMA_FROM_DEVICE); | |
| 1489 | + dma_unmap_single(&ndev->dev, rxdesc->addr, | |
| 1490 | + ALIGN(mdp->rx_buf_sz, 16), | |
| 1491 | + DMA_FROM_DEVICE); | |
| 1453 | 1492 | skb_put(skb, pkt_len); |
| 1454 | 1493 | skb->protocol = eth_type_trans(skb, ndev); |
| 1455 | 1494 | netif_receive_skb(skb); |
| @@ -1469,15 +1508,20 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) · 13 unmodified lines | ||
| 1469 | 1508 | |
| 1470 | 1509 | if (mdp->rx_skbuff[entry] == NULL) { |
| 1471 | 1510 | skb = netdev_alloc_skb(ndev, skbuff_size); |
| 1472 | − mdp->rx_skbuff[entry] = skb; | |
| 1473 | 1511 | if (skb == NULL) |
| 1474 | 1512 | break; /* Better luck next round. */ |
| 1475 | 1513 | sh_eth_set_receive_align(skb); |
| 1476 | − dma_map_single(&ndev->dev, skb->data, | |
| 1477 | − rxdesc->buffer_length, DMA_FROM_DEVICE); | |
| 1514 | + dma_addr = dma_map_single(&ndev->dev, skb->data, | |
| 1515 | + rxdesc->buffer_length, | |
| 1516 | + DMA_FROM_DEVICE); | |
| 1517 | + if (dma_mapping_error(&ndev->dev, dma_addr)) { | |
| 1518 | + kfree_skb(skb); | |
| 1519 | + break; | |
| 1520 | + } | |
| 1521 | + mdp->rx_skbuff[entry] = skb; | |
| 1478 | 1522 | |
| 1479 | 1523 | skb_checksum_none_assert(skb); |
| 1480 | − rxdesc->addr = virt_to_phys(skb->data); | |
| 1524 | + rxdesc->addr = dma_addr; | |
| 1481 | 1525 | } |
| 1482 | 1526 | if (entry >= mdp->num_rx_ring - 1) |
| 1483 | 1527 | rxdesc->status |= |
| @@ -1573,7 +1617,6 @@ ignore_link: · 89 unmodified lines | ||
| 1573 | 1617 | if (intr_status & EESR_RFRMER) { |
| 1574 | 1618 | /* Receive Frame Overflow int */ |
| 1575 | 1619 | ndev->stats.rx_frame_errors++; |
| 1576 | − netif_err(mdp, rx_err, ndev, "Receive Abort\n"); | |
| 1577 | 1620 | } |
| 1578 | 1621 | } |
| 1579 | 1622 | |
| @@ -1592,13 +1635,11 @@ ignore_link: · 12 unmodified lines | ||
| 1592 | 1635 | if (intr_status & EESR_RDE) { |
| 1593 | 1636 | /* Receive Descriptor Empty int */ |
| 1594 | 1637 | ndev->stats.rx_over_errors++; |
| 1595 | − netif_err(mdp, rx_err, ndev, "Receive Descriptor Empty\n"); | |
| 1596 | 1638 | } |
| 1597 | 1639 | |
| 1598 | 1640 | if (intr_status & EESR_RFE) { |
| 1599 | 1641 | /* Receive FIFO Overflow int */ |
| 1600 | 1642 | ndev->stats.rx_fifo_errors++; |
| 1601 | − netif_err(mdp, rx_err, ndev, "Receive FIFO Overflow\n"); | |
| 1602 | 1643 | } |
| 1603 | 1644 | |
| 1604 | 1645 | if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { |
| @@ -1653,7 +1694,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) · 48 unmodified lines | ||
| 1653 | 1694 | if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) |
| 1654 | 1695 | ret = IRQ_HANDLED; |
| 1655 | 1696 | else |
| 1656 | − goto other_irq; | |
| 1697 | + goto out; | |
| 1698 | + | |
| 1699 | + if (!likely(mdp->irq_enabled)) { | |
| 1700 | + sh_eth_write(ndev, 0, EESIPR); | |
| 1701 | + goto out; | |
| 1702 | + } | |
| 1657 | 1703 | |
| 1658 | 1704 | if (intr_status & EESR_RX_CHECK) { |
| 1659 | 1705 | if (napi_schedule_prep(&mdp->napi)) { |
| @@ -1684,7 +1730,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) · 24 unmodified lines | ||
| 1684 | 1730 | sh_eth_error(ndev, intr_status); |
| 1685 | 1731 | } |
| 1686 | 1732 | |
| 1687 | −other_irq: | |
| 1733 | +out: | |
| 1688 | 1734 | spin_unlock(&mdp->lock); |
| 1689 | 1735 | |
| 1690 | 1736 | return ret; |
| @@ -1712,7 +1758,8 @@ static int sh_eth_poll(struct napi_struct *napi, int budget) · 21 unmodified lines | ||
| 1712 | 1758 | napi_complete(napi); |
| 1713 | 1759 | |
| 1714 | 1760 | /* Reenable Rx interrupts */ |
| 1715 | − sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | |
| 1761 | + if (mdp->irq_enabled) | |
| 1762 | + sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | |
| 1716 | 1763 | out: |
| 1717 | 1764 | return budget - quota; |
| 1718 | 1765 | } |
| @@ -1968,40 +2015,50 @@ static int sh_eth_set_ringparam(struct net_device *ndev, · 249 unmodified lines | ||
| 1968 | 2015 | return -EINVAL; |
| 1969 | 2016 | |
| 1970 | 2017 | if (netif_running(ndev)) { |
| 2018 | + netif_device_detach(ndev); | |
| 1971 | 2019 | netif_tx_disable(ndev); |
| 1972 | − /* Disable interrupts by clearing the interrupt mask. */ | |
| 1973 | − sh_eth_write(ndev, 0x0000, EESIPR); | |
| 1974 | − /* Stop the chip's Tx and Rx processes. */ | |
| 1975 | − sh_eth_write(ndev, 0, EDTRR); | |
| 1976 | − sh_eth_write(ndev, 0, EDRRR); | |
| 2020 | + | |
| 2021 | + /* Serialise with the interrupt handler and NAPI, then | |
| 2022 | + * disable interrupts. We have to clear the | |
| 2023 | + * irq_enabled flag first to ensure that interrupts | |
| 2024 | + * won't be re-enabled. | |
| 2025 | + */ | |
| 2026 | + mdp->irq_enabled = false; | |
| 1977 | 2027 | synchronize_irq(ndev->irq); |
| 1978 | − } | |
| 2028 | + napi_synchronize(&mdp->napi); | |
| 2029 | + sh_eth_write(ndev, 0x0000, EESIPR); | |
| 1979 | 2030 | |
| 1980 | − /* Free all the skbuffs in the Rx queue. */ | |
| 1981 | − sh_eth_ring_free(ndev); | |
| 1982 | − /* Free DMA buffer */ | |
| 1983 | − sh_eth_free_dma_buffer(mdp); | |
| 2031 | + sh_eth_dev_exit(ndev); | |
| 2032 | + | |
| 2033 | + /* Free all the skbuffs in the Rx queue. */ | |
| 2034 | + sh_eth_ring_free(ndev); | |
| 2035 | + /* Free DMA buffer */ | |
| 2036 | + sh_eth_free_dma_buffer(mdp); | |
| 2037 | + } | |
| 1984 | 2038 | |
| 1985 | 2039 | /* Set new parameters */ |
| 1986 | 2040 | mdp->num_rx_ring = ring->rx_pending; |
| 1987 | 2041 | mdp->num_tx_ring = ring->tx_pending; |
| 1988 | 2042 | |
| 1989 | − ret = sh_eth_ring_init(ndev); | |
| 1990 | − if (ret < 0) { | |
| 1991 | − netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", __func__); | |
| 1992 | − return ret; | |
| 1993 | − } | |
| 1994 | − ret = sh_eth_dev_init(ndev, false); | |
| 1995 | − if (ret < 0) { | |
| 1996 | − netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); | |
| 1997 | − return ret; | |
| 1998 | − } | |
| 1999 | − | |
| 2000 | 2043 | if (netif_running(ndev)) { |
| 2044 | + ret = sh_eth_ring_init(ndev); | |
| 2045 | + if (ret < 0) { | |
| 2046 | + netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", | |
| 2047 | + __func__); | |
| 2048 | + return ret; | |
| 2049 | + } | |
| 2050 | + ret = sh_eth_dev_init(ndev, false); | |
| 2051 | + if (ret < 0) { | |
| 2052 | + netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", | |
| 2053 | + __func__); | |
| 2054 | + return ret; | |
| 2055 | + } | |
| 2056 | + | |
| 2057 | + mdp->irq_enabled = true; | |
| 2001 | 2058 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
| 2002 | 2059 | /* Setting the Rx mode will start the Rx process. */ |
| 2003 | 2060 | sh_eth_write(ndev, EDRRR_R, EDRRR); |
| 2004 | − netif_wake_queue(ndev); | |
| 2061 | + netif_device_attach(ndev); | |
| 2005 | 2062 | } |
| 2006 | 2063 | |
| 2007 | 2064 | return 0; |
| @@ -2117,6 +2174,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 109 unmodified lines | ||
| 2117 | 2174 | } |
| 2118 | 2175 | spin_unlock_irqrestore(&mdp->lock, flags); |
| 2119 | 2176 | |
| 2177 | + if (skb_padto(skb, ETH_ZLEN)) | |
| 2178 | + return NETDEV_TX_OK; | |
| 2179 | + | |
| 2120 | 2180 | entry = mdp->cur_tx % mdp->num_tx_ring; |
| 2121 | 2181 | mdp->tx_skbuff[entry] = skb; |
| 2122 | 2182 | txdesc = &mdp->tx_ring[entry]; |
| @@ -2126,10 +2186,11 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 3 unmodified lines | ||
| 2126 | 2186 | skb->len + 2); |
| 2127 | 2187 | txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, |
| 2128 | 2188 | DMA_TO_DEVICE); |
| 2129 | − if (skb->len < ETH_ZLEN) | |
| 2130 | − txdesc->buffer_length = ETH_ZLEN; | |
| 2131 | − else | |
| 2132 | − txdesc->buffer_length = skb->len; | |
| 2189 | + if (dma_mapping_error(&ndev->dev, txdesc->addr)) { | |
| 2190 | + kfree_skb(skb); | |
| 2191 | + return NETDEV_TX_OK; | |
| 2192 | + } | |
| 2193 | + txdesc->buffer_length = skb->len; | |
| 2133 | 2194 | |
| 2134 | 2195 | if (entry >= mdp->num_tx_ring - 1) |
| 2135 | 2196 | txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); |
| @@ -2181,14 +2242,17 @@ static int sh_eth_close(struct net_device *ndev) · 45 unmodified lines | ||
| 2181 | 2242 | |
| 2182 | 2243 | netif_stop_queue(ndev); |
| 2183 | 2244 | |
| 2184 | − /* Disable interrupts by clearing the interrupt mask. */ | |
| 2245 | + /* Serialise with the interrupt handler and NAPI, then disable | |
| 2246 | + * interrupts. We have to clear the irq_enabled flag first to | |
| 2247 | + * ensure that interrupts won't be re-enabled. | |
| 2248 | + */ | |
| 2249 | + mdp->irq_enabled = false; | |
| 2250 | + synchronize_irq(ndev->irq); | |
| 2251 | + napi_disable(&mdp->napi); | |
| 2185 | 2252 | sh_eth_write(ndev, 0x0000, EESIPR); |
| 2186 | 2253 | |
| 2187 | − /* Stop the chip's Tx and Rx processes. */ | |
| 2188 | − sh_eth_write(ndev, 0, EDTRR); | |
| 2189 | − sh_eth_write(ndev, 0, EDRRR); | |
| 2254 | + sh_eth_dev_exit(ndev); | |
| 2190 | 2255 | |
| 2191 | − sh_eth_get_stats(ndev); | |
| 2192 | 2256 | /* PHY Disconnect */ |
| 2193 | 2257 | if (mdp->phydev) { |
| 2194 | 2258 | phy_stop(mdp->phydev); |
| @@ -2198,8 +2262,6 @@ static int sh_eth_close(struct net_device *ndev) · 3 unmodified lines | ||
| 2198 | 2262 | |
| 2199 | 2263 | free_irq(ndev->irq, ndev); |
| 2200 | 2264 | |
| 2201 | − napi_disable(&mdp->napi); | |
| 2202 | − | |
| 2203 | 2265 | /* Free all the skbuffs in the Rx queue. */ |
| 2204 | 2266 | sh_eth_ring_free(ndev); |
| 2205 | 2267 | |
| @@ -513,6 +513,7 @@ struct sh_eth_private { · 512 unmodified lines | ||
| 513 | 513 | u32 rx_buf_sz; /* Based on MTU+slack. */ |
| 514 | 514 | int edmac_endian; |
| 515 | 515 | struct napi_struct napi; |
| 516 | + bool irq_enabled; | |
| 516 | 517 | /* MII transceiver section. */ |
| 517 | 518 | u32 phy_id; /* PHY ID */ |
| 518 | 519 | struct mii_bus *mii_bus; /* MDIO bus control */ |
| @@ -2778,6 +2778,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv) · 2777 unmodified lines | ||
| 2778 | 2778 | * @addr: iobase memory address |
| 2779 | 2779 | * Description: this is the main probe function used to |
| 2780 | 2780 | * call the alloc_etherdev, allocate the priv structure. |
| 2781 | + * Return: | |
| 2782 | + * on success the new private structure is returned, otherwise the error | |
| 2783 | + * pointer. | |
| 2781 | 2784 | */ |
| 2782 | 2785 | struct stmmac_priv *stmmac_dvr_probe(struct device *device, |
| 2783 | 2786 | struct plat_stmmacenet_data *plat_dat, |
| @@ -2789,7 +2792,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, · 5 unmodified lines | ||
| 2789 | 2792 | |
| 2790 | 2793 | ndev = alloc_etherdev(sizeof(struct stmmac_priv)); |
| 2791 | 2794 | if (!ndev) |
| 2792 | − return NULL; | |
| 2795 | + return ERR_PTR(-ENOMEM); | |
| 2793 | 2796 | |
| 2794 | 2797 | SET_NETDEV_DEV(ndev, device); |
| 2795 | 2798 | |
| @@ -1683,6 +1683,19 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, · 1682 unmodified lines | ||
| 1683 | 1683 | if (vid == priv->data.default_vlan) |
| 1684 | 1684 | return 0; |
| 1685 | 1685 | |
| 1686 | + if (priv->data.dual_emac) { | |
| 1687 | + /* In dual EMAC, reserved VLAN id should not be used for | |
| 1688 | + * creating VLAN interfaces as this can break the dual | |
| 1689 | + * EMAC port separation | |
| 1690 | + */ | |
| 1691 | + int i; | |
| 1692 | + | |
| 1693 | + for (i = 0; i < priv->data.slaves; i++) { | |
| 1694 | + if (vid == priv->slaves[i].port_vlan) | |
| 1695 | + return -EINVAL; | |
| 1696 | + } | |
| 1697 | + } | |
| 1698 | + | |
| 1686 | 1699 | dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); |
| 1687 | 1700 | return cpsw_add_vlan_ale_entry(priv, vid); |
| 1688 | 1701 | } |
| @@ -1696,6 +1709,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, · 7 unmodified lines | ||
| 1696 | 1709 | if (vid == priv->data.default_vlan) |
| 1697 | 1710 | return 0; |
| 1698 | 1711 | |
| 1712 | + if (priv->data.dual_emac) { | |
| 1713 | + int i; | |
| 1714 | + | |
| 1715 | + for (i = 0; i < priv->data.slaves; i++) { | |
| 1716 | + if (vid == priv->slaves[i].port_vlan) | |
| 1717 | + return -EINVAL; | |
| 1718 | + } | |
| 1719 | + } | |
| 1720 | + | |
| 1699 | 1721 | dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); |
| 1700 | 1722 | ret = cpsw_ale_del_vlan(priv->ale, vid, 0); |
| 1701 | 1723 | if (ret != 0) |
| @@ -377,9 +377,11 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) · 376 unmodified lines | ||
| 377 | 377 | }; |
| 378 | 378 | |
| 379 | 379 | dst = ip6_route_output(dev_net(dev), NULL, &fl6); |
| 380 | − if (IS_ERR(dst)) | |
| 380 | + if (dst->error) { | |
| 381 | + ret = dst->error; | |
| 382 | + dst_release(dst); | |
| 381 | 383 | goto err; |
| 382 | − | |
| 384 | + } | |
| 383 | 385 | skb_dst_drop(skb); |
| 384 | 386 | skb_dst_set(skb, dst); |
| 385 | 387 | err = ip6_local_out(skb); |
| @@ -285,6 +285,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | __ath_cancel_work(sc); |
| 287 | 287 | |
| 288 | + disable_irq(sc->irq); | |
| 288 | 289 | tasklet_disable(&sc->intr_tq); |
| 289 | 290 | tasklet_disable(&sc->bcon_tasklet); |
| 290 | 291 | spin_lock_bh(&sc->sc_pcu_lock); |
| @@ -331,6 +332,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) · 40 unmodified lines | ||
| 331 | 332 | r = -EIO; |
| 332 | 333 | |
| 333 | 334 | out: |
| 335 | + enable_irq(sc->irq); | |
| 334 | 336 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 335 | 337 | tasklet_enable(&sc->bcon_tasklet); |
| 336 | 338 | tasklet_enable(&sc->intr_tq); |
| @@ -512,9 +514,6 @@ irqreturn_t ath_isr(int irq, void *dev) · 175 unmodified lines | ||
| 512 | 514 | if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) |
| 513 | 515 | return IRQ_NONE; |
| 514 | 516 | |
| 515 | − if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | |
| 516 | − return IRQ_NONE; | |
| 517 | − | |
| 518 | 517 | /* shared irq, not for us */ |
| 519 | 518 | if (!ath9k_hw_intrpend(ah)) |
| 520 | 519 | return IRQ_NONE; |
| @@ -529,7 +528,7 @@ irqreturn_t ath_isr(int irq, void *dev) · 8 unmodified lines | ||
| 529 | 528 | ath9k_debug_sync_cause(sc, sync_cause); |
| 530 | 529 | status &= ah->imask; /* discard unasked-for bits */ |
| 531 | 530 | |
| 532 | − if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | |
| 531 | + if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) | |
| 533 | 532 | return IRQ_HANDLED; |
| 534 | 533 | |
| 535 | 534 | /* |
| @@ -246,6 +246,7 @@ enum iwl_ucode_tlv_flag { · 245 unmodified lines | ||
| 246 | 246 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, |
| 247 | 247 | * regardless of the band or the number of the probes. FW will calculate |
| 248 | 248 | * the actual dwell time. |
| 249 | + * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. | |
| 249 | 250 | */ |
| 250 | 251 | enum iwl_ucode_tlv_api { |
| 251 | 252 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), |
| @@ -257,6 +258,7 @@ enum iwl_ucode_tlv_api { · 5 unmodified lines | ||
| 257 | 258 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), |
| 258 | 259 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), |
| 259 | 260 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), |
| 261 | + IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), | |
| 260 | 262 | }; |
| 261 | 263 | |
| 262 | 264 | /** |
| @@ -653,8 +653,11 @@ enum iwl_scan_channel_flags { · 652 unmodified lines | ||
| 653 | 653 | }; |
| 654 | 654 | |
| 655 | 655 | /* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S |
| 656 | − * @flags: enum iwl_scan_channel_flgs | |
| 657 | − * @non_ebs_ratio: how many regular scan iteration before EBS | |
| 656 | + * @flags: enum iwl_scan_channel_flags | |
| 657 | + * @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is | |
| 658 | + * involved. | |
| 659 | + * 1 - EBS is disabled. | |
| 660 | + * 2 - every second scan will be full scan(and so on). | |
| 658 | 661 | */ |
| 659 | 662 | struct iwl_scan_channel_opt { |
| 660 | 663 | __le16 flags; |
| @@ -3343,18 +3343,16 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, · 3342 unmodified lines | ||
| 3343 | 3343 | msk |= mvmsta->tfd_queue_msk; |
| 3344 | 3344 | } |
| 3345 | 3345 | |
| 3346 | − if (drop) { | |
| 3347 | − if (iwl_mvm_flush_tx_path(mvm, msk, true)) | |
| 3348 | − IWL_ERR(mvm, "flush request fail\n"); | |
| 3349 | − mutex_unlock(&mvm->mutex); | |
| 3350 | − } else { | |
| 3351 | − mutex_unlock(&mvm->mutex); | |
| 3346 | + msk &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); | |
| 3352 | 3347 | |
| 3353 | − /* this can take a while, and we may need/want other operations | |
| 3354 | − * to succeed while doing this, so do it without the mutex held | |
| 3355 | − */ | |
| 3356 | − iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | |
| 3357 | − } | |
| 3348 | + if (iwl_mvm_flush_tx_path(mvm, msk, true)) | |
| 3349 | + IWL_ERR(mvm, "flush request fail\n"); | |
| 3350 | + mutex_unlock(&mvm->mutex); | |
| 3351 | + | |
| 3352 | + /* this can take a while, and we may need/want other operations | |
| 3353 | + * to succeed while doing this, so do it without the mutex held | |
| 3354 | + */ | |
| 3355 | + iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | |
| 3358 | 3356 | } |
| 3359 | 3357 | |
| 3360 | 3358 | const struct ieee80211_ops iwl_mvm_hw_ops = { |
| @@ -72,6 +72,8 @@ · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | #define IWL_PLCP_QUIET_THRESH 1 |
| 74 | 74 | #define IWL_ACTIVE_QUIET_TIME 10 |
| 75 | +#define IWL_DENSE_EBS_SCAN_RATIO 5 | |
| 76 | +#define IWL_SPARSE_EBS_SCAN_RATIO 1 | |
| 75 | 77 | |
| 76 | 78 | struct iwl_mvm_scan_params { |
| 77 | 79 | u32 max_out_time; |
| @@ -1105,6 +1107,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) · 1027 unmodified lines | ||
| 1105 | 1107 | return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, |
| 1106 | 1108 | notify); |
| 1107 | 1109 | |
| 1110 | + if (mvm->scan_status == IWL_MVM_SCAN_NONE) | |
| 1111 | + return 0; | |
| 1112 | + | |
| 1113 | + if (iwl_mvm_is_radio_killed(mvm)) | |
| 1114 | + goto out; | |
| 1115 | + | |
| 1108 | 1116 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && |
| 1109 | 1117 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || |
| 1110 | 1118 | mvm->scan_status != IWL_MVM_SCAN_OS)) { |
| @@ -1141,6 +1149,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) · 30 unmodified lines | ||
| 1141 | 1149 | if (mvm->scan_status == IWL_MVM_SCAN_OS) |
| 1142 | 1150 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); |
| 1143 | 1151 | |
| 1152 | +out: | |
| 1144 | 1153 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
| 1145 | 1154 | |
| 1146 | 1155 | if (notify) { |
| @@ -1297,18 +1306,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, · 150 unmodified lines | ||
| 1297 | 1306 | cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); |
| 1298 | 1307 | cmd->iter_num = cpu_to_le32(1); |
| 1299 | 1308 | |
| 1300 | − if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | |
| 1301 | − mvm->last_ebs_successful) { | |
| 1302 | − cmd->channel_opt[0].flags = | |
| 1303 | − cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
| 1304 | − IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
| 1305 | − IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
| 1306 | − cmd->channel_opt[1].flags = | |
| 1307 | − cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
| 1308 | − IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
| 1309 | − IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
| 1310 | − } | |
| 1311 | − | |
| 1312 | 1309 | if (iwl_mvm_rrm_scan_needed(mvm)) |
| 1313 | 1310 | cmd->scan_flags |= |
| 1314 | 1311 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); |
| @@ -1383,6 +1380,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, · 68 unmodified lines | ||
| 1383 | 1380 | cmd->schedule[1].iterations = 0; |
| 1384 | 1381 | cmd->schedule[1].full_scan_mul = 0; |
| 1385 | 1382 | |
| 1383 | + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && | |
| 1384 | + mvm->last_ebs_successful) { | |
| 1385 | + cmd->channel_opt[0].flags = | |
| 1386 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
| 1387 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
| 1388 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
| 1389 | + cmd->channel_opt[0].non_ebs_ratio = | |
| 1390 | + cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | |
| 1391 | + cmd->channel_opt[1].flags = | |
| 1392 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
| 1393 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
| 1394 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
| 1395 | + cmd->channel_opt[1].non_ebs_ratio = | |
| 1396 | + cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | |
| 1397 | + } | |
| 1398 | + | |
| 1386 | 1399 | for (i = 1; i <= req->req.n_ssids; i++) |
| 1387 | 1400 | ssid_bitmap |= BIT(i); |
| 1388 | 1401 | |
| @@ -1483,6 +1496,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, · 94 unmodified lines | ||
| 1483 | 1496 | cmd->schedule[1].iterations = 0xff; |
| 1484 | 1497 | cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; |
| 1485 | 1498 | |
| 1499 | + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | |
| 1500 | + mvm->last_ebs_successful) { | |
| 1501 | + cmd->channel_opt[0].flags = | |
| 1502 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
| 1503 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
| 1504 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
| 1505 | + cmd->channel_opt[0].non_ebs_ratio = | |
| 1506 | + cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | |
| 1507 | + cmd->channel_opt[1].flags = | |
| 1508 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
| 1509 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
| 1510 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
| 1511 | + cmd->channel_opt[1].non_ebs_ratio = | |
| 1512 | + cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | |
| 1513 | + } | |
| 1514 | + | |
| 1486 | 1515 | iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, |
| 1487 | 1516 | ssid_bitmap, cmd); |
| 1488 | 1517 | |
| @@ -90,8 +90,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | if (ieee80211_is_probe_resp(fc)) |
| 92 | 92 | tx_flags |= TX_CMD_FLG_TSF; |
| 93 | − else if (ieee80211_is_back_req(fc)) | |
| 94 | − tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | |
| 95 | 93 | |
| 96 | 94 | if (ieee80211_has_morefrags(fc)) |
| 97 | 95 | tx_flags |= TX_CMD_FLG_MORE_FRAG; |
| @@ -100,6 +98,15 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, · 2 unmodified lines | ||
| 100 | 98 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
| 101 | 99 | tx_cmd->tid_tspec = qc[0] & 0xf; |
| 102 | 100 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; |
| 101 | + } else if (ieee80211_is_back_req(fc)) { | |
| 102 | + struct ieee80211_bar *bar = (void *)skb->data; | |
| 103 | + u16 control = le16_to_cpu(bar->control); | |
| 104 | + | |
| 105 | + tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | |
| 106 | + tx_cmd->tid_tspec = (control & | |
| 107 | + IEEE80211_BAR_CTRL_TID_INFO_MASK) >> | |
| 108 | + IEEE80211_BAR_CTRL_TID_INFO_SHIFT; | |
| 109 | + WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT); | |
| 103 | 110 | } else { |
| 104 | 111 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; |
| 105 | 112 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
| @@ -177,7 +177,7 @@ struct at91_pinctrl { · 176 unmodified lines | ||
| 177 | 177 | struct device *dev; |
| 178 | 178 | struct pinctrl_dev *pctl; |
| 179 | 179 | |
| 180 | − int nbanks; | |
| 180 | + int nactive_banks; | |
| 181 | 181 | |
| 182 | 182 | uint32_t *mux_mask; |
| 183 | 183 | int nmux; |
| @@ -653,12 +653,18 @@ static int pin_check_config(struct at91_pinctrl *info, const char *name, · 469 unmodified lines | ||
| 653 | 653 | int mux; |
| 654 | 654 | |
| 655 | 655 | /* check if it's a valid config */ |
| 656 | − if (pin->bank >= info->nbanks) { | |
| 656 | + if (pin->bank >= gpio_banks) { | |
| 657 | 657 | dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n", |
| 658 | − name, index, pin->bank, info->nbanks); | |
| 658 | + name, index, pin->bank, gpio_banks); | |
| 659 | 659 | return -EINVAL; |
| 660 | 660 | } |
| 661 | 661 | |
| 662 | + if (!gpio_chips[pin->bank]) { | |
| 663 | + dev_err(info->dev, "%s: pin conf %d bank_id %d not enabled\n", | |
| 664 | + name, index, pin->bank); | |
| 665 | + return -ENXIO; | |
| 666 | + } | |
| 667 | + | |
| 662 | 668 | if (pin->pin >= MAX_NB_GPIO_PER_BANK) { |
| 663 | 669 | dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n", |
| 664 | 670 | name, index, pin->pin, MAX_NB_GPIO_PER_BANK); |
| @@ -981,7 +987,8 @@ static void at91_pinctrl_child_count(struct at91_pinctrl *info, · 316 unmodified lines | ||
| 981 | 987 | |
| 982 | 988 | for_each_child_of_node(np, child) { |
| 983 | 989 | if (of_device_is_compatible(child, gpio_compat)) { |
| 984 | − info->nbanks++; | |
| 990 | + if (of_device_is_available(child)) | |
| 991 | + info->nactive_banks++; | |
| 985 | 992 | } else { |
| 986 | 993 | info->nfunctions++; |
| 987 | 994 | info->ngroups += of_get_child_count(child); |
| @@ -1003,11 +1010,11 @@ static int at91_pinctrl_mux_mask(struct at91_pinctrl *info, · 15 unmodified lines | ||
| 1003 | 1010 | } |
| 1004 | 1011 | |
| 1005 | 1012 | size /= sizeof(*list); |
| 1006 | − if (!size || size % info->nbanks) { | |
| 1007 | − dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks); | |
| 1013 | + if (!size || size % gpio_banks) { | |
| 1014 | + dev_err(info->dev, "wrong mux mask array should be by %d\n", gpio_banks); | |
| 1008 | 1015 | return -EINVAL; |
| 1009 | 1016 | } |
| 1010 | − info->nmux = size / info->nbanks; | |
| 1017 | + info->nmux = size / gpio_banks; | |
| 1011 | 1018 | |
| 1012 | 1019 | info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); |
| 1013 | 1020 | if (!info->mux_mask) { |
| @@ -1131,7 +1138,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, · 117 unmodified lines | ||
| 1131 | 1138 | of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; |
| 1132 | 1139 | at91_pinctrl_child_count(info, np); |
| 1133 | 1140 | |
| 1134 | − if (info->nbanks < 1) { | |
| 1141 | + if (gpio_banks < 1) { | |
| 1135 | 1142 | dev_err(&pdev->dev, "you need to specify at least one gpio-controller\n"); |
| 1136 | 1143 | return -EINVAL; |
| 1137 | 1144 | } |
| @@ -1144,7 +1151,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, · 6 unmodified lines | ||
| 1144 | 1151 | |
| 1145 | 1152 | dev_dbg(&pdev->dev, "mux-mask\n"); |
| 1146 | 1153 | tmp = info->mux_mask; |
| 1147 | − for (i = 0; i < info->nbanks; i++) { | |
| 1154 | + for (i = 0; i < gpio_banks; i++) { | |
| 1148 | 1155 | for (j = 0; j < info->nmux; j++, tmp++) { |
| 1149 | 1156 | dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); |
| 1150 | 1157 | } |
| @@ -1162,7 +1169,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, · 11 unmodified lines | ||
| 1162 | 1169 | if (!info->groups) |
| 1163 | 1170 | return -ENOMEM; |
| 1164 | 1171 | |
| 1165 | − dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks); | |
| 1172 | + dev_dbg(&pdev->dev, "nbanks = %d\n", gpio_banks); | |
| 1166 | 1173 | dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); |
| 1167 | 1174 | dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); |
| 1168 | 1175 | |
| @@ -1185,7 +1192,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev) · 16 unmodified lines | ||
| 1185 | 1192 | { |
| 1186 | 1193 | struct at91_pinctrl *info; |
| 1187 | 1194 | struct pinctrl_pin_desc *pdesc; |
| 1188 | − int ret, i, j, k; | |
| 1195 | + int ret, i, j, k, ngpio_chips_enabled = 0; | |
| 1189 | 1196 | |
| 1190 | 1197 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
| 1191 | 1198 | if (!info) |
| @@ -1200,23 +1207,27 @@ static int at91_pinctrl_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 1200 | 1207 | * to obtain references to the struct gpio_chip * for them, and we |
| 1201 | 1208 | * need this to proceed. |
| 1202 | 1209 | */ |
| 1203 | − for (i = 0; i < info->nbanks; i++) { | |
| 1204 | − if (!gpio_chips[i]) { | |
| 1205 | − dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); | |
| 1206 | − devm_kfree(&pdev->dev, info); | |
| 1207 | − return -EPROBE_DEFER; | |
| 1208 | − } | |
| 1210 | + for (i = 0; i < gpio_banks; i++) | |
| 1211 | + if (gpio_chips[i]) | |
| 1212 | + ngpio_chips_enabled++; | |
| 1213 | + | |
| 1214 | + if (ngpio_chips_enabled < info->nactive_banks) { | |
| 1215 | + dev_warn(&pdev->dev, | |
| 1216 | + "All GPIO chips are not registered yet (%d/%d)\n", | |
| 1217 | + ngpio_chips_enabled, info->nactive_banks); | |
| 1218 | + devm_kfree(&pdev->dev, info); | |
| 1219 | + return -EPROBE_DEFER; | |
| 1209 | 1220 | } |
| 1210 | 1221 | |
| 1211 | 1222 | at91_pinctrl_desc.name = dev_name(&pdev->dev); |
| 1212 | − at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK; | |
| 1223 | + at91_pinctrl_desc.npins = gpio_banks * MAX_NB_GPIO_PER_BANK; | |
| 1213 | 1224 | at91_pinctrl_desc.pins = pdesc = |
| 1214 | 1225 | devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); |
| 1215 | 1226 | |
| 1216 | 1227 | if (!at91_pinctrl_desc.pins) |
| 1217 | 1228 | return -ENOMEM; |
| 1218 | 1229 | |
| 1219 | − for (i = 0 , k = 0; i < info->nbanks; i++) { | |
| 1230 | + for (i = 0, k = 0; i < gpio_banks; i++) { | |
| 1220 | 1231 | for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { |
| 1221 | 1232 | pdesc->number = k; |
| 1222 | 1233 | pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); |
| @@ -1234,8 +1245,9 @@ static int at91_pinctrl_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 1234 | 1245 | } |
| 1235 | 1246 | |
| 1236 | 1247 | /* We will handle a range of GPIO pins */ |
| 1237 | − for (i = 0; i < info->nbanks; i++) | |
| 1238 | − pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); | |
| 1248 | + for (i = 0; i < gpio_banks; i++) | |
| 1249 | + if (gpio_chips[i]) | |
| 1250 | + pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); | |
| 1239 | 1251 | |
| 1240 | 1252 | dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); |
| 1241 | 1253 | |
| @@ -1613,9 +1625,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) · 371 unmodified lines | ||
| 1613 | 1625 | static int at91_gpio_of_irq_setup(struct platform_device *pdev, |
| 1614 | 1626 | struct at91_gpio_chip *at91_gpio) |
| 1615 | 1627 | { |
| 1628 | + struct gpio_chip *gpiochip_prev = NULL; | |
| 1616 | 1629 | struct at91_gpio_chip *prev = NULL; |
| 1617 | 1630 | struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); |
| 1618 | − int ret; | |
| 1631 | + int ret, i; | |
| 1619 | 1632 | |
| 1620 | 1633 | at91_gpio->pioc_hwirq = irqd_to_hwirq(d); |
| 1621 | 1634 | |
| @@ -1641,24 +1654,33 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev, · 19 unmodified lines | ||
| 1641 | 1654 | return ret; |
| 1642 | 1655 | } |
| 1643 | 1656 | |
| 1644 | − /* Setup chained handler */ | |
| 1645 | − if (at91_gpio->pioc_idx) | |
| 1646 | − prev = gpio_chips[at91_gpio->pioc_idx - 1]; | |
| 1647 | − | |
| 1648 | 1657 | /* The top level handler handles one bank of GPIOs, except |
| 1649 | 1658 | * on some SoC it can handle up to three... |
| 1650 | 1659 | * We only set up the handler for the first of the list. |
| 1651 | 1660 | */ |
| 1652 | − if (prev && prev->next == at91_gpio) | |
| 1661 | + gpiochip_prev = irq_get_handler_data(at91_gpio->pioc_virq); | |
| 1662 | + if (!gpiochip_prev) { | |
| 1663 | + /* Then register the chain on the parent IRQ */ | |
| 1664 | + gpiochip_set_chained_irqchip(&at91_gpio->chip, | |
| 1665 | + &gpio_irqchip, | |
| 1666 | + at91_gpio->pioc_virq, | |
| 1667 | + gpio_irq_handler); | |
| 1653 | 1668 | return 0; |
| 1669 | + } | |
| 1654 | 1670 | |
| 1655 | − /* Then register the chain on the parent IRQ */ | |
| 1656 | − gpiochip_set_chained_irqchip(&at91_gpio->chip, | |
| 1657 | − &gpio_irqchip, | |
| 1658 | − at91_gpio->pioc_virq, | |
| 1659 | − gpio_irq_handler); | |
| 1671 | + prev = container_of(gpiochip_prev, struct at91_gpio_chip, chip); | |
| 1660 | 1672 | |
| 1661 | − return 0; | |
| 1673 | + /* we can only have 2 banks before */ | |
| 1674 | + for (i = 0; i < 2; i++) { | |
| 1675 | + if (prev->next) { | |
| 1676 | + prev = prev->next; | |
| 1677 | + } else { | |
| 1678 | + prev->next = at91_gpio; | |
| 1679 | + return 0; | |
| 1680 | + } | |
| 1681 | + } | |
| 1682 | + | |
| 1683 | + return -EINVAL; | |
| 1662 | 1684 | } |
| 1663 | 1685 | |
| 1664 | 1686 | /* This structure is replicated for each GPIO block allocated at probe time */ |
| @@ -1675,24 +1697,6 @@ static struct gpio_chip at91_gpio_template = { · 10 unmodified lines | ||
| 1675 | 1697 | .ngpio = MAX_NB_GPIO_PER_BANK, |
| 1676 | 1698 | }; |
| 1677 | 1699 | |
| 1678 | −static void at91_gpio_probe_fixup(void) | |
| 1679 | −{ | |
| 1680 | − unsigned i; | |
| 1681 | − struct at91_gpio_chip *at91_gpio, *last = NULL; | |
| 1682 | − | |
| 1683 | − for (i = 0; i < gpio_banks; i++) { | |
| 1684 | − at91_gpio = gpio_chips[i]; | |
| 1685 | − | |
| 1686 | − /* | |
| 1687 | − * GPIO controller are grouped on some SoC: | |
| 1688 | − * PIOC, PIOD and PIOE can share the same IRQ line | |
| 1689 | − */ | |
| 1690 | − if (last && last->pioc_virq == at91_gpio->pioc_virq) | |
| 1691 | − last->next = at91_gpio; | |
| 1692 | − last = at91_gpio; | |
| 1693 | − } | |
| 1694 | −} | |
| 1695 | − | |
| 1696 | 1700 | static struct of_device_id at91_gpio_of_match[] = { |
| 1697 | 1701 | { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, |
| 1698 | 1702 | { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, |
| @@ -1805,8 +1809,6 @@ static int at91_gpio_probe(struct platform_device *pdev) · 106 unmodified lines | ||
| 1805 | 1809 | gpio_chips[alias_idx] = at91_chip; |
| 1806 | 1810 | gpio_banks = max(gpio_banks, alias_idx + 1); |
| 1807 | 1811 | |
| 1808 | − at91_gpio_probe_fixup(); | |
| 1809 | − | |
| 1810 | 1812 | ret = at91_gpio_of_irq_setup(pdev, at91_chip); |
| 1811 | 1813 | if (ret) |
| 1812 | 1814 | goto irq_setup_err; |
| @@ -1488,7 +1488,7 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id) · 1487 unmodified lines | ||
| 1488 | 1488 | } |
| 1489 | 1489 | EXPORT_SYMBOL_GPL(regulator_get_optional); |
| 1490 | 1490 | |
| 1491 | −/* Locks held by regulator_put() */ | |
| 1491 | +/* regulator_list_mutex lock held by regulator_put() */ | |
| 1492 | 1492 | static void _regulator_put(struct regulator *regulator) |
| 1493 | 1493 | { |
| 1494 | 1494 | struct regulator_dev *rdev; |
| @@ -1503,12 +1503,14 @@ static void _regulator_put(struct regulator *regulator) · 8 unmodified lines | ||
| 1503 | 1503 | /* remove any sysfs entries */ |
| 1504 | 1504 | if (regulator->dev) |
| 1505 | 1505 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); |
| 1506 | + mutex_lock(&rdev->mutex); | |
| 1506 | 1507 | kfree(regulator->supply_name); |
| 1507 | 1508 | list_del(®ulator->list); |
| 1508 | 1509 | kfree(regulator); |
| 1509 | 1510 | |
| 1510 | 1511 | rdev->open_count--; |
| 1511 | 1512 | rdev->exclusive = 0; |
| 1513 | + mutex_unlock(&rdev->mutex); | |
| 1512 | 1514 | |
| 1513 | 1515 | module_put(rdev->owner); |
| 1514 | 1516 | } |
| @@ -405,6 +405,40 @@ static struct regulator_ops s2mps14_reg_ops; · 404 unmodified lines | ||
| 405 | 405 | .enable_mask = S2MPS14_ENABLE_MASK \ |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | +#define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \ | |
| 409 | + .name = "BUCK"#num, \ | |
| 410 | + .id = S2MPS13_BUCK##num, \ | |
| 411 | + .ops = &s2mps14_reg_ops, \ | |
| 412 | + .type = REGULATOR_VOLTAGE, \ | |
| 413 | + .owner = THIS_MODULE, \ | |
| 414 | + .min_uV = min, \ | |
| 415 | + .uV_step = step, \ | |
| 416 | + .linear_min_sel = min_sel, \ | |
| 417 | + .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | |
| 418 | + .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ | |
| 419 | + .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ | |
| 420 | + .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | |
| 421 | + .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \ | |
| 422 | + .enable_mask = S2MPS14_ENABLE_MASK \ | |
| 423 | +} | |
| 424 | + | |
| 425 | +#define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \ | |
| 426 | + .name = "BUCK"#num, \ | |
| 427 | + .id = S2MPS13_BUCK##num, \ | |
| 428 | + .ops = &s2mps14_reg_ops, \ | |
| 429 | + .type = REGULATOR_VOLTAGE, \ | |
| 430 | + .owner = THIS_MODULE, \ | |
| 431 | + .min_uV = min, \ | |
| 432 | + .uV_step = step, \ | |
| 433 | + .linear_min_sel = min_sel, \ | |
| 434 | + .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | |
| 435 | + .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ | |
| 436 | + .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ | |
| 437 | + .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | |
| 438 | + .enable_reg = S2MPS13_REG_B1CTRL + (num) * 2 - 1, \ | |
| 439 | + .enable_mask = S2MPS14_ENABLE_MASK \ | |
| 440 | +} | |
| 441 | + | |
| 408 | 442 | static const struct regulator_desc s2mps13_regulators[] = { |
| 409 | 443 | regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00), |
| 410 | 444 | regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C), |
| @@ -452,10 +486,10 @@ static const struct regulator_desc s2mps13_regulators[] = { · 41 unmodified lines | ||
| 452 | 486 | regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10), |
| 453 | 487 | regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10), |
| 454 | 488 | regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10), |
| 455 | − regulator_desc_s2mps13_buck(7, MIN_500_MV, STEP_6_25_MV, 0x10), | |
| 456 | − regulator_desc_s2mps13_buck(8, MIN_1000_MV, STEP_12_5_MV, 0x20), | |
| 457 | − regulator_desc_s2mps13_buck(9, MIN_1000_MV, STEP_12_5_MV, 0x20), | |
| 458 | − regulator_desc_s2mps13_buck(10, MIN_500_MV, STEP_6_25_MV, 0x10), | |
| 489 | + regulator_desc_s2mps13_buck7(7, MIN_500_MV, STEP_6_25_MV, 0x10), | |
| 490 | + regulator_desc_s2mps13_buck8_10(8, MIN_1000_MV, STEP_12_5_MV, 0x20), | |
| 491 | + regulator_desc_s2mps13_buck8_10(9, MIN_1000_MV, STEP_12_5_MV, 0x20), | |
| 492 | + regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10), | |
| 459 | 493 | }; |
| 460 | 494 | |
| 461 | 495 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) |
| @@ -832,6 +832,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); · 831 unmodified lines | ||
| 832 | 832 | static const struct platform_device_id s5m_rtc_id[] = { |
| 833 | 833 | { "s5m-rtc", S5M8767X }, |
| 834 | 834 | { "s2mps14-rtc", S2MPS14X }, |
| 835 | + { }, | |
| 835 | 836 | }; |
| 836 | 837 | |
| 837 | 838 | static struct platform_driver s5m_rtc_driver = { |
| @@ -1784,6 +1784,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, · 1783 unmodified lines | ||
| 1784 | 1784 | QETH_DBF_TEXT(SETUP, 2, "idxanswr"); |
| 1785 | 1785 | card = CARD_FROM_CDEV(channel->ccwdev); |
| 1786 | 1786 | iob = qeth_get_buffer(channel); |
| 1787 | + if (!iob) | |
| 1788 | + return -ENOMEM; | |
| 1787 | 1789 | iob->callback = idx_reply_cb; |
| 1788 | 1790 | memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1)); |
| 1789 | 1791 | channel->ccw.count = QETH_BUFSIZE; |
| @@ -1834,6 +1836,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, · 44 unmodified lines | ||
| 1834 | 1836 | QETH_DBF_TEXT(SETUP, 2, "idxactch"); |
| 1835 | 1837 | |
| 1836 | 1838 | iob = qeth_get_buffer(channel); |
| 1839 | + if (!iob) | |
| 1840 | + return -ENOMEM; | |
| 1837 | 1841 | iob->callback = idx_reply_cb; |
| 1838 | 1842 | memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1)); |
| 1839 | 1843 | channel->ccw.count = IDX_ACTIVATE_SIZE; |
| @@ -2021,10 +2025,36 @@ void qeth_prepare_control_data(struct qeth_card *card, int len, · 181 unmodified lines | ||
| 2021 | 2025 | } |
| 2022 | 2026 | EXPORT_SYMBOL_GPL(qeth_prepare_control_data); |
| 2023 | 2027 | |
| 2028 | +/** | |
| 2029 | + * qeth_send_control_data() - send control command to the card | |
| 2030 | + * @card: qeth_card structure pointer | |
| 2031 | + * @len: size of the command buffer | |
| 2032 | + * @iob: qeth_cmd_buffer pointer | |
| 2033 | + * @reply_cb: callback function pointer | |
| 2034 | + * @cb_card: pointer to the qeth_card structure | |
| 2035 | + * @cb_reply: pointer to the qeth_reply structure | |
| 2036 | + * @cb_cmd: pointer to the original iob for non-IPA | |
| 2037 | + * commands, or to the qeth_ipa_cmd structure | |
| 2038 | + * for the IPA commands. | |
| 2039 | + * @reply_param: private pointer passed to the callback | |
| 2040 | + * | |
| 2041 | + * Returns the value of the `return_code' field of the response | |
| 2042 | + * block returned from the hardware, or other error indication. | |
| 2043 | + * Value of zero indicates successful execution of the command. | |
| 2044 | + * | |
| 2045 | + * Callback function gets called one or more times, with cb_cmd | |
| 2046 | + * pointing to the response returned by the hardware. Callback | |
| 2047 | + * function must return non-zero if more reply blocks are expected, | |
| 2048 | + * and zero if the last or only reply block is received. Callback | |
| 2049 | + * function can get the value of the reply_param pointer from the | |
| 2050 | + * field 'param' of the structure qeth_reply. | |
| 2051 | + */ | |
| 2052 | + | |
| 2024 | 2053 | int qeth_send_control_data(struct qeth_card *card, int len, |
| 2025 | 2054 | struct qeth_cmd_buffer *iob, |
| 2026 | − int (*reply_cb)(struct qeth_card *, struct qeth_reply *, | |
| 2027 | − unsigned long), | |
| 2055 | + int (*reply_cb)(struct qeth_card *cb_card, | |
| 2056 | + struct qeth_reply *cb_reply, | |
| 2057 | + unsigned long cb_cmd), | |
| 2028 | 2058 | void *reply_param) |
| 2029 | 2059 | { |
| 2030 | 2060 | int rc; |
| @@ -2914,9 +2944,16 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, · 883 unmodified lines | ||
| 2914 | 2944 | struct qeth_cmd_buffer *iob; |
| 2915 | 2945 | struct qeth_ipa_cmd *cmd; |
| 2916 | 2946 | |
| 2917 | − iob = qeth_wait_for_buffer(&card->write); | |
| 2918 | − cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | |
| 2919 | − qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); | |
| 2947 | + iob = qeth_get_buffer(&card->write); | |
| 2948 | + if (iob) { | |
| 2949 | + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | |
| 2950 | + qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); | |
| 2951 | + } else { | |
| 2952 | + dev_warn(&card->gdev->dev, | |
| 2953 | + "The qeth driver ran out of channel command buffers\n"); | |
| 2954 | + QETH_DBF_MESSAGE(1, "%s The qeth driver ran out of channel command buffers", | |
| 2955 | + dev_name(&card->gdev->dev)); | |
| 2956 | + } | |
| 2920 | 2957 | |
| 2921 | 2958 | return iob; |
| 2922 | 2959 | } |
| @@ -2932,6 +2969,12 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, · 9 unmodified lines | ||
| 2932 | 2969 | } |
| 2933 | 2970 | EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); |
| 2934 | 2971 | |
| 2972 | +/** | |
| 2973 | + * qeth_send_ipa_cmd() - send an IPA command | |
| 2974 | + * | |
| 2975 | + * See qeth_send_control_data() for explanation of the arguments. | |
| 2976 | + */ | |
| 2977 | + | |
| 2935 | 2978 | int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, |
| 2936 | 2979 | int (*reply_cb)(struct qeth_card *, struct qeth_reply*, |
| 2937 | 2980 | unsigned long), |
| @@ -2968,6 +3011,8 @@ int qeth_send_startlan(struct qeth_card *card) · 30 unmodified lines | ||
| 2968 | 3011 | QETH_DBF_TEXT(SETUP, 2, "strtlan"); |
| 2969 | 3012 | |
| 2970 | 3013 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); |
| 3014 | + if (!iob) | |
| 3015 | + return -ENOMEM; | |
| 2971 | 3016 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); |
| 2972 | 3017 | return rc; |
| 2973 | 3018 | } |
| @@ -3013,11 +3058,13 @@ static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, · 39 unmodified lines | ||
| 3013 | 3058 | |
| 3014 | 3059 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, |
| 3015 | 3060 | QETH_PROT_IPV4); |
| 3016 | − cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | |
| 3017 | − cmd->data.setadapterparms.hdr.cmdlength = cmdlen; | |
| 3018 | − cmd->data.setadapterparms.hdr.command_code = command; | |
| 3019 | − cmd->data.setadapterparms.hdr.used_total = 1; | |
| 3020 | − cmd->data.setadapterparms.hdr.seq_no = 1; | |
| 3061 | + if (iob) { | |
| 3062 | + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | |
| 3063 | + cmd->data.setadapterparms.hdr.cmdlength = cmdlen; | |
| 3064 | + cmd->data.setadapterparms.hdr.command_code = command; | |
| 3065 | + cmd->data.setadapterparms.hdr.used_total = 1; | |
| 3066 | + cmd->data.setadapterparms.hdr.seq_no = 1; | |
| 3067 | + } | |
| 3021 | 3068 | |
| 3022 | 3069 | return iob; |
| 3023 | 3070 | } |
| @@ -3030,6 +3077,8 @@ int qeth_query_setadapterparms(struct qeth_card *card) · 6 unmodified lines | ||
| 3030 | 3077 | QETH_CARD_TEXT(card, 3, "queryadp"); |
| 3031 | 3078 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, |
| 3032 | 3079 | sizeof(struct qeth_ipacmd_setadpparms)); |
| 3080 | + if (!iob) | |
| 3081 | + return -ENOMEM; | |
| 3033 | 3082 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); |
| 3034 | 3083 | return rc; |
| 3035 | 3084 | } |
| @@ -3080,6 +3129,8 @@ int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot) · 44 unmodified lines | ||
| 3080 | 3129 | |
| 3081 | 3130 | QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); |
| 3082 | 3131 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); |
| 3132 | + if (!iob) | |
| 3133 | + return -ENOMEM; | |
| 3083 | 3134 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); |
| 3084 | 3135 | return rc; |
| 3085 | 3136 | } |
| @@ -3119,6 +3170,8 @@ int qeth_query_switch_attributes(struct qeth_card *card, · 33 unmodified lines | ||
| 3119 | 3170 | return -ENOMEDIUM; |
| 3120 | 3171 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, |
| 3121 | 3172 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); |
| 3173 | + if (!iob) | |
| 3174 | + return -ENOMEM; | |
| 3122 | 3175 | return qeth_send_ipa_cmd(card, iob, |
| 3123 | 3176 | qeth_query_switch_attributes_cb, sw_info); |
| 3124 | 3177 | } |
| @@ -3146,6 +3199,8 @@ static int qeth_query_setdiagass(struct qeth_card *card) · 21 unmodified lines | ||
| 3146 | 3199 | |
| 3147 | 3200 | QETH_DBF_TEXT(SETUP, 2, "qdiagass"); |
| 3148 | 3201 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
| 3202 | + if (!iob) | |
| 3203 | + return -ENOMEM; | |
| 3149 | 3204 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 3150 | 3205 | cmd->data.diagass.subcmd_len = 16; |
| 3151 | 3206 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; |
| @@ -3197,6 +3252,8 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) · 45 unmodified lines | ||
| 3197 | 3252 | |
| 3198 | 3253 | QETH_DBF_TEXT(SETUP, 2, "diagtrap"); |
| 3199 | 3254 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
| 3255 | + if (!iob) | |
| 3256 | + return -ENOMEM; | |
| 3200 | 3257 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 3201 | 3258 | cmd->data.diagass.subcmd_len = 80; |
| 3202 | 3259 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; |
| @@ -4162,6 +4219,8 @@ void qeth_setadp_promisc_mode(struct qeth_card *card) · 959 unmodified lines | ||
| 4162 | 4219 | |
| 4163 | 4220 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, |
| 4164 | 4221 | sizeof(struct qeth_ipacmd_setadpparms)); |
| 4222 | + if (!iob) | |
| 4223 | + return; | |
| 4165 | 4224 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); |
| 4166 | 4225 | cmd->data.setadapterparms.data.mode = mode; |
| 4167 | 4226 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); |
| @@ -4232,6 +4291,8 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) · 64 unmodified lines | ||
| 4232 | 4291 | |
| 4233 | 4292 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, |
| 4234 | 4293 | sizeof(struct qeth_ipacmd_setadpparms)); |
| 4294 | + if (!iob) | |
| 4295 | + return -ENOMEM; | |
| 4235 | 4296 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4236 | 4297 | cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; |
| 4237 | 4298 | cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; |
| @@ -4345,6 +4406,8 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, · 107 unmodified lines | ||
| 4345 | 4406 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, |
| 4346 | 4407 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + |
| 4347 | 4408 | sizeof(struct qeth_set_access_ctrl)); |
| 4409 | + if (!iob) | |
| 4410 | + return -ENOMEM; | |
| 4348 | 4411 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4349 | 4412 | access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; |
| 4350 | 4413 | access_ctrl_req->subcmd_code = isolation; |
| @@ -4588,6 +4651,10 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) · 237 unmodified lines | ||
| 4588 | 4651 | |
| 4589 | 4652 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, |
| 4590 | 4653 | QETH_SNMP_SETADP_CMDLENGTH + req_len); |
| 4654 | + if (!iob) { | |
| 4655 | + rc = -ENOMEM; | |
| 4656 | + goto out; | |
| 4657 | + } | |
| 4591 | 4658 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4592 | 4659 | memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); |
| 4593 | 4660 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, |
| @@ -4599,7 +4666,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) · 5 unmodified lines | ||
| 4599 | 4666 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) |
| 4600 | 4667 | rc = -EFAULT; |
| 4601 | 4668 | } |
| 4602 | − | |
| 4669 | +out: | |
| 4603 | 4670 | kfree(ureq); |
| 4604 | 4671 | kfree(qinfo.udata); |
| 4605 | 4672 | return rc; |
| @@ -4670,6 +4737,10 @@ int qeth_query_oat_command(struct qeth_card *card, char __user *udata) · 64 unmodified lines | ||
| 4670 | 4737 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, |
| 4671 | 4738 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + |
| 4672 | 4739 | sizeof(struct qeth_query_oat)); |
| 4740 | + if (!iob) { | |
| 4741 | + rc = -ENOMEM; | |
| 4742 | + goto out_free; | |
| 4743 | + } | |
| 4673 | 4744 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4674 | 4745 | oat_req = &cmd->data.setadapterparms.data.query_oat; |
| 4675 | 4746 | oat_req->subcmd_code = oat_data.command; |
| @@ -4735,6 +4806,8 @@ static int qeth_query_card_info(struct qeth_card *card, · 59 unmodified lines | ||
| 4735 | 4806 | return -EOPNOTSUPP; |
| 4736 | 4807 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, |
| 4737 | 4808 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); |
| 4809 | + if (!iob) | |
| 4810 | + return -ENOMEM; | |
| 4738 | 4811 | return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, |
| 4739 | 4812 | (void *)carrier_info); |
| 4740 | 4813 | } |
| @@ -5060,11 +5133,23 @@ retriable: · 319 unmodified lines | ||
| 5060 | 5133 | card->options.adp.supported_funcs = 0; |
| 5061 | 5134 | card->options.sbp.supported_funcs = 0; |
| 5062 | 5135 | card->info.diagass_support = 0; |
| 5063 | − qeth_query_ipassists(card, QETH_PROT_IPV4); | |
| 5064 | − if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) | |
| 5065 | − qeth_query_setadapterparms(card); | |
| 5066 | − if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) | |
| 5067 | − qeth_query_setdiagass(card); | |
| 5136 | + rc = qeth_query_ipassists(card, QETH_PROT_IPV4); | |
| 5137 | + if (rc == -ENOMEM) | |
| 5138 | + goto out; | |
| 5139 | + if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { | |
| 5140 | + rc = qeth_query_setadapterparms(card); | |
| 5141 | + if (rc < 0) { | |
| 5142 | + QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); | |
| 5143 | + goto out; | |
| 5144 | + } | |
| 5145 | + } | |
| 5146 | + if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { | |
| 5147 | + rc = qeth_query_setdiagass(card); | |
| 5148 | + if (rc < 0) { | |
| 5149 | + QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc); | |
| 5150 | + goto out; | |
| 5151 | + } | |
| 5152 | + } | |
| 5068 | 5153 | return 0; |
| 5069 | 5154 | out: |
| 5070 | 5155 | dev_warn(&card->gdev->dev, "The qeth device driver failed to recover " |
| @@ -27,10 +27,7 @@ static int qeth_l2_set_offline(struct ccwgroup_device *); · 26 unmodified lines | ||
| 27 | 27 | static int qeth_l2_stop(struct net_device *); |
| 28 | 28 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); |
| 29 | 29 | static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, |
| 30 | − enum qeth_ipa_cmds, | |
| 31 | − int (*reply_cb) (struct qeth_card *, | |
| 32 | − struct qeth_reply*, | |
| 33 | − unsigned long)); | |
| 30 | + enum qeth_ipa_cmds); | |
| 34 | 31 | static void qeth_l2_set_multicast_list(struct net_device *); |
| 35 | 32 | static int qeth_l2_recover(void *); |
| 36 | 33 | static void qeth_bridgeport_query_support(struct qeth_card *card); |
| @@ -130,56 +127,71 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no) · 93 unmodified lines | ||
| 130 | 127 | return ndev; |
| 131 | 128 | } |
| 132 | 129 | |
| 133 | −static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, | |
| 134 | − struct qeth_reply *reply, | |
| 135 | − unsigned long data) | |
| 130 | +static int qeth_setdel_makerc(struct qeth_card *card, int retcode) | |
| 136 | 131 | { |
| 137 | − struct qeth_ipa_cmd *cmd; | |
| 138 | − __u8 *mac; | |
| 132 | + int rc; | |
| 139 | 133 | |
| 140 | − QETH_CARD_TEXT(card, 2, "L2Sgmacb"); | |
| 141 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 142 | − mac = &cmd->data.setdelmac.mac[0]; | |
| 143 | − /* MAC already registered, needed in couple/uncouple case */ | |
| 144 | − if (cmd->hdr.return_code == IPA_RC_L2_DUP_MAC) { | |
| 145 | − QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n", | |
| 146 | − mac, QETH_CARD_IFNAME(card)); | |
| 147 | − cmd->hdr.return_code = 0; | |
| 134 | + if (retcode) | |
| 135 | + QETH_CARD_TEXT_(card, 2, "err%04x", retcode); | |
| 136 | + switch (retcode) { | |
| 137 | + case IPA_RC_SUCCESS: | |
| 138 | + rc = 0; | |
| 139 | + break; | |
| 140 | + case IPA_RC_L2_UNSUPPORTED_CMD: | |
| 141 | + rc = -ENOSYS; | |
| 142 | + break; | |
| 143 | + case IPA_RC_L2_ADDR_TABLE_FULL: | |
| 144 | + rc = -ENOSPC; | |
| 145 | + break; | |
| 146 | + case IPA_RC_L2_DUP_MAC: | |
| 147 | + case IPA_RC_L2_DUP_LAYER3_MAC: | |
| 148 | + rc = -EEXIST; | |
| 149 | + break; | |
| 150 | + case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | |
| 151 | + case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | |
| 152 | + rc = -EPERM; | |
| 153 | + break; | |
| 154 | + case IPA_RC_L2_MAC_NOT_FOUND: | |
| 155 | + rc = -ENOENT; | |
| 156 | + break; | |
| 157 | + case -ENOMEM: | |
| 158 | + rc = -ENOMEM; | |
| 159 | + break; | |
| 160 | + default: | |
| 161 | + rc = -EIO; | |
| 162 | + break; | |
| 148 | 163 | } |
| 149 | − if (cmd->hdr.return_code) | |
| 150 | − QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n", | |
| 151 | − mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); | |
| 152 | − return 0; | |
| 164 | + return rc; | |
| 153 | 165 | } |
| 154 | 166 | |
| 155 | 167 | static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) |
| 156 | 168 | { |
| 157 | − QETH_CARD_TEXT(card, 2, "L2Sgmac"); | |
| 158 | − return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC, | |
| 159 | − qeth_l2_send_setgroupmac_cb); | |
| 160 | −} | |
| 161 | − | |
| 162 | −static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card, | |
| 163 | − struct qeth_reply *reply, | |
| 164 | − unsigned long data) | |
| 165 | −{ | |
| 166 | − struct qeth_ipa_cmd *cmd; | |
| 167 | − __u8 *mac; | |
| 169 | + int rc; | |
| 168 | 170 | |
| 169 | − QETH_CARD_TEXT(card, 2, "L2Dgmacb"); | |
| 170 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 171 | − mac = &cmd->data.setdelmac.mac[0]; | |
| 172 | − if (cmd->hdr.return_code) | |
| 173 | − QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n", | |
| 174 | − mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); | |
| 175 | − return 0; | |
| 171 | + QETH_CARD_TEXT(card, 2, "L2Sgmac"); | |
| 172 | + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, | |
| 173 | + IPA_CMD_SETGMAC)); | |
| 174 | + if (rc == -EEXIST) | |
| 175 | + QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n", | |
| 176 | + mac, QETH_CARD_IFNAME(card)); | |
| 177 | + else if (rc) | |
| 178 | + QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n", | |
| 179 | + mac, QETH_CARD_IFNAME(card), rc); | |
| 180 | + return rc; | |
| 176 | 181 | } |
| 177 | 182 | |
| 178 | 183 | static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) |
| 179 | 184 | { |
| 185 | + int rc; | |
| 186 | + | |
| 180 | 187 | QETH_CARD_TEXT(card, 2, "L2Dgmac"); |
| 181 | − return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC, | |
| 182 | − qeth_l2_send_delgroupmac_cb); | |
| 188 | + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, | |
| 189 | + IPA_CMD_DELGMAC)); | |
| 190 | + if (rc) | |
| 191 | + QETH_DBF_MESSAGE(2, | |
| 192 | + "Could not delete group MAC %pM on %s: %d\n", | |
| 193 | + mac, QETH_CARD_IFNAME(card), rc); | |
| 194 | + return rc; | |
| 183 | 195 | } |
| 184 | 196 | |
| 185 | 197 | static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) |
| @@ -197,10 +209,11 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) · 11 unmodified lines | ||
| 197 | 209 | mc->is_vmac = vmac; |
| 198 | 210 | |
| 199 | 211 | if (vmac) { |
| 200 | − rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, | |
| 201 | − NULL); | |
| 212 | + rc = qeth_setdel_makerc(card, | |
| 213 | + qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC)); | |
| 202 | 214 | } else { |
| 203 | − rc = qeth_l2_send_setgroupmac(card, mac); | |
| 215 | + rc = qeth_setdel_makerc(card, | |
| 216 | + qeth_l2_send_setgroupmac(card, mac)); | |
| 204 | 217 | } |
| 205 | 218 | |
| 206 | 219 | if (!rc) |
| @@ -218,7 +231,7 @@ static void qeth_l2_del_all_mc(struct qeth_card *card, int del) · 11 unmodified lines | ||
| 218 | 231 | if (del) { |
| 219 | 232 | if (mc->is_vmac) |
| 220 | 233 | qeth_l2_send_setdelmac(card, mc->mc_addr, |
| 221 | − IPA_CMD_DELVMAC, NULL); | |
| 234 | + IPA_CMD_DELVMAC); | |
| 222 | 235 | else |
| 223 | 236 | qeth_l2_send_delgroupmac(card, mc->mc_addr); |
| 224 | 237 | } |
| @@ -291,6 +304,8 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i, · 66 unmodified lines | ||
| 291 | 304 | |
| 292 | 305 | QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); |
| 293 | 306 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
| 307 | + if (!iob) | |
| 308 | + return -ENOMEM; | |
| 294 | 309 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 295 | 310 | cmd->data.setdelvlan.vlan_id = i; |
| 296 | 311 | return qeth_send_ipa_cmd(card, iob, |
| @@ -313,6 +328,7 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, · 16 unmodified lines | ||
| 313 | 328 | { |
| 314 | 329 | struct qeth_card *card = dev->ml_priv; |
| 315 | 330 | struct qeth_vlan_vid *id; |
| 331 | + int rc; | |
| 316 | 332 | |
| 317 | 333 | QETH_CARD_TEXT_(card, 4, "aid:%d", vid); |
| 318 | 334 | if (!vid) |
| @@ -328,7 +344,11 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, · 9 unmodified lines | ||
| 328 | 344 | id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC); |
| 329 | 345 | if (id) { |
| 330 | 346 | id->vid = vid; |
| 331 | − qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); | |
| 347 | + rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); | |
| 348 | + if (rc) { | |
| 349 | + kfree(id); | |
| 350 | + return rc; | |
| 351 | + } | |
| 332 | 352 | spin_lock_bh(&card->vlanlock); |
| 333 | 353 | list_add_tail(&id->list, &card->vid_list); |
| 334 | 354 | spin_unlock_bh(&card->vlanlock); |
| @@ -343,6 +363,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, · 8 unmodified lines | ||
| 343 | 363 | { |
| 344 | 364 | struct qeth_vlan_vid *id, *tmpid = NULL; |
| 345 | 365 | struct qeth_card *card = dev->ml_priv; |
| 366 | + int rc = 0; | |
| 346 | 367 | |
| 347 | 368 | QETH_CARD_TEXT_(card, 4, "kid:%d", vid); |
| 348 | 369 | if (card->info.type == QETH_CARD_TYPE_OSM) { |
| @@ -363,11 +384,11 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, · 14 unmodified lines | ||
| 363 | 384 | } |
| 364 | 385 | spin_unlock_bh(&card->vlanlock); |
| 365 | 386 | if (tmpid) { |
| 366 | − qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); | |
| 387 | + rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); | |
| 367 | 388 | kfree(tmpid); |
| 368 | 389 | } |
| 369 | 390 | qeth_l2_set_multicast_list(card->dev); |
| 370 | − return 0; | |
| 391 | + return rc; | |
| 371 | 392 | } |
| 372 | 393 | |
| 373 | 394 | static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) |
| @@ -539,91 +560,62 @@ out: · 165 unmodified lines | ||
| 539 | 560 | } |
| 540 | 561 | |
| 541 | 562 | static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, |
| 542 | − enum qeth_ipa_cmds ipacmd, | |
| 543 | − int (*reply_cb) (struct qeth_card *, | |
| 544 | − struct qeth_reply*, | |
| 545 | − unsigned long)) | |
| 563 | + enum qeth_ipa_cmds ipacmd) | |
| 546 | 564 | { |
| 547 | 565 | struct qeth_ipa_cmd *cmd; |
| 548 | 566 | struct qeth_cmd_buffer *iob; |
| 549 | 567 | |
| 550 | 568 | QETH_CARD_TEXT(card, 2, "L2sdmac"); |
| 551 | 569 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
| 570 | + if (!iob) | |
| 571 | + return -ENOMEM; | |
| 552 | 572 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 553 | 573 | cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; |
| 554 | 574 | memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); |
| 555 | − return qeth_send_ipa_cmd(card, iob, reply_cb, NULL); | |
| 575 | + return qeth_send_ipa_cmd(card, iob, NULL, NULL); | |
| 556 | 576 | } |
| 557 | 577 | |
| 558 | −static int qeth_l2_send_setmac_cb(struct qeth_card *card, | |
| 559 | − struct qeth_reply *reply, | |
| 560 | − unsigned long data) | |
| 578 | +static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) | |
| 561 | 579 | { |
| 562 | − struct qeth_ipa_cmd *cmd; | |
| 580 | + int rc; | |
| 563 | 581 | |
| 564 | − QETH_CARD_TEXT(card, 2, "L2Smaccb"); | |
| 565 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 566 | − if (cmd->hdr.return_code) { | |
| 567 | − QETH_CARD_TEXT_(card, 2, "L2er%x", cmd->hdr.return_code); | |
| 582 | + QETH_CARD_TEXT(card, 2, "L2Setmac"); | |
| 583 | + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, | |
| 584 | + IPA_CMD_SETVMAC)); | |
| 585 | + if (rc == 0) { | |
| 586 | + card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; | |
| 587 | + memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN); | |
| 588 | + dev_info(&card->gdev->dev, | |
| 589 | + "MAC address %pM successfully registered on device %s\n", | |
| 590 | + card->dev->dev_addr, card->dev->name); | |
| 591 | + } else { | |
| 568 | 592 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
| 569 | − switch (cmd->hdr.return_code) { | |
| 570 | − case IPA_RC_L2_DUP_MAC: | |
| 571 | − case IPA_RC_L2_DUP_LAYER3_MAC: | |
| 593 | + switch (rc) { | |
| 594 | + case -EEXIST: | |
| 572 | 595 | dev_warn(&card->gdev->dev, |
| 573 | − "MAC address %pM already exists\n", | |
| 574 | − cmd->data.setdelmac.mac); | |
| 596 | + "MAC address %pM already exists\n", mac); | |
| 575 | 597 | break; |
| 576 | − case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | |
| 577 | − case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | |
| 598 | + case -EPERM: | |
| 578 | 599 | dev_warn(&card->gdev->dev, |
| 579 | − "MAC address %pM is not authorized\n", | |
| 580 | − cmd->data.setdelmac.mac); | |
| 581 | − break; | |
| 582 | − default: | |
| 600 | + "MAC address %pM is not authorized\n", mac); | |
| 583 | 601 | break; |
| 584 | 602 | } |
| 585 | − } else { | |
| 586 | − card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; | |
| 587 | − memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, | |
| 588 | − OSA_ADDR_LEN); | |
| 589 | − dev_info(&card->gdev->dev, | |
| 590 | − "MAC address %pM successfully registered on device %s\n", | |
| 591 | − card->dev->dev_addr, card->dev->name); | |
| 592 | − } | |
| 593 | − return 0; | |
| 594 | −} | |
| 595 | − | |
| 596 | −static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) | |
| 597 | −{ | |
| 598 | − QETH_CARD_TEXT(card, 2, "L2Setmac"); | |
| 599 | − return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, | |
| 600 | − qeth_l2_send_setmac_cb); | |
| 601 | −} | |
| 602 | − | |
| 603 | −static int qeth_l2_send_delmac_cb(struct qeth_card *card, | |
| 604 | − struct qeth_reply *reply, | |
| 605 | − unsigned long data) | |
| 606 | −{ | |
| 607 | − struct qeth_ipa_cmd *cmd; | |
| 608 | − | |
| 609 | − QETH_CARD_TEXT(card, 2, "L2Dmaccb"); | |
| 610 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 611 | − if (cmd->hdr.return_code) { | |
| 612 | − QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code); | |
| 613 | − return 0; | |
| 614 | 603 | } |
| 615 | − card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | |
| 616 | − | |
| 617 | − return 0; | |
| 604 | + return rc; | |
| 618 | 605 | } |
| 619 | 606 | |
| 620 | 607 | static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) |
| 621 | 608 | { |
| 609 | + int rc; | |
| 610 | + | |
| 622 | 611 | QETH_CARD_TEXT(card, 2, "L2Delmac"); |
| 623 | 612 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) |
| 624 | 613 | return 0; |
| 625 | − return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, | |
| 626 | − qeth_l2_send_delmac_cb); | |
| 614 | + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, | |
| 615 | + IPA_CMD_DELVMAC)); | |
| 616 | + if (rc == 0) | |
| 617 | + card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | |
| 618 | + return rc; | |
| 627 | 619 | } |
| 628 | 620 | |
| 629 | 621 | static int qeth_l2_request_initial_mac(struct qeth_card *card) |
| @@ -651,7 +643,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) · 21 unmodified lines | ||
| 651 | 643 | if (rc) { |
| 652 | 644 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " |
| 653 | 645 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
| 654 | − QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | |
| 646 | + QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc); | |
| 655 | 647 | return rc; |
| 656 | 648 | } |
| 657 | 649 | QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); |
| @@ -687,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) · 29 unmodified lines | ||
| 687 | 679 | return -ERESTARTSYS; |
| 688 | 680 | } |
| 689 | 681 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); |
| 690 | − if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) | |
| 682 | + if (!rc || (rc == -ENOENT)) | |
| 691 | 683 | rc = qeth_l2_send_setmac(card, addr->sa_data); |
| 692 | 684 | return rc ? -EINVAL : 0; |
| 693 | 685 | } |
| @@ -996,7 +988,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) · 302 unmodified lines | ||
| 996 | 988 | recover_flag = card->state; |
| 997 | 989 | rc = qeth_core_hardsetup_card(card); |
| 998 | 990 | if (rc) { |
| 999 | − QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | |
| 991 | + QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); | |
| 1000 | 992 | rc = -ENODEV; |
| 1001 | 993 | goto out_remove; |
| 1002 | 994 | } |
| @@ -1730,6 +1722,8 @@ static void qeth_bridgeport_query_support(struct qeth_card *card) · 727 unmodified lines | ||
| 1730 | 1722 | |
| 1731 | 1723 | QETH_CARD_TEXT(card, 2, "brqsuppo"); |
| 1732 | 1724 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
| 1725 | + if (!iob) | |
| 1726 | + return; | |
| 1733 | 1727 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1734 | 1728 | cmd->data.sbp.hdr.cmdlength = |
| 1735 | 1729 | sizeof(struct qeth_ipacmd_sbp_hdr) + |
| @@ -1805,6 +1799,8 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, · 69 unmodified lines | ||
| 1805 | 1799 | if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) |
| 1806 | 1800 | return -EOPNOTSUPP; |
| 1807 | 1801 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
| 1802 | + if (!iob) | |
| 1803 | + return -ENOMEM; | |
| 1808 | 1804 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1809 | 1805 | cmd->data.sbp.hdr.cmdlength = |
| 1810 | 1806 | sizeof(struct qeth_ipacmd_sbp_hdr); |
| @@ -1817,9 +1813,7 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, · 6 unmodified lines | ||
| 1817 | 1813 | if (rc) |
| 1818 | 1814 | return rc; |
| 1819 | 1815 | rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); |
| 1820 | − if (rc) | |
| 1821 | − return rc; | |
| 1822 | − return 0; | |
| 1816 | + return rc; | |
| 1823 | 1817 | } |
| 1824 | 1818 | EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); |
| 1825 | 1819 | |
| @@ -1873,6 +1867,8 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) · 47 unmodified lines | ||
| 1873 | 1867 | if (!(card->options.sbp.supported_funcs & setcmd)) |
| 1874 | 1868 | return -EOPNOTSUPP; |
| 1875 | 1869 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
| 1870 | + if (!iob) | |
| 1871 | + return -ENOMEM; | |
| 1876 | 1872 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1877 | 1873 | cmd->data.sbp.hdr.cmdlength = cmdlength; |
| 1878 | 1874 | cmd->data.sbp.hdr.command_code = setcmd; |
| @@ -549,6 +549,8 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card, · 548 unmodified lines | ||
| 549 | 549 | QETH_CARD_TEXT(card, 4, "setdelmc"); |
| 550 | 550 | |
| 551 | 551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); |
| 552 | + if (!iob) | |
| 553 | + return -ENOMEM; | |
| 552 | 554 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 553 | 555 | memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); |
| 554 | 556 | if (addr->proto == QETH_PROT_IPV6) |
| @@ -588,6 +590,8 @@ static int qeth_l3_send_setdelip(struct qeth_card *card, · 33 unmodified lines | ||
| 588 | 590 | QETH_CARD_TEXT_(card, 4, "flags%02X", flags); |
| 589 | 591 | |
| 590 | 592 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); |
| 593 | + if (!iob) | |
| 594 | + return -ENOMEM; | |
| 591 | 595 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 592 | 596 | if (addr->proto == QETH_PROT_IPV6) { |
| 593 | 597 | memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, |
| @@ -616,6 +620,8 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, · 22 unmodified lines | ||
| 616 | 620 | |
| 617 | 621 | QETH_CARD_TEXT(card, 4, "setroutg"); |
| 618 | 622 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); |
| 623 | + if (!iob) | |
| 624 | + return -ENOMEM; | |
| 619 | 625 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 620 | 626 | cmd->data.setrtg.type = (type); |
| 621 | 627 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); |
| @@ -1049,12 +1055,14 @@ static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd( · 427 unmodified lines | ||
| 1049 | 1055 | QETH_CARD_TEXT(card, 4, "getasscm"); |
| 1050 | 1056 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); |
| 1051 | 1057 | |
| 1052 | − cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | |
| 1053 | − cmd->data.setassparms.hdr.assist_no = ipa_func; | |
| 1054 | − cmd->data.setassparms.hdr.length = 8 + len; | |
| 1055 | − cmd->data.setassparms.hdr.command_code = cmd_code; | |
| 1056 | − cmd->data.setassparms.hdr.return_code = 0; | |
| 1057 | − cmd->data.setassparms.hdr.seq_no = 0; | |
| 1058 | + if (iob) { | |
| 1059 | + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | |
| 1060 | + cmd->data.setassparms.hdr.assist_no = ipa_func; | |
| 1061 | + cmd->data.setassparms.hdr.length = 8 + len; | |
| 1062 | + cmd->data.setassparms.hdr.command_code = cmd_code; | |
| 1063 | + cmd->data.setassparms.hdr.return_code = 0; | |
| 1064 | + cmd->data.setassparms.hdr.seq_no = 0; | |
| 1065 | + } | |
| 1058 | 1066 | |
| 1059 | 1067 | return iob; |
| 1060 | 1068 | } |
| @@ -1090,6 +1098,8 @@ static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, · 29 unmodified lines | ||
| 1090 | 1098 | QETH_CARD_TEXT(card, 4, "simassp6"); |
| 1091 | 1099 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, |
| 1092 | 1100 | 0, QETH_PROT_IPV6); |
| 1101 | + if (!iob) | |
| 1102 | + return -ENOMEM; | |
| 1093 | 1103 | rc = qeth_l3_send_setassparms(card, iob, 0, 0, |
| 1094 | 1104 | qeth_l3_default_setassparms_cb, NULL); |
| 1095 | 1105 | return rc; |
| @@ -1108,6 +1118,8 @@ static int qeth_l3_send_simple_setassparms(struct qeth_card *card, · 12 unmodified lines | ||
| 1108 | 1118 | length = sizeof(__u32); |
| 1109 | 1119 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, |
| 1110 | 1120 | length, QETH_PROT_IPV4); |
| 1121 | + if (!iob) | |
| 1122 | + return -ENOMEM; | |
| 1111 | 1123 | rc = qeth_l3_send_setassparms(card, iob, length, data, |
| 1112 | 1124 | qeth_l3_default_setassparms_cb, NULL); |
| 1113 | 1125 | return rc; |
| @@ -1494,6 +1506,8 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card) · 380 unmodified lines | ||
| 1494 | 1506 | |
| 1495 | 1507 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, |
| 1496 | 1508 | QETH_PROT_IPV6); |
| 1509 | + if (!iob) | |
| 1510 | + return -ENOMEM; | |
| 1497 | 1511 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1498 | 1512 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = |
| 1499 | 1513 | card->info.unique_id; |
| @@ -1537,6 +1551,8 @@ static int qeth_l3_get_unique_id(struct qeth_card *card) · 37 unmodified lines | ||
| 1537 | 1551 | |
| 1538 | 1552 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, |
| 1539 | 1553 | QETH_PROT_IPV6); |
| 1554 | + if (!iob) | |
| 1555 | + return -ENOMEM; | |
| 1540 | 1556 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1541 | 1557 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = |
| 1542 | 1558 | card->info.unique_id; |
| @@ -1611,6 +1627,8 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) · 68 unmodified lines | ||
| 1611 | 1627 | QETH_DBF_TEXT(SETUP, 2, "diagtrac"); |
| 1612 | 1628 | |
| 1613 | 1629 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
| 1630 | + if (!iob) | |
| 1631 | + return -ENOMEM; | |
| 1614 | 1632 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1615 | 1633 | cmd->data.diagass.subcmd_len = 16; |
| 1616 | 1634 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; |
| @@ -2442,6 +2460,8 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card, · 825 unmodified lines | ||
| 2442 | 2460 | IPA_CMD_ASS_ARP_QUERY_INFO, |
| 2443 | 2461 | sizeof(struct qeth_arp_query_data) - sizeof(char), |
| 2444 | 2462 | prot); |
| 2463 | + if (!iob) | |
| 2464 | + return -ENOMEM; | |
| 2445 | 2465 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 2446 | 2466 | cmd->data.setassparms.data.query_arp.request_bits = 0x000F; |
| 2447 | 2467 | cmd->data.setassparms.data.query_arp.reply_bits = 0; |
| @@ -2535,6 +2555,8 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, · 87 unmodified lines | ||
| 2535 | 2555 | IPA_CMD_ASS_ARP_ADD_ENTRY, |
| 2536 | 2556 | sizeof(struct qeth_arp_cache_entry), |
| 2537 | 2557 | QETH_PROT_IPV4); |
| 2558 | + if (!iob) | |
| 2559 | + return -ENOMEM; | |
| 2538 | 2560 | rc = qeth_l3_send_setassparms(card, iob, |
| 2539 | 2561 | sizeof(struct qeth_arp_cache_entry), |
| 2540 | 2562 | (unsigned long) entry, |
| @@ -2574,6 +2596,8 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, · 33 unmodified lines | ||
| 2574 | 2596 | IPA_CMD_ASS_ARP_REMOVE_ENTRY, |
| 2575 | 2597 | 12, |
| 2576 | 2598 | QETH_PROT_IPV4); |
| 2599 | + if (!iob) | |
| 2600 | + return -ENOMEM; | |
| 2577 | 2601 | rc = qeth_l3_send_setassparms(card, iob, |
| 2578 | 2602 | 12, (unsigned long)buf, |
| 2579 | 2603 | qeth_l3_default_setassparms_cb, NULL); |
| @@ -3262,6 +3286,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { · 682 unmodified lines | ||
| 3262 | 3286 | |
| 3263 | 3287 | static int qeth_l3_setup_netdev(struct qeth_card *card) |
| 3264 | 3288 | { |
| 3289 | + int rc; | |
| 3290 | + | |
| 3265 | 3291 | if (card->info.type == QETH_CARD_TYPE_OSD || |
| 3266 | 3292 | card->info.type == QETH_CARD_TYPE_OSX) { |
| 3267 | 3293 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || |
| @@ -3293,7 +3319,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) · 25 unmodified lines | ||
| 3293 | 3319 | return -ENODEV; |
| 3294 | 3320 | card->dev->flags |= IFF_NOARP; |
| 3295 | 3321 | card->dev->netdev_ops = &qeth_l3_netdev_ops; |
| 3296 | − qeth_l3_iqd_read_initial_mac(card); | |
| 3322 | + rc = qeth_l3_iqd_read_initial_mac(card); | |
| 3323 | + if (rc) | |
| 3324 | + return rc; | |
| 3297 | 3325 | if (card->options.hsuid[0]) |
| 3298 | 3326 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); |
| 3299 | 3327 | } else |
| @@ -3360,7 +3388,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) · 60 unmodified lines | ||
| 3360 | 3388 | recover_flag = card->state; |
| 3361 | 3389 | rc = qeth_core_hardsetup_card(card); |
| 3362 | 3390 | if (rc) { |
| 3363 | − QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | |
| 3391 | + QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); | |
| 3364 | 3392 | rc = -ENODEV; |
| 3365 | 3393 | goto out_remove; |
| 3366 | 3394 | } |
| @@ -3401,7 +3429,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) · 34 unmodified lines | ||
| 3401 | 3429 | contin: |
| 3402 | 3430 | rc = qeth_l3_setadapter_parms(card); |
| 3403 | 3431 | if (rc) |
| 3404 | − QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | |
| 3432 | + QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); | |
| 3405 | 3433 | if (!card->options.sniffer) { |
| 3406 | 3434 | rc = qeth_l3_start_ipassists(card); |
| 3407 | 3435 | if (rc) { |
| @@ -3410,10 +3438,10 @@ contin: · 2 unmodified lines | ||
| 3410 | 3438 | } |
| 3411 | 3439 | rc = qeth_l3_setrouting_v4(card); |
| 3412 | 3440 | if (rc) |
| 3413 | − QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); | |
| 3441 | + QETH_DBF_TEXT_(SETUP, 2, "4err%04x", rc); | |
| 3414 | 3442 | rc = qeth_l3_setrouting_v6(card); |
| 3415 | 3443 | if (rc) |
| 3416 | − QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); | |
| 3444 | + QETH_DBF_TEXT_(SETUP, 2, "5err%04x", rc); | |
| 3417 | 3445 | } |
| 3418 | 3446 | netif_tx_disable(card->dev); |
| 3419 | 3447 | |
| @@ -986,9 +986,9 @@ int scsi_device_get(struct scsi_device *sdev) · 985 unmodified lines | ||
| 986 | 986 | return -ENXIO; |
| 987 | 987 | if (!get_device(&sdev->sdev_gendev)) |
| 988 | 988 | return -ENXIO; |
| 989 | − /* We can fail this if we're doing SCSI operations | |
| 989 | + /* We can fail try_module_get if we're doing SCSI operations | |
| 990 | 990 | * from module exit (like cache flush) */ |
| 991 | − try_module_get(sdev->host->hostt->module); | |
| 991 | + __module_get(sdev->host->hostt->module); | |
| 992 | 992 | |
| 993 | 993 | return 0; |
| 994 | 994 | } |
| @@ -1004,14 +1004,7 @@ EXPORT_SYMBOL(scsi_device_get); · 9 unmodified lines | ||
| 1004 | 1004 | */ |
| 1005 | 1005 | void scsi_device_put(struct scsi_device *sdev) |
| 1006 | 1006 | { |
| 1007 | −#ifdef CONFIG_MODULE_UNLOAD | |
| 1008 | − struct module *module = sdev->host->hostt->module; | |
| 1009 | − | |
| 1010 | − /* The module refcount will be zero if scsi_device_get() | |
| 1011 | − * was called from a module removal routine */ | |
| 1012 | − if (module && module_refcount(module) != 0) | |
| 1013 | − module_put(module); | |
| 1014 | −#endif | |
| 1007 | + module_put(sdev->host->hostt->module); | |
| 1015 | 1008 | put_device(&sdev->sdev_gendev); |
| 1016 | 1009 | } |
| 1017 | 1010 | EXPORT_SYMBOL(scsi_device_put); |
| @@ -271,7 +271,6 @@ int dw_spi_mid_init(struct dw_spi *dws) · 270 unmodified lines | ||
| 271 | 271 | iounmap(clk_reg); |
| 272 | 272 | |
| 273 | 273 | dws->num_cs = 16; |
| 274 | − dws->fifo_len = 40; /* FIFO has 40 words buffer */ | |
| 275 | 274 | |
| 276 | 275 | #ifdef CONFIG_SPI_DW_MID_DMA |
| 277 | 276 | dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL); |
| @@ -621,13 +621,13 @@ static void spi_hw_init(struct dw_spi *dws) · 620 unmodified lines | ||
| 621 | 621 | if (!dws->fifo_len) { |
| 622 | 622 | u32 fifo; |
| 623 | 623 | |
| 624 | − for (fifo = 2; fifo <= 257; fifo++) { | |
| 624 | + for (fifo = 2; fifo <= 256; fifo++) { | |
| 625 | 625 | dw_writew(dws, DW_SPI_TXFLTR, fifo); |
| 626 | 626 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) |
| 627 | 627 | break; |
| 628 | 628 | } |
| 629 | 629 | |
| 630 | − dws->fifo_len = (fifo == 257) ? 0 : fifo; | |
| 630 | + dws->fifo_len = (fifo == 2) ? 0 : fifo - 1; | |
| 631 | 631 | dw_writew(dws, DW_SPI_TXFLTR, 0); |
| 632 | 632 | } |
| 633 | 633 | } |
| @@ -673,7 +673,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) · 39 unmodified lines | ||
| 673 | 673 | if (dws->dma_ops && dws->dma_ops->dma_init) { |
| 674 | 674 | ret = dws->dma_ops->dma_init(dws); |
| 675 | 675 | if (ret) { |
| 676 | − dev_warn(&master->dev, "DMA init failed\n"); | |
| 676 | + dev_warn(dev, "DMA init failed\n"); | |
| 677 | 677 | dws->dma_inited = 0; |
| 678 | 678 | } |
| 679 | 679 | } |
| @@ -546,8 +546,8 @@ static void giveback(struct driver_data *drv_data) · 545 unmodified lines | ||
| 546 | 546 | cs_deassert(drv_data); |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | − spi_finalize_current_message(drv_data->master); | |
| 550 | 549 | drv_data->cur_chip = NULL; |
| 550 | + spi_finalize_current_message(drv_data->master); | |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | static void reset_sccr1(struct driver_data *drv_data) |
| @@ -82,7 +82,7 @@ struct sh_msiof_spi_priv { · 81 unmodified lines | ||
| 82 | 82 | #define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ |
| 83 | 83 | #define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ |
| 84 | 84 | #define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ |
| 85 | −#define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */ | |
| 85 | +#define MDR1_FLD_MASK 0x0000000c /* Frame Sync Signal Interval (0-3) */ | |
| 86 | 86 | #define MDR1_FLD_SHIFT 2 |
| 87 | 87 | #define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ |
| 88 | 88 | /* TMDR1 */ |
| @@ -632,7 +632,7 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) · 631 unmodified lines | ||
| 632 | 632 | return 0; |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | − if (cfio->fault.ft_flags & VM_FAULT_SIGBUS) { | |
| 635 | + if (cfio->fault.ft_flags & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) { | |
| 636 | 636 | CDEBUG(D_PAGE, "got addr %p - SIGBUS\n", vmf->virtual_address); |
| 637 | 637 | return -EFAULT; |
| 638 | 638 | } |
| @@ -85,23 +85,20 @@ static struct nvec_chip *nvec_power_handle; · 84 unmodified lines | ||
| 85 | 85 | static const struct mfd_cell nvec_devices[] = { |
| 86 | 86 | { |
| 87 | 87 | .name = "nvec-kbd", |
| 88 | − .id = 1, | |
| 89 | 88 | }, |
| 90 | 89 | { |
| 91 | 90 | .name = "nvec-mouse", |
| 92 | − .id = 1, | |
| 93 | 91 | }, |
| 94 | 92 | { |
| 95 | 93 | .name = "nvec-power", |
| 96 | − .id = 1, | |
| 94 | + .id = 0, | |
| 97 | 95 | }, |
| 98 | 96 | { |
| 99 | 97 | .name = "nvec-power", |
| 100 | − .id = 2, | |
| 98 | + .id = 1, | |
| 101 | 99 | }, |
| 102 | 100 | { |
| 103 | 101 | .name = "nvec-paz00", |
| 104 | − .id = 1, | |
| 105 | 102 | }, |
| 106 | 103 | }; |
| 107 | 104 | |
| @@ -891,7 +888,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) · 783 unmodified lines | ||
| 891 | 888 | nvec_msg_free(nvec, msg); |
| 892 | 889 | } |
| 893 | 890 | |
| 894 | − ret = mfd_add_devices(nvec->dev, -1, nvec_devices, | |
| 891 | + ret = mfd_add_devices(nvec->dev, 0, nvec_devices, | |
| 895 | 892 | ARRAY_SIZE(nvec_devices), NULL, 0, NULL); |
| 896 | 893 | if (ret) |
| 897 | 894 | dev_err(nvec->dev, "error adding subdevices\n"); |
| @@ -55,6 +55,11 @@ static int is_targeted(struct usb_device *dev) · 54 unmodified lines | ||
| 55 | 55 | le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) |
| 56 | 56 | return 0; |
| 57 | 57 | |
| 58 | + /* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */ | |
| 59 | + if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && | |
| 60 | + le16_to_cpu(dev->descriptor.idProduct) == 0x0200)) | |
| 61 | + return 1; | |
| 62 | + | |
| 58 | 63 | /* NOTE: can't use usb_match_id() since interface caches |
| 59 | 64 | * aren't set up yet. this is cut/paste from that code. |
| 60 | 65 | */ |
| @@ -179,6 +179,10 @@ static const struct usb_device_id usb_quirk_list[] = { · 178 unmodified lines | ||
| 179 | 179 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = |
| 180 | 180 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, |
| 181 | 181 | |
| 182 | + /* Protocol and OTG Electrical Test Device */ | |
| 183 | + { USB_DEVICE(0x1a0a, 0x0200), .driver_info = | |
| 184 | + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | |
| 185 | + | |
| 182 | 186 | { } /* terminating entry must be last */ |
| 183 | 187 | }; |
| 184 | 188 | |
| @@ -476,13 +476,13 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) · 475 unmodified lines | ||
| 476 | 476 | u32 gintsts; |
| 477 | 477 | irqreturn_t retval = IRQ_NONE; |
| 478 | 478 | |
| 479 | + spin_lock(&hsotg->lock); | |
| 480 | + | |
| 479 | 481 | if (!dwc2_is_controller_alive(hsotg)) { |
| 480 | 482 | dev_warn(hsotg->dev, "Controller is dead\n"); |
| 481 | 483 | goto out; |
| 482 | 484 | } |
| 483 | 485 | |
| 484 | − spin_lock(&hsotg->lock); | |
| 485 | − | |
| 486 | 486 | gintsts = dwc2_read_common_intr(hsotg); |
| 487 | 487 | if (gintsts & ~GINTSTS_PRTINT) |
| 488 | 488 | retval = IRQ_HANDLED; |
| @@ -515,8 +515,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) · 26 unmodified lines | ||
| 515 | 515 | } |
| 516 | 516 | } |
| 517 | 517 | |
| 518 | − spin_unlock(&hsotg->lock); | |
| 519 | 518 | out: |
| 519 | + spin_unlock(&hsotg->lock); | |
| 520 | 520 | return retval; |
| 521 | 521 | } |
| 522 | 522 | EXPORT_SYMBOL_GPL(dwc2_handle_common_intr); |
| @@ -34,7 +34,7 @@ static struct usb_phy *__usb_find_phy(struct list_head *list, · 33 unmodified lines | ||
| 34 | 34 | return phy; |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | − return ERR_PTR(-EPROBE_DEFER); | |
| 37 | + return ERR_PTR(-ENODEV); | |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | static struct usb_phy *__usb_find_phy_dev(struct device *dev, |
| @@ -507,7 +507,7 @@ UNUSUAL_DEV( 0x04e6, 0x000c, 0x0100, 0x0100, · 506 unmodified lines | ||
| 507 | 507 | UNUSUAL_DEV( 0x04e6, 0x000f, 0x0000, 0x9999, |
| 508 | 508 | "SCM Microsystems", |
| 509 | 509 | "eUSB SCSI Adapter (Bus Powered)", |
| 510 | − USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, | |
| 510 | + USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init, | |
| 511 | 511 | US_FL_SCM_MULT_TARG ), |
| 512 | 512 | |
| 513 | 513 | UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, |
| @@ -1995,6 +1995,13 @@ UNUSUAL_DEV( 0x152d, 0x2329, 0x0100, 0x0100, · 1481 unmodified lines | ||
| 1995 | 1995 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 1996 | 1996 | US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), |
| 1997 | 1997 | |
| 1998 | +/* Reported by Dmitry Nezhevenko <dion@dion.org.ua> */ | |
| 1999 | +UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114, | |
| 2000 | + "JMicron", | |
| 2001 | + "USB to ATA/ATAPI Bridge", | |
| 2002 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 2003 | + US_FL_BROKEN_FUA ), | |
| 2004 | + | |
| 1998 | 2005 | /* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) |
| 1999 | 2006 | * and Mac USB Dock USB-SCSI */ |
| 2000 | 2007 | UNUSUAL_DEV( 0x1645, 0x0007, 0x0100, 0x0133, |
| @@ -140,3 +140,10 @@ UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, · 139 unmodified lines | ||
| 140 | 140 | "External HDD", |
| 141 | 141 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 142 | 142 | US_FL_IGNORE_UAS), |
| 143 | + | |
| 144 | +/* Reported-by: Richard Henderson <rth@redhat.com> */ | |
| 145 | +UNUSUAL_DEV(0x4971, 0x8017, 0x0000, 0x9999, | |
| 146 | + "SimpleTech", | |
| 147 | + "External HDD", | |
| 148 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 149 | + US_FL_NO_REPORT_OPCODES), | |
| @@ -3065,6 +3065,8 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, · 3064 unmodified lines | ||
| 3065 | 3065 | path->search_commit_root = 1; |
| 3066 | 3066 | path->skip_locking = 1; |
| 3067 | 3067 | |
| 3068 | + ppath->search_commit_root = 1; | |
| 3069 | + ppath->skip_locking = 1; | |
| 3068 | 3070 | /* |
| 3069 | 3071 | * trigger the readahead for extent tree csum tree and wait for |
| 3070 | 3072 | * completion. During readahead, the scrub is officially paused |
| @@ -667,7 +667,7 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) · 666 unmodified lines | ||
| 667 | 667 | |
| 668 | 668 | static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, |
| 669 | 669 | s64 change, struct gfs2_quota_data *qd, |
| 670 | − struct fs_disk_quota *fdq) | |
| 670 | + struct qc_dqblk *fdq) | |
| 671 | 671 | { |
| 672 | 672 | struct inode *inode = &ip->i_inode; |
| 673 | 673 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| @@ -697,16 +697,16 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, · 23 unmodified lines | ||
| 697 | 697 | be64_add_cpu(&q.qu_value, change); |
| 698 | 698 | qd->qd_qb.qb_value = q.qu_value; |
| 699 | 699 | if (fdq) { |
| 700 | − if (fdq->d_fieldmask & FS_DQ_BSOFT) { | |
| 701 | − q.qu_warn = cpu_to_be64(fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift); | |
| 700 | + if (fdq->d_fieldmask & QC_SPC_SOFT) { | |
| 701 | + q.qu_warn = cpu_to_be64(fdq->d_spc_softlimit >> sdp->sd_sb.sb_bsize_shift); | |
| 702 | 702 | qd->qd_qb.qb_warn = q.qu_warn; |
| 703 | 703 | } |
| 704 | − if (fdq->d_fieldmask & FS_DQ_BHARD) { | |
| 705 | − q.qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift); | |
| 704 | + if (fdq->d_fieldmask & QC_SPC_HARD) { | |
| 705 | + q.qu_limit = cpu_to_be64(fdq->d_spc_hardlimit >> sdp->sd_sb.sb_bsize_shift); | |
| 706 | 706 | qd->qd_qb.qb_limit = q.qu_limit; |
| 707 | 707 | } |
| 708 | − if (fdq->d_fieldmask & FS_DQ_BCOUNT) { | |
| 709 | − q.qu_value = cpu_to_be64(fdq->d_bcount >> sdp->sd_fsb2bb_shift); | |
| 708 | + if (fdq->d_fieldmask & QC_SPACE) { | |
| 709 | + q.qu_value = cpu_to_be64(fdq->d_space >> sdp->sd_sb.sb_bsize_shift); | |
| 710 | 710 | qd->qd_qb.qb_value = q.qu_value; |
| 711 | 711 | } |
| 712 | 712 | } |
| @@ -1497,7 +1497,7 @@ static int gfs2_quota_get_xstate(struct super_block *sb, · 784 unmodified lines | ||
| 1497 | 1497 | } |
| 1498 | 1498 | |
| 1499 | 1499 | static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, |
| 1500 | − struct fs_disk_quota *fdq) | |
| 1500 | + struct qc_dqblk *fdq) | |
| 1501 | 1501 | { |
| 1502 | 1502 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 1503 | 1503 | struct gfs2_quota_lvb *qlvb; |
| @@ -1505,7 +1505,7 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, · 1 unmodified line | ||
| 1505 | 1505 | struct gfs2_holder q_gh; |
| 1506 | 1506 | int error; |
| 1507 | 1507 | |
| 1508 | − memset(fdq, 0, sizeof(struct fs_disk_quota)); | |
| 1508 | + memset(fdq, 0, sizeof(*fdq)); | |
| 1509 | 1509 | |
| 1510 | 1510 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
| 1511 | 1511 | return -ESRCH; /* Crazy XFS error code */ |
| @@ -1522,12 +1522,9 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, · 10 unmodified lines | ||
| 1522 | 1522 | goto out; |
| 1523 | 1523 | |
| 1524 | 1524 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; |
| 1525 | − fdq->d_version = FS_DQUOT_VERSION; | |
| 1526 | − fdq->d_flags = (qid.type == USRQUOTA) ? FS_USER_QUOTA : FS_GROUP_QUOTA; | |
| 1527 | − fdq->d_id = from_kqid_munged(current_user_ns(), qid); | |
| 1528 | − fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; | |
| 1529 | − fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; | |
| 1530 | − fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; | |
| 1525 | + fdq->d_spc_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_sb.sb_bsize_shift; | |
| 1526 | + fdq->d_spc_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_sb.sb_bsize_shift; | |
| 1527 | + fdq->d_space = be64_to_cpu(qlvb->qb_value) << sdp->sd_sb.sb_bsize_shift; | |
| 1531 | 1528 | |
| 1532 | 1529 | gfs2_glock_dq_uninit(&q_gh); |
| 1533 | 1530 | out: |
| @@ -1536,10 +1533,10 @@ out: · 2 unmodified lines | ||
| 1536 | 1533 | } |
| 1537 | 1534 | |
| 1538 | 1535 | /* GFS2 only supports a subset of the XFS fields */ |
| 1539 | −#define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) | |
| 1536 | +#define GFS2_FIELDMASK (QC_SPC_SOFT|QC_SPC_HARD|QC_SPACE) | |
| 1540 | 1537 | |
| 1541 | 1538 | static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, |
| 1542 | − struct fs_disk_quota *fdq) | |
| 1539 | + struct qc_dqblk *fdq) | |
| 1543 | 1540 | { |
| 1544 | 1541 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 1545 | 1542 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); |
| @@ -1583,17 +1580,17 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, · 37 unmodified lines | ||
| 1583 | 1580 | goto out_i; |
| 1584 | 1581 | |
| 1585 | 1582 | /* If nothing has changed, this is a no-op */ |
| 1586 | − if ((fdq->d_fieldmask & FS_DQ_BSOFT) && | |
| 1587 | − ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) | |
| 1588 | − fdq->d_fieldmask ^= FS_DQ_BSOFT; | |
| 1583 | + if ((fdq->d_fieldmask & QC_SPC_SOFT) && | |
| 1584 | + ((fdq->d_spc_softlimit >> sdp->sd_sb.sb_bsize_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) | |
| 1585 | + fdq->d_fieldmask ^= QC_SPC_SOFT; | |
| 1589 | 1586 | |
| 1590 | − if ((fdq->d_fieldmask & FS_DQ_BHARD) && | |
| 1591 | − ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) | |
| 1592 | − fdq->d_fieldmask ^= FS_DQ_BHARD; | |
| 1587 | + if ((fdq->d_fieldmask & QC_SPC_HARD) && | |
| 1588 | + ((fdq->d_spc_hardlimit >> sdp->sd_sb.sb_bsize_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) | |
| 1589 | + fdq->d_fieldmask ^= QC_SPC_HARD; | |
| 1593 | 1590 | |
| 1594 | − if ((fdq->d_fieldmask & FS_DQ_BCOUNT) && | |
| 1595 | − ((fdq->d_bcount >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_value))) | |
| 1596 | − fdq->d_fieldmask ^= FS_DQ_BCOUNT; | |
| 1591 | + if ((fdq->d_fieldmask & QC_SPACE) && | |
| 1592 | + ((fdq->d_space >> sdp->sd_sb.sb_bsize_shift) == be64_to_cpu(qd->qd_qb.qb_value))) | |
| 1593 | + fdq->d_fieldmask ^= QC_SPACE; | |
| 1597 | 1594 | |
| 1598 | 1595 | if (fdq->d_fieldmask == 0) |
| 1599 | 1596 | goto out_i; |
| @@ -212,6 +212,12 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, · 211 unmodified lines | ||
| 212 | 212 | */ |
| 213 | 213 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) |
| 214 | 214 | { |
| 215 | + struct inode *inode = iocb->ki_filp->f_mapping->host; | |
| 216 | + | |
| 217 | + /* we only support swap file calling nfs_direct_IO */ | |
| 218 | + if (!IS_SWAPFILE(inode)) | |
| 219 | + return 0; | |
| 220 | + | |
| 215 | 221 | #ifndef CONFIG_NFS_SWAP |
| 216 | 222 | dprintk("NFS: nfs_direct_IO (%pD) off/no(%Ld/%lu) EINVAL\n", |
| 217 | 223 | iocb->ki_filp, (long long) pos, iter->nr_segs); |
| @@ -352,8 +352,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st · 351 unmodified lines | ||
| 352 | 352 | |
| 353 | 353 | nfs_attr_check_mountpoint(sb, fattr); |
| 354 | 354 | |
| 355 | − if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) && | |
| 356 | − !nfs_attr_use_mounted_on_fileid(fattr)) | |
| 355 | + if (nfs_attr_use_mounted_on_fileid(fattr)) | |
| 356 | + fattr->fileid = fattr->mounted_on_fileid; | |
| 357 | + else if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) | |
| 357 | 358 | goto out_no_inode; |
| 358 | 359 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) |
| 359 | 360 | goto out_no_inode; |
| @@ -31,8 +31,6 @@ static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) · 30 unmodified lines | ||
| 31 | 31 | (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) && |
| 32 | 32 | ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0))) |
| 33 | 33 | return 0; |
| 34 | − | |
| 35 | − fattr->fileid = fattr->mounted_on_fileid; | |
| 36 | 34 | return 1; |
| 37 | 35 | } |
| 38 | 36 | |
| @@ -639,7 +639,7 @@ int nfs41_walk_client_list(struct nfs_client *new, · 638 unmodified lines | ||
| 639 | 639 | prev = pos; |
| 640 | 640 | |
| 641 | 641 | status = nfs_wait_client_init_complete(pos); |
| 642 | − if (status == 0) { | |
| 642 | + if (pos->cl_cons_state == NFS_CS_SESSION_INITING) { | |
| 643 | 643 | nfs4_schedule_lease_recovery(pos); |
| 644 | 644 | status = nfs4_wait_clnt_recover(pos); |
| 645 | 645 | } |
| @@ -2396,30 +2396,25 @@ static inline qsize_t stoqb(qsize_t space) · 2395 unmodified lines | ||
| 2396 | 2396 | } |
| 2397 | 2397 | |
| 2398 | 2398 | /* Generic routine for getting common part of quota structure */ |
| 2399 | −static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |
| 2399 | +static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |
| 2400 | 2400 | { |
| 2401 | 2401 | struct mem_dqblk *dm = &dquot->dq_dqb; |
| 2402 | 2402 | |
| 2403 | 2403 | memset(di, 0, sizeof(*di)); |
| 2404 | − di->d_version = FS_DQUOT_VERSION; | |
| 2405 | − di->d_flags = dquot->dq_id.type == USRQUOTA ? | |
| 2406 | − FS_USER_QUOTA : FS_GROUP_QUOTA; | |
| 2407 | − di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id); | |
| 2408 | − | |
| 2409 | 2404 | spin_lock(&dq_data_lock); |
| 2410 | − di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); | |
| 2411 | − di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit); | |
| 2405 | + di->d_spc_hardlimit = dm->dqb_bhardlimit; | |
| 2406 | + di->d_spc_softlimit = dm->dqb_bsoftlimit; | |
| 2412 | 2407 | di->d_ino_hardlimit = dm->dqb_ihardlimit; |
| 2413 | 2408 | di->d_ino_softlimit = dm->dqb_isoftlimit; |
| 2414 | − di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace; | |
| 2415 | − di->d_icount = dm->dqb_curinodes; | |
| 2416 | − di->d_btimer = dm->dqb_btime; | |
| 2417 | − di->d_itimer = dm->dqb_itime; | |
| 2409 | + di->d_space = dm->dqb_curspace + dm->dqb_rsvspace; | |
| 2410 | + di->d_ino_count = dm->dqb_curinodes; | |
| 2411 | + di->d_spc_timer = dm->dqb_btime; | |
| 2412 | + di->d_ino_timer = dm->dqb_itime; | |
| 2418 | 2413 | spin_unlock(&dq_data_lock); |
| 2419 | 2414 | } |
| 2420 | 2415 | |
| 2421 | 2416 | int dquot_get_dqblk(struct super_block *sb, struct kqid qid, |
| 2422 | − struct fs_disk_quota *di) | |
| 2417 | + struct qc_dqblk *di) | |
| 2423 | 2418 | { |
| 2424 | 2419 | struct dquot *dquot; |
| 2425 | 2420 | |
| @@ -2433,70 +2428,70 @@ int dquot_get_dqblk(struct super_block *sb, struct kqid qid, · 7 unmodified lines | ||
| 2433 | 2428 | } |
| 2434 | 2429 | EXPORT_SYMBOL(dquot_get_dqblk); |
| 2435 | 2430 | |
| 2436 | −#define VFS_FS_DQ_MASK \ | |
| 2437 | − (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ | |
| 2438 | − FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \ | |
| 2439 | − FS_DQ_BTIMER | FS_DQ_ITIMER) | |
| 2431 | +#define VFS_QC_MASK \ | |
| 2432 | + (QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \ | |
| 2433 | + QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \ | |
| 2434 | + QC_SPC_TIMER | QC_INO_TIMER) | |
| 2440 | 2435 | |
| 2441 | 2436 | /* Generic routine for setting common part of quota structure */ |
| 2442 | −static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |
| 2437 | +static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |
| 2443 | 2438 | { |
| 2444 | 2439 | struct mem_dqblk *dm = &dquot->dq_dqb; |
| 2445 | 2440 | int check_blim = 0, check_ilim = 0; |
| 2446 | 2441 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; |
| 2447 | 2442 | |
| 2448 | − if (di->d_fieldmask & ~VFS_FS_DQ_MASK) | |
| 2443 | + if (di->d_fieldmask & ~VFS_QC_MASK) | |
| 2449 | 2444 | return -EINVAL; |
| 2450 | 2445 | |
| 2451 | − if (((di->d_fieldmask & FS_DQ_BSOFT) && | |
| 2452 | − (di->d_blk_softlimit > dqi->dqi_maxblimit)) || | |
| 2453 | − ((di->d_fieldmask & FS_DQ_BHARD) && | |
| 2454 | − (di->d_blk_hardlimit > dqi->dqi_maxblimit)) || | |
| 2455 | − ((di->d_fieldmask & FS_DQ_ISOFT) && | |
| 2446 | + if (((di->d_fieldmask & QC_SPC_SOFT) && | |
| 2447 | + stoqb(di->d_spc_softlimit) > dqi->dqi_maxblimit) || | |
| 2448 | + ((di->d_fieldmask & QC_SPC_HARD) && | |
| 2449 | + stoqb(di->d_spc_hardlimit) > dqi->dqi_maxblimit) || | |
| 2450 | + ((di->d_fieldmask & QC_INO_SOFT) && | |
| 2456 | 2451 | (di->d_ino_softlimit > dqi->dqi_maxilimit)) || |
| 2457 | − ((di->d_fieldmask & FS_DQ_IHARD) && | |
| 2452 | + ((di->d_fieldmask & QC_INO_HARD) && | |
| 2458 | 2453 | (di->d_ino_hardlimit > dqi->dqi_maxilimit))) |
| 2459 | 2454 | return -ERANGE; |
| 2460 | 2455 | |
| 2461 | 2456 | spin_lock(&dq_data_lock); |
| 2462 | − if (di->d_fieldmask & FS_DQ_BCOUNT) { | |
| 2463 | − dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace; | |
| 2457 | + if (di->d_fieldmask & QC_SPACE) { | |
| 2458 | + dm->dqb_curspace = di->d_space - dm->dqb_rsvspace; | |
| 2464 | 2459 | check_blim = 1; |
| 2465 | 2460 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); |
| 2466 | 2461 | } |
| 2467 | 2462 | |
| 2468 | − if (di->d_fieldmask & FS_DQ_BSOFT) | |
| 2469 | − dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit); | |
| 2470 | − if (di->d_fieldmask & FS_DQ_BHARD) | |
| 2471 | − dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit); | |
| 2472 | − if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) { | |
| 2463 | + if (di->d_fieldmask & QC_SPC_SOFT) | |
| 2464 | + dm->dqb_bsoftlimit = di->d_spc_softlimit; | |
| 2465 | + if (di->d_fieldmask & QC_SPC_HARD) | |
| 2466 | + dm->dqb_bhardlimit = di->d_spc_hardlimit; | |
| 2467 | + if (di->d_fieldmask & (QC_SPC_SOFT | QC_SPC_HARD)) { | |
| 2473 | 2468 | check_blim = 1; |
| 2474 | 2469 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); |
| 2475 | 2470 | } |
| 2476 | 2471 | |
| 2477 | − if (di->d_fieldmask & FS_DQ_ICOUNT) { | |
| 2478 | − dm->dqb_curinodes = di->d_icount; | |
| 2472 | + if (di->d_fieldmask & QC_INO_COUNT) { | |
| 2473 | + dm->dqb_curinodes = di->d_ino_count; | |
| 2479 | 2474 | check_ilim = 1; |
| 2480 | 2475 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); |
| 2481 | 2476 | } |
| 2482 | 2477 | |
| 2483 | − if (di->d_fieldmask & FS_DQ_ISOFT) | |
| 2478 | + if (di->d_fieldmask & QC_INO_SOFT) | |
| 2484 | 2479 | dm->dqb_isoftlimit = di->d_ino_softlimit; |
| 2485 | − if (di->d_fieldmask & FS_DQ_IHARD) | |
| 2480 | + if (di->d_fieldmask & QC_INO_HARD) | |
| 2486 | 2481 | dm->dqb_ihardlimit = di->d_ino_hardlimit; |
| 2487 | − if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) { | |
| 2482 | + if (di->d_fieldmask & (QC_INO_SOFT | QC_INO_HARD)) { | |
| 2488 | 2483 | check_ilim = 1; |
| 2489 | 2484 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); |
| 2490 | 2485 | } |
| 2491 | 2486 | |
| 2492 | − if (di->d_fieldmask & FS_DQ_BTIMER) { | |
| 2493 | − dm->dqb_btime = di->d_btimer; | |
| 2487 | + if (di->d_fieldmask & QC_SPC_TIMER) { | |
| 2488 | + dm->dqb_btime = di->d_spc_timer; | |
| 2494 | 2489 | check_blim = 1; |
| 2495 | 2490 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
| 2496 | 2491 | } |
| 2497 | 2492 | |
| 2498 | − if (di->d_fieldmask & FS_DQ_ITIMER) { | |
| 2499 | − dm->dqb_itime = di->d_itimer; | |
| 2493 | + if (di->d_fieldmask & QC_INO_TIMER) { | |
| 2494 | + dm->dqb_itime = di->d_ino_timer; | |
| 2500 | 2495 | check_ilim = 1; |
| 2501 | 2496 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); |
| 2502 | 2497 | } |
| @@ -2506,7 +2501,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) · 3 unmodified lines | ||
| 2506 | 2501 | dm->dqb_curspace < dm->dqb_bsoftlimit) { |
| 2507 | 2502 | dm->dqb_btime = 0; |
| 2508 | 2503 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
| 2509 | − } else if (!(di->d_fieldmask & FS_DQ_BTIMER)) | |
| 2504 | + } else if (!(di->d_fieldmask & QC_SPC_TIMER)) | |
| 2510 | 2505 | /* Set grace only if user hasn't provided his own... */ |
| 2511 | 2506 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; |
| 2512 | 2507 | } |
| @@ -2515,7 +2510,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) · 2 unmodified lines | ||
| 2515 | 2510 | dm->dqb_curinodes < dm->dqb_isoftlimit) { |
| 2516 | 2511 | dm->dqb_itime = 0; |
| 2517 | 2512 | clear_bit(DQ_INODES_B, &dquot->dq_flags); |
| 2518 | − } else if (!(di->d_fieldmask & FS_DQ_ITIMER)) | |
| 2513 | + } else if (!(di->d_fieldmask & QC_INO_TIMER)) | |
| 2519 | 2514 | /* Set grace only if user hasn't provided his own... */ |
| 2520 | 2515 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; |
| 2521 | 2516 | } |
| @@ -2531,7 +2526,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) · 9 unmodified lines | ||
| 2531 | 2526 | } |
| 2532 | 2527 | |
| 2533 | 2528 | int dquot_set_dqblk(struct super_block *sb, struct kqid qid, |
| 2534 | − struct fs_disk_quota *di) | |
| 2529 | + struct qc_dqblk *di) | |
| 2535 | 2530 | { |
| 2536 | 2531 | struct dquot *dquot; |
| 2537 | 2532 | int rc; |
| @@ -118,17 +118,27 @@ static int quota_setinfo(struct super_block *sb, int type, void __user *addr) · 117 unmodified lines | ||
| 118 | 118 | return sb->s_qcop->set_info(sb, type, &info); |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | −static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) | |
| 121 | +static inline qsize_t qbtos(qsize_t blocks) | |
| 122 | +{ | |
| 123 | + return blocks << QIF_DQBLKSIZE_BITS; | |
| 124 | +} | |
| 125 | + | |
| 126 | +static inline qsize_t stoqb(qsize_t space) | |
| 127 | +{ | |
| 128 | + return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS; | |
| 129 | +} | |
| 130 | + | |
| 131 | +static void copy_to_if_dqblk(struct if_dqblk *dst, struct qc_dqblk *src) | |
| 122 | 132 | { |
| 123 | 133 | memset(dst, 0, sizeof(*dst)); |
| 124 | − dst->dqb_bhardlimit = src->d_blk_hardlimit; | |
| 125 | − dst->dqb_bsoftlimit = src->d_blk_softlimit; | |
| 126 | − dst->dqb_curspace = src->d_bcount; | |
| 134 | + dst->dqb_bhardlimit = stoqb(src->d_spc_hardlimit); | |
| 135 | + dst->dqb_bsoftlimit = stoqb(src->d_spc_softlimit); | |
| 136 | + dst->dqb_curspace = src->d_space; | |
| 127 | 137 | dst->dqb_ihardlimit = src->d_ino_hardlimit; |
| 128 | 138 | dst->dqb_isoftlimit = src->d_ino_softlimit; |
| 129 | − dst->dqb_curinodes = src->d_icount; | |
| 130 | − dst->dqb_btime = src->d_btimer; | |
| 131 | − dst->dqb_itime = src->d_itimer; | |
| 139 | + dst->dqb_curinodes = src->d_ino_count; | |
| 140 | + dst->dqb_btime = src->d_spc_timer; | |
| 141 | + dst->dqb_itime = src->d_ino_timer; | |
| 132 | 142 | dst->dqb_valid = QIF_ALL; |
| 133 | 143 | } |
| 134 | 144 | |
| @@ -136,7 +146,7 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, · 1 unmodified line | ||
| 136 | 146 | void __user *addr) |
| 137 | 147 | { |
| 138 | 148 | struct kqid qid; |
| 139 | − struct fs_disk_quota fdq; | |
| 149 | + struct qc_dqblk fdq; | |
| 140 | 150 | struct if_dqblk idq; |
| 141 | 151 | int ret; |
| 142 | 152 | |
| @@ -154,36 +164,36 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, · 11 unmodified lines | ||
| 154 | 164 | return 0; |
| 155 | 165 | } |
| 156 | 166 | |
| 157 | −static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src) | |
| 167 | +static void copy_from_if_dqblk(struct qc_dqblk *dst, struct if_dqblk *src) | |
| 158 | 168 | { |
| 159 | − dst->d_blk_hardlimit = src->dqb_bhardlimit; | |
| 160 | − dst->d_blk_softlimit = src->dqb_bsoftlimit; | |
| 161 | − dst->d_bcount = src->dqb_curspace; | |
| 169 | + dst->d_spc_hardlimit = qbtos(src->dqb_bhardlimit); | |
| 170 | + dst->d_spc_softlimit = qbtos(src->dqb_bsoftlimit); | |
| 171 | + dst->d_space = src->dqb_curspace; | |
| 162 | 172 | dst->d_ino_hardlimit = src->dqb_ihardlimit; |
| 163 | 173 | dst->d_ino_softlimit = src->dqb_isoftlimit; |
| 164 | − dst->d_icount = src->dqb_curinodes; | |
| 165 | − dst->d_btimer = src->dqb_btime; | |
| 166 | − dst->d_itimer = src->dqb_itime; | |
| 174 | + dst->d_ino_count = src->dqb_curinodes; | |
| 175 | + dst->d_spc_timer = src->dqb_btime; | |
| 176 | + dst->d_ino_timer = src->dqb_itime; | |
| 167 | 177 | |
| 168 | 178 | dst->d_fieldmask = 0; |
| 169 | 179 | if (src->dqb_valid & QIF_BLIMITS) |
| 170 | − dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD; | |
| 180 | + dst->d_fieldmask |= QC_SPC_SOFT | QC_SPC_HARD; | |
| 171 | 181 | if (src->dqb_valid & QIF_SPACE) |
| 172 | − dst->d_fieldmask |= FS_DQ_BCOUNT; | |
| 182 | + dst->d_fieldmask |= QC_SPACE; | |
| 173 | 183 | if (src->dqb_valid & QIF_ILIMITS) |
| 174 | − dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD; | |
| 184 | + dst->d_fieldmask |= QC_INO_SOFT | QC_INO_HARD; | |
| 175 | 185 | if (src->dqb_valid & QIF_INODES) |
| 176 | − dst->d_fieldmask |= FS_DQ_ICOUNT; | |
| 186 | + dst->d_fieldmask |= QC_INO_COUNT; | |
| 177 | 187 | if (src->dqb_valid & QIF_BTIME) |
| 178 | − dst->d_fieldmask |= FS_DQ_BTIMER; | |
| 188 | + dst->d_fieldmask |= QC_SPC_TIMER; | |
| 179 | 189 | if (src->dqb_valid & QIF_ITIME) |
| 180 | − dst->d_fieldmask |= FS_DQ_ITIMER; | |
| 190 | + dst->d_fieldmask |= QC_INO_TIMER; | |
| 181 | 191 | } |
| 182 | 192 | |
| 183 | 193 | static int quota_setquota(struct super_block *sb, int type, qid_t id, |
| 184 | 194 | void __user *addr) |
| 185 | 195 | { |
| 186 | − struct fs_disk_quota fdq; | |
| 196 | + struct qc_dqblk fdq; | |
| 187 | 197 | struct if_dqblk idq; |
| 188 | 198 | struct kqid qid; |
| 189 | 199 | |
| @@ -247,10 +257,78 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) · 57 unmodified lines | ||
| 247 | 257 | return ret; |
| 248 | 258 | } |
| 249 | 259 | |
| 260 | +/* | |
| 261 | + * XFS defines BBTOB and BTOBB macros inside fs/xfs/ and we cannot move them | |
| 262 | + * out of there as xfsprogs rely on definitions being in that header file. So | |
| 263 | + * just define same functions here for quota purposes. | |
| 264 | + */ | |
| 265 | +#define XFS_BB_SHIFT 9 | |
| 266 | + | |
| 267 | +static inline u64 quota_bbtob(u64 blocks) | |
| 268 | +{ | |
| 269 | + return blocks << XFS_BB_SHIFT; | |
| 270 | +} | |
| 271 | + | |
| 272 | +static inline u64 quota_btobb(u64 bytes) | |
| 273 | +{ | |
| 274 | + return (bytes + (1 << XFS_BB_SHIFT) - 1) >> XFS_BB_SHIFT; | |
| 275 | +} | |
| 276 | + | |
| 277 | +static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) | |
| 278 | +{ | |
| 279 | + dst->d_spc_hardlimit = quota_bbtob(src->d_blk_hardlimit); | |
| 280 | + dst->d_spc_softlimit = quota_bbtob(src->d_blk_softlimit); | |
| 281 | + dst->d_ino_hardlimit = src->d_ino_hardlimit; | |
| 282 | + dst->d_ino_softlimit = src->d_ino_softlimit; | |
| 283 | + dst->d_space = quota_bbtob(src->d_bcount); | |
| 284 | + dst->d_ino_count = src->d_icount; | |
| 285 | + dst->d_ino_timer = src->d_itimer; | |
| 286 | + dst->d_spc_timer = src->d_btimer; | |
| 287 | + dst->d_ino_warns = src->d_iwarns; | |
| 288 | + dst->d_spc_warns = src->d_bwarns; | |
| 289 | + dst->d_rt_spc_hardlimit = quota_bbtob(src->d_rtb_hardlimit); | |
| 290 | + dst->d_rt_spc_softlimit = quota_bbtob(src->d_rtb_softlimit); | |
| 291 | + dst->d_rt_space = quota_bbtob(src->d_rtbcount); | |
| 292 | + dst->d_rt_spc_timer = src->d_rtbtimer; | |
| 293 | + dst->d_rt_spc_warns = src->d_rtbwarns; | |
| 294 | + dst->d_fieldmask = 0; | |
| 295 | + if (src->d_fieldmask & FS_DQ_ISOFT) | |
| 296 | + dst->d_fieldmask |= QC_INO_SOFT; | |
| 297 | + if (src->d_fieldmask & FS_DQ_IHARD) | |
| 298 | + dst->d_fieldmask |= QC_INO_HARD; | |
| 299 | + if (src->d_fieldmask & FS_DQ_BSOFT) | |
| 300 | + dst->d_fieldmask |= QC_SPC_SOFT; | |
| 301 | + if (src->d_fieldmask & FS_DQ_BHARD) | |
| 302 | + dst->d_fieldmask |= QC_SPC_HARD; | |
| 303 | + if (src->d_fieldmask & FS_DQ_RTBSOFT) | |
| 304 | + dst->d_fieldmask |= QC_RT_SPC_SOFT; | |
| 305 | + if (src->d_fieldmask & FS_DQ_RTBHARD) | |
| 306 | + dst->d_fieldmask |= QC_RT_SPC_HARD; | |
| 307 | + if (src->d_fieldmask & FS_DQ_BTIMER) | |
| 308 | + dst->d_fieldmask |= QC_SPC_TIMER; | |
| 309 | + if (src->d_fieldmask & FS_DQ_ITIMER) | |
| 310 | + dst->d_fieldmask |= QC_INO_TIMER; | |
| 311 | + if (src->d_fieldmask & FS_DQ_RTBTIMER) | |
| 312 | + dst->d_fieldmask |= QC_RT_SPC_TIMER; | |
| 313 | + if (src->d_fieldmask & FS_DQ_BWARNS) | |
| 314 | + dst->d_fieldmask |= QC_SPC_WARNS; | |
| 315 | + if (src->d_fieldmask & FS_DQ_IWARNS) | |
| 316 | + dst->d_fieldmask |= QC_INO_WARNS; | |
| 317 | + if (src->d_fieldmask & FS_DQ_RTBWARNS) | |
| 318 | + dst->d_fieldmask |= QC_RT_SPC_WARNS; | |
| 319 | + if (src->d_fieldmask & FS_DQ_BCOUNT) | |
| 320 | + dst->d_fieldmask |= QC_SPACE; | |
| 321 | + if (src->d_fieldmask & FS_DQ_ICOUNT) | |
| 322 | + dst->d_fieldmask |= QC_INO_COUNT; | |
| 323 | + if (src->d_fieldmask & FS_DQ_RTBCOUNT) | |
| 324 | + dst->d_fieldmask |= QC_RT_SPACE; | |
| 325 | +} | |
| 326 | + | |
| 250 | 327 | static int quota_setxquota(struct super_block *sb, int type, qid_t id, |
| 251 | 328 | void __user *addr) |
| 252 | 329 | { |
| 253 | 330 | struct fs_disk_quota fdq; |
| 331 | + struct qc_dqblk qdq; | |
| 254 | 332 | struct kqid qid; |
| 255 | 333 | |
| 256 | 334 | if (copy_from_user(&fdq, addr, sizeof(fdq))) |
| @@ -260,13 +338,44 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, · 3 unmodified lines | ||
| 260 | 338 | qid = make_kqid(current_user_ns(), type, id); |
| 261 | 339 | if (!qid_valid(qid)) |
| 262 | 340 | return -EINVAL; |
| 263 | − return sb->s_qcop->set_dqblk(sb, qid, &fdq); | |
| 341 | + copy_from_xfs_dqblk(&qdq, &fdq); | |
| 342 | + return sb->s_qcop->set_dqblk(sb, qid, &qdq); | |
| 343 | +} | |
| 344 | + | |
| 345 | +static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src, | |
| 346 | + int type, qid_t id) | |
| 347 | +{ | |
| 348 | + memset(dst, 0, sizeof(*dst)); | |
| 349 | + dst->d_version = FS_DQUOT_VERSION; | |
| 350 | + dst->d_id = id; | |
| 351 | + if (type == USRQUOTA) | |
| 352 | + dst->d_flags = FS_USER_QUOTA; | |
| 353 | + else if (type == PRJQUOTA) | |
| 354 | + dst->d_flags = FS_PROJ_QUOTA; | |
| 355 | + else | |
| 356 | + dst->d_flags = FS_GROUP_QUOTA; | |
| 357 | + dst->d_blk_hardlimit = quota_btobb(src->d_spc_hardlimit); | |
| 358 | + dst->d_blk_softlimit = quota_btobb(src->d_spc_softlimit); | |
| 359 | + dst->d_ino_hardlimit = src->d_ino_hardlimit; | |
| 360 | + dst->d_ino_softlimit = src->d_ino_softlimit; | |
| 361 | + dst->d_bcount = quota_btobb(src->d_space); | |
| 362 | + dst->d_icount = src->d_ino_count; | |
| 363 | + dst->d_itimer = src->d_ino_timer; | |
| 364 | + dst->d_btimer = src->d_spc_timer; | |
| 365 | + dst->d_iwarns = src->d_ino_warns; | |
| 366 | + dst->d_bwarns = src->d_spc_warns; | |
| 367 | + dst->d_rtb_hardlimit = quota_btobb(src->d_rt_spc_hardlimit); | |
| 368 | + dst->d_rtb_softlimit = quota_btobb(src->d_rt_spc_softlimit); | |
| 369 | + dst->d_rtbcount = quota_btobb(src->d_rt_space); | |
| 370 | + dst->d_rtbtimer = src->d_rt_spc_timer; | |
| 371 | + dst->d_rtbwarns = src->d_rt_spc_warns; | |
| 264 | 372 | } |
| 265 | 373 | |
| 266 | 374 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, |
| 267 | 375 | void __user *addr) |
| 268 | 376 | { |
| 269 | 377 | struct fs_disk_quota fdq; |
| 378 | + struct qc_dqblk qdq; | |
| 270 | 379 | struct kqid qid; |
| 271 | 380 | int ret; |
| 272 | 381 | |
| @@ -275,8 +384,11 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id, · 2 unmodified lines | ||
| 275 | 384 | qid = make_kqid(current_user_ns(), type, id); |
| 276 | 385 | if (!qid_valid(qid)) |
| 277 | 386 | return -EINVAL; |
| 278 | − ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); | |
| 279 | − if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) | |
| 387 | + ret = sb->s_qcop->get_dqblk(sb, qid, &qdq); | |
| 388 | + if (ret) | |
| 389 | + return ret; | |
| 390 | + copy_to_xfs_dqblk(&fdq, &qdq, type, id); | |
| 391 | + if (copy_to_user(addr, &fdq, sizeof(fdq))) | |
| 280 | 392 | return -EFAULT; |
| 281 | 393 | return ret; |
| 282 | 394 | } |
| @@ -224,7 +224,7 @@ out: · 223 unmodified lines | ||
| 224 | 224 | static int udf_release_file(struct inode *inode, struct file *filp) |
| 225 | 225 | { |
| 226 | 226 | if (filp->f_mode & FMODE_WRITE && |
| 227 | − atomic_read(&inode->i_writecount) > 1) { | |
| 227 | + atomic_read(&inode->i_writecount) == 1) { | |
| 228 | 228 | /* |
| 229 | 229 | * Grab i_mutex to avoid races with writes changing i_size |
| 230 | 230 | * while we are running. |
| @@ -166,9 +166,9 @@ extern void xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint); · 165 unmodified lines | ||
| 166 | 166 | /* quota ops */ |
| 167 | 167 | extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); |
| 168 | 168 | extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t, |
| 169 | − uint, struct fs_disk_quota *); | |
| 169 | + uint, struct qc_dqblk *); | |
| 170 | 170 | extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, |
| 171 | − struct fs_disk_quota *); | |
| 171 | + struct qc_dqblk *); | |
| 172 | 172 | extern int xfs_qm_scall_getqstat(struct xfs_mount *, |
| 173 | 173 | struct fs_quota_stat *); |
| 174 | 174 | extern int xfs_qm_scall_getqstatv(struct xfs_mount *, |
| @@ -39,7 +39,6 @@ STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); · 38 unmodified lines | ||
| 39 | 39 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, |
| 40 | 40 | uint); |
| 41 | 41 | STATIC uint xfs_qm_export_flags(uint); |
| 42 | −STATIC uint xfs_qm_export_qtype_flags(uint); | |
| 43 | 42 | |
| 44 | 43 | /* |
| 45 | 44 | * Turn off quota accounting and/or enforcement for all udquots and/or |
| @@ -573,8 +572,8 @@ xfs_qm_scall_getqstatv( · 527 unmodified lines | ||
| 573 | 572 | return 0; |
| 574 | 573 | } |
| 575 | 574 | |
| 576 | −#define XFS_DQ_MASK \ | |
| 577 | − (FS_DQ_LIMIT_MASK | FS_DQ_TIMER_MASK | FS_DQ_WARNS_MASK) | |
| 575 | +#define XFS_QC_MASK \ | |
| 576 | + (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) | |
| 578 | 577 | |
| 579 | 578 | /* |
| 580 | 579 | * Adjust quota limits, and start/stop timers accordingly. |
| @@ -584,7 +583,7 @@ xfs_qm_scall_setqlim( · 3 unmodified lines | ||
| 584 | 583 | struct xfs_mount *mp, |
| 585 | 584 | xfs_dqid_t id, |
| 586 | 585 | uint type, |
| 587 | − fs_disk_quota_t *newlim) | |
| 586 | + struct qc_dqblk *newlim) | |
| 588 | 587 | { |
| 589 | 588 | struct xfs_quotainfo *q = mp->m_quotainfo; |
| 590 | 589 | struct xfs_disk_dquot *ddq; |
| @@ -593,9 +592,9 @@ xfs_qm_scall_setqlim( · 2 unmodified lines | ||
| 593 | 592 | int error; |
| 594 | 593 | xfs_qcnt_t hard, soft; |
| 595 | 594 | |
| 596 | − if (newlim->d_fieldmask & ~XFS_DQ_MASK) | |
| 595 | + if (newlim->d_fieldmask & ~XFS_QC_MASK) | |
| 597 | 596 | return -EINVAL; |
| 598 | − if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0) | |
| 597 | + if ((newlim->d_fieldmask & XFS_QC_MASK) == 0) | |
| 599 | 598 | return 0; |
| 600 | 599 | |
| 601 | 600 | /* |
| @@ -633,11 +632,11 @@ xfs_qm_scall_setqlim( · 31 unmodified lines | ||
| 633 | 632 | /* |
| 634 | 633 | * Make sure that hardlimits are >= soft limits before changing. |
| 635 | 634 | */ |
| 636 | − hard = (newlim->d_fieldmask & FS_DQ_BHARD) ? | |
| 637 | − (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_blk_hardlimit) : | |
| 635 | + hard = (newlim->d_fieldmask & QC_SPC_HARD) ? | |
| 636 | + (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : | |
| 638 | 637 | be64_to_cpu(ddq->d_blk_hardlimit); |
| 639 | − soft = (newlim->d_fieldmask & FS_DQ_BSOFT) ? | |
| 640 | − (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_blk_softlimit) : | |
| 638 | + soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? | |
| 639 | + (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : | |
| 641 | 640 | be64_to_cpu(ddq->d_blk_softlimit); |
| 642 | 641 | if (hard == 0 || hard >= soft) { |
| 643 | 642 | ddq->d_blk_hardlimit = cpu_to_be64(hard); |
| @@ -650,11 +649,11 @@ xfs_qm_scall_setqlim( · 6 unmodified lines | ||
| 650 | 649 | } else { |
| 651 | 650 | xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); |
| 652 | 651 | } |
| 653 | − hard = (newlim->d_fieldmask & FS_DQ_RTBHARD) ? | |
| 654 | − (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_rtb_hardlimit) : | |
| 652 | + hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? | |
| 653 | + (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : | |
| 655 | 654 | be64_to_cpu(ddq->d_rtb_hardlimit); |
| 656 | − soft = (newlim->d_fieldmask & FS_DQ_RTBSOFT) ? | |
| 657 | − (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_rtb_softlimit) : | |
| 655 | + soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? | |
| 656 | + (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : | |
| 658 | 657 | be64_to_cpu(ddq->d_rtb_softlimit); |
| 659 | 658 | if (hard == 0 || hard >= soft) { |
| 660 | 659 | ddq->d_rtb_hardlimit = cpu_to_be64(hard); |
| @@ -667,10 +666,10 @@ xfs_qm_scall_setqlim( · 6 unmodified lines | ||
| 667 | 666 | xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); |
| 668 | 667 | } |
| 669 | 668 | |
| 670 | − hard = (newlim->d_fieldmask & FS_DQ_IHARD) ? | |
| 669 | + hard = (newlim->d_fieldmask & QC_INO_HARD) ? | |
| 671 | 670 | (xfs_qcnt_t) newlim->d_ino_hardlimit : |
| 672 | 671 | be64_to_cpu(ddq->d_ino_hardlimit); |
| 673 | − soft = (newlim->d_fieldmask & FS_DQ_ISOFT) ? | |
| 672 | + soft = (newlim->d_fieldmask & QC_INO_SOFT) ? | |
| 674 | 673 | (xfs_qcnt_t) newlim->d_ino_softlimit : |
| 675 | 674 | be64_to_cpu(ddq->d_ino_softlimit); |
| 676 | 675 | if (hard == 0 || hard >= soft) { |
| @@ -687,12 +686,12 @@ xfs_qm_scall_setqlim( · 10 unmodified lines | ||
| 687 | 686 | /* |
| 688 | 687 | * Update warnings counter(s) if requested |
| 689 | 688 | */ |
| 690 | − if (newlim->d_fieldmask & FS_DQ_BWARNS) | |
| 691 | − ddq->d_bwarns = cpu_to_be16(newlim->d_bwarns); | |
| 692 | − if (newlim->d_fieldmask & FS_DQ_IWARNS) | |
| 693 | − ddq->d_iwarns = cpu_to_be16(newlim->d_iwarns); | |
| 694 | − if (newlim->d_fieldmask & FS_DQ_RTBWARNS) | |
| 695 | − ddq->d_rtbwarns = cpu_to_be16(newlim->d_rtbwarns); | |
| 689 | + if (newlim->d_fieldmask & QC_SPC_WARNS) | |
| 690 | + ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns); | |
| 691 | + if (newlim->d_fieldmask & QC_INO_WARNS) | |
| 692 | + ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns); | |
| 693 | + if (newlim->d_fieldmask & QC_RT_SPC_WARNS) | |
| 694 | + ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns); | |
| 696 | 695 | |
| 697 | 696 | if (id == 0) { |
| 698 | 697 | /* |
| @@ -702,24 +701,24 @@ xfs_qm_scall_setqlim( · 3 unmodified lines | ||
| 702 | 701 | * soft and hard limit values (already done, above), and |
| 703 | 702 | * for warnings. |
| 704 | 703 | */ |
| 705 | − if (newlim->d_fieldmask & FS_DQ_BTIMER) { | |
| 706 | − q->qi_btimelimit = newlim->d_btimer; | |
| 707 | − ddq->d_btimer = cpu_to_be32(newlim->d_btimer); | |
| 704 | + if (newlim->d_fieldmask & QC_SPC_TIMER) { | |
| 705 | + q->qi_btimelimit = newlim->d_spc_timer; | |
| 706 | + ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer); | |
| 708 | 707 | } |
| 709 | − if (newlim->d_fieldmask & FS_DQ_ITIMER) { | |
| 710 | − q->qi_itimelimit = newlim->d_itimer; | |
| 711 | − ddq->d_itimer = cpu_to_be32(newlim->d_itimer); | |
| 708 | + if (newlim->d_fieldmask & QC_INO_TIMER) { | |
| 709 | + q->qi_itimelimit = newlim->d_ino_timer; | |
| 710 | + ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer); | |
| 712 | 711 | } |
| 713 | − if (newlim->d_fieldmask & FS_DQ_RTBTIMER) { | |
| 714 | − q->qi_rtbtimelimit = newlim->d_rtbtimer; | |
| 715 | − ddq->d_rtbtimer = cpu_to_be32(newlim->d_rtbtimer); | |
| 712 | + if (newlim->d_fieldmask & QC_RT_SPC_TIMER) { | |
| 713 | + q->qi_rtbtimelimit = newlim->d_rt_spc_timer; | |
| 714 | + ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer); | |
| 716 | 715 | } |
| 717 | − if (newlim->d_fieldmask & FS_DQ_BWARNS) | |
| 718 | − q->qi_bwarnlimit = newlim->d_bwarns; | |
| 719 | − if (newlim->d_fieldmask & FS_DQ_IWARNS) | |
| 720 | − q->qi_iwarnlimit = newlim->d_iwarns; | |
| 721 | − if (newlim->d_fieldmask & FS_DQ_RTBWARNS) | |
| 722 | − q->qi_rtbwarnlimit = newlim->d_rtbwarns; | |
| 716 | + if (newlim->d_fieldmask & QC_SPC_WARNS) | |
| 717 | + q->qi_bwarnlimit = newlim->d_spc_warns; | |
| 718 | + if (newlim->d_fieldmask & QC_INO_WARNS) | |
| 719 | + q->qi_iwarnlimit = newlim->d_ino_warns; | |
| 720 | + if (newlim->d_fieldmask & QC_RT_SPC_WARNS) | |
| 721 | + q->qi_rtbwarnlimit = newlim->d_rt_spc_warns; | |
| 723 | 722 | } else { |
| 724 | 723 | /* |
| 725 | 724 | * If the user is now over quota, start the timelimit. |
| @@ -824,7 +823,7 @@ xfs_qm_scall_getquota( · 98 unmodified lines | ||
| 824 | 823 | struct xfs_mount *mp, |
| 825 | 824 | xfs_dqid_t id, |
| 826 | 825 | uint type, |
| 827 | − struct fs_disk_quota *dst) | |
| 826 | + struct qc_dqblk *dst) | |
| 828 | 827 | { |
| 829 | 828 | struct xfs_dquot *dqp; |
| 830 | 829 | int error; |
| @@ -848,28 +847,25 @@ xfs_qm_scall_getquota( · 17 unmodified lines | ||
| 848 | 847 | } |
| 849 | 848 | |
| 850 | 849 | memset(dst, 0, sizeof(*dst)); |
| 851 | − dst->d_version = FS_DQUOT_VERSION; | |
| 852 | − dst->d_flags = xfs_qm_export_qtype_flags(dqp->q_core.d_flags); | |
| 853 | − dst->d_id = be32_to_cpu(dqp->q_core.d_id); | |
| 854 | − dst->d_blk_hardlimit = | |
| 855 | − XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); | |
| 856 | − dst->d_blk_softlimit = | |
| 857 | − XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); | |
| 850 | + dst->d_spc_hardlimit = | |
| 851 | + XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); | |
| 852 | + dst->d_spc_softlimit = | |
| 853 | + XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); | |
| 858 | 854 | dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); |
| 859 | 855 | dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); |
| 860 | − dst->d_bcount = XFS_FSB_TO_BB(mp, dqp->q_res_bcount); | |
| 861 | − dst->d_icount = dqp->q_res_icount; | |
| 862 | − dst->d_btimer = be32_to_cpu(dqp->q_core.d_btimer); | |
| 863 | − dst->d_itimer = be32_to_cpu(dqp->q_core.d_itimer); | |
| 864 | − dst->d_iwarns = be16_to_cpu(dqp->q_core.d_iwarns); | |
| 865 | − dst->d_bwarns = be16_to_cpu(dqp->q_core.d_bwarns); | |
| 866 | − dst->d_rtb_hardlimit = | |
| 867 | − XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); | |
| 868 | − dst->d_rtb_softlimit = | |
| 869 | − XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); | |
| 870 | − dst->d_rtbcount = XFS_FSB_TO_BB(mp, dqp->q_res_rtbcount); | |
| 871 | − dst->d_rtbtimer = be32_to_cpu(dqp->q_core.d_rtbtimer); | |
| 872 | − dst->d_rtbwarns = be16_to_cpu(dqp->q_core.d_rtbwarns); | |
| 856 | + dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount); | |
| 857 | + dst->d_ino_count = dqp->q_res_icount; | |
| 858 | + dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); | |
| 859 | + dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); | |
| 860 | + dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); | |
| 861 | + dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); | |
| 862 | + dst->d_rt_spc_hardlimit = | |
| 863 | + XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); | |
| 864 | + dst->d_rt_spc_softlimit = | |
| 865 | + XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); | |
| 866 | + dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount); | |
| 867 | + dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); | |
| 868 | + dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); | |
| 873 | 869 | |
| 874 | 870 | /* |
| 875 | 871 | * Internally, we don't reset all the timers when quota enforcement |
| @@ -882,23 +878,23 @@ xfs_qm_scall_getquota( · 6 unmodified lines | ||
| 882 | 878 | dqp->q_core.d_flags == XFS_DQ_GROUP) || |
| 883 | 879 | (!XFS_IS_PQUOTA_ENFORCED(mp) && |
| 884 | 880 | dqp->q_core.d_flags == XFS_DQ_PROJ)) { |
| 885 | − dst->d_btimer = 0; | |
| 886 | − dst->d_itimer = 0; | |
| 887 | − dst->d_rtbtimer = 0; | |
| 881 | + dst->d_spc_timer = 0; | |
| 882 | + dst->d_ino_timer = 0; | |
| 883 | + dst->d_rt_spc_timer = 0; | |
| 888 | 884 | } |
| 889 | 885 | |
| 890 | 886 | #ifdef DEBUG |
| 891 | − if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) || | |
| 892 | − (XFS_IS_GQUOTA_ENFORCED(mp) && dst->d_flags == FS_GROUP_QUOTA) || | |
| 893 | − (XFS_IS_PQUOTA_ENFORCED(mp) && dst->d_flags == FS_PROJ_QUOTA)) && | |
| 894 | − dst->d_id != 0) { | |
| 895 | − if ((dst->d_bcount > dst->d_blk_softlimit) && | |
| 896 | − (dst->d_blk_softlimit > 0)) { | |
| 897 | − ASSERT(dst->d_btimer != 0); | |
| 887 | + if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || | |
| 888 | + (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || | |
| 889 | + (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && | |
| 890 | + id != 0) { | |
| 891 | + if ((dst->d_space > dst->d_spc_softlimit) && | |
| 892 | + (dst->d_spc_softlimit > 0)) { | |
| 893 | + ASSERT(dst->d_spc_timer != 0); | |
| 898 | 894 | } |
| 899 | − if ((dst->d_icount > dst->d_ino_softlimit) && | |
| 895 | + if ((dst->d_ino_count > dst->d_ino_softlimit) && | |
| 900 | 896 | (dst->d_ino_softlimit > 0)) { |
| 901 | − ASSERT(dst->d_itimer != 0); | |
| 897 | + ASSERT(dst->d_ino_timer != 0); | |
| 902 | 898 | } |
| 903 | 899 | } |
| 904 | 900 | #endif |
| @@ -907,26 +903,6 @@ out_put: · 2 unmodified lines | ||
| 907 | 903 | return error; |
| 908 | 904 | } |
| 909 | 905 | |
| 910 | −STATIC uint | |
| 911 | −xfs_qm_export_qtype_flags( | |
| 912 | − uint flags) | |
| 913 | −{ | |
| 914 | − /* | |
| 915 | − * Can't be more than one, or none. | |
| 916 | − */ | |
| 917 | − ASSERT((flags & (FS_PROJ_QUOTA | FS_USER_QUOTA)) != | |
| 918 | − (FS_PROJ_QUOTA | FS_USER_QUOTA)); | |
| 919 | − ASSERT((flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)) != | |
| 920 | − (FS_PROJ_QUOTA | FS_GROUP_QUOTA)); | |
| 921 | − ASSERT((flags & (FS_USER_QUOTA | FS_GROUP_QUOTA)) != | |
| 922 | − (FS_USER_QUOTA | FS_GROUP_QUOTA)); | |
| 923 | − ASSERT((flags & (FS_PROJ_QUOTA|FS_USER_QUOTA|FS_GROUP_QUOTA)) != 0); | |
| 924 | − | |
| 925 | − return (flags & XFS_DQ_USER) ? | |
| 926 | − FS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? | |
| 927 | − FS_PROJ_QUOTA : FS_GROUP_QUOTA; | |
| 928 | −} | |
| 929 | − | |
| 930 | 906 | STATIC uint |
| 931 | 907 | xfs_qm_export_flags( |
| 932 | 908 | uint flags) |
| @@ -131,7 +131,7 @@ STATIC int · 130 unmodified lines | ||
| 131 | 131 | xfs_fs_get_dqblk( |
| 132 | 132 | struct super_block *sb, |
| 133 | 133 | struct kqid qid, |
| 134 | − struct fs_disk_quota *fdq) | |
| 134 | + struct qc_dqblk *qdq) | |
| 135 | 135 | { |
| 136 | 136 | struct xfs_mount *mp = XFS_M(sb); |
| 137 | 137 | |
| @@ -141,14 +141,14 @@ xfs_fs_get_dqblk( · 3 unmodified lines | ||
| 141 | 141 | return -ESRCH; |
| 142 | 142 | |
| 143 | 143 | return xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid), |
| 144 | − xfs_quota_type(qid.type), fdq); | |
| 144 | + xfs_quota_type(qid.type), qdq); | |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | 147 | STATIC int |
| 148 | 148 | xfs_fs_set_dqblk( |
| 149 | 149 | struct super_block *sb, |
| 150 | 150 | struct kqid qid, |
| 151 | − struct fs_disk_quota *fdq) | |
| 151 | + struct qc_dqblk *qdq) | |
| 152 | 152 | { |
| 153 | 153 | struct xfs_mount *mp = XFS_M(sb); |
| 154 | 154 | |
| @@ -160,7 +160,7 @@ xfs_fs_set_dqblk( · 5 unmodified lines | ||
| 160 | 160 | return -ESRCH; |
| 161 | 161 | |
| 162 | 162 | return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid), |
| 163 | − xfs_quota_type(qid.type), fdq); | |
| 163 | + xfs_quota_type(qid.type), qdq); | |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | 166 | const struct quotactl_ops xfs_quotactl_operations = { |
| @@ -228,7 +228,9 @@ struct i2c_client { · 227 unmodified lines | ||
| 228 | 228 | struct device dev; /* the device structure */ |
| 229 | 229 | int irq; /* irq issued by device */ |
| 230 | 230 | struct list_head detected; |
| 231 | +#if IS_ENABLED(CONFIG_I2C_SLAVE) | |
| 231 | 232 | i2c_slave_cb_t slave_cb; /* callback for slave mode */ |
| 233 | +#endif | |
| 232 | 234 | }; |
| 233 | 235 | #define to_i2c_client(d) container_of(d, struct i2c_client, dev) |
| 234 | 236 | |
| @@ -253,6 +255,7 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) · 18 unmodified lines | ||
| 253 | 255 | |
| 254 | 256 | /* I2C slave support */ |
| 255 | 257 | |
| 258 | +#if IS_ENABLED(CONFIG_I2C_SLAVE) | |
| 256 | 259 | enum i2c_slave_event { |
| 257 | 260 | I2C_SLAVE_REQ_READ_START, |
| 258 | 261 | I2C_SLAVE_REQ_READ_END, |
| @@ -269,6 +272,7 @@ static inline int i2c_slave_event(struct i2c_client *client, · 10 unmodified lines | ||
| 269 | 272 | { |
| 270 | 273 | return client->slave_cb(client, event, val); |
| 271 | 274 | } |
| 275 | +#endif | |
| 272 | 276 | |
| 273 | 277 | /** |
| 274 | 278 | * struct i2c_board_info - template for device creation |
| @@ -404,8 +408,10 @@ struct i2c_algorithm { · 129 unmodified lines | ||
| 404 | 408 | /* To determine what the adapter supports */ |
| 405 | 409 | u32 (*functionality) (struct i2c_adapter *); |
| 406 | 410 | |
| 411 | +#if IS_ENABLED(CONFIG_I2C_SLAVE) | |
| 407 | 412 | int (*reg_slave)(struct i2c_client *client); |
| 408 | 413 | int (*unreg_slave)(struct i2c_client *client); |
| 414 | +#endif | |
| 409 | 415 | }; |
| 410 | 416 | |
| 411 | 417 | /** |
| @@ -176,7 +176,7 @@ extern int _cond_resched(void); · 175 unmodified lines | ||
| 176 | 176 | */ |
| 177 | 177 | # define might_sleep() \ |
| 178 | 178 | do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) |
| 179 | −# define sched_annotate_sleep() __set_current_state(TASK_RUNNING) | |
| 179 | +# define sched_annotate_sleep() (current->task_state_change = 0) | |
| 180 | 180 | #else |
| 181 | 181 | static inline void ___might_sleep(const char *file, int line, |
| 182 | 182 | int preempt_offset) { } |
| @@ -59,6 +59,7 @@ enum s2mps13_reg { · 58 unmodified lines | ||
| 59 | 59 | S2MPS13_REG_B6CTRL, |
| 60 | 60 | S2MPS13_REG_B6OUT, |
| 61 | 61 | S2MPS13_REG_B7CTRL, |
| 62 | + S2MPS13_REG_B7SW, | |
| 62 | 63 | S2MPS13_REG_B7OUT, |
| 63 | 64 | S2MPS13_REG_B8CTRL, |
| 64 | 65 | S2MPS13_REG_B8OUT, |
| @@ -102,6 +103,7 @@ enum s2mps13_reg { · 37 unmodified lines | ||
| 102 | 103 | S2MPS13_REG_L26CTRL, |
| 103 | 104 | S2MPS13_REG_L27CTRL, |
| 104 | 105 | S2MPS13_REG_L28CTRL, |
| 106 | + S2MPS13_REG_L29CTRL, | |
| 105 | 107 | S2MPS13_REG_L30CTRL, |
| 106 | 108 | S2MPS13_REG_L31CTRL, |
| 107 | 109 | S2MPS13_REG_L32CTRL, |
| @@ -1070,6 +1070,7 @@ static inline int page_mapped(struct page *page) · 1069 unmodified lines | ||
| 1070 | 1070 | #define VM_FAULT_WRITE 0x0008 /* Special case for get_user_pages */ |
| 1071 | 1071 | #define VM_FAULT_HWPOISON 0x0010 /* Hit poisoned small page */ |
| 1072 | 1072 | #define VM_FAULT_HWPOISON_LARGE 0x0020 /* Hit poisoned large page. Index encoded in upper bits */ |
| 1073 | +#define VM_FAULT_SIGSEGV 0x0040 | |
| 1073 | 1074 | |
| 1074 | 1075 | #define VM_FAULT_NOPAGE 0x0100 /* ->fault installed the pte, not return page */ |
| 1075 | 1076 | #define VM_FAULT_LOCKED 0x0200 /* ->fault locked the returned page */ |
| @@ -1078,8 +1079,9 @@ static inline int page_mapped(struct page *page) · 2 unmodified lines | ||
| 1078 | 1079 | |
| 1079 | 1080 | #define VM_FAULT_HWPOISON_LARGE_MASK 0xf000 /* encodes hpage index for large hwpoison */ |
| 1080 | 1081 | |
| 1081 | −#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | \ | |
| 1082 | − VM_FAULT_FALLBACK | VM_FAULT_HWPOISON_LARGE) | |
| 1082 | +#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | \ | |
| 1083 | + VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE | \ | |
| 1084 | + VM_FAULT_FALLBACK) | |
| 1083 | 1085 | |
| 1084 | 1086 | /* Encode hstate index for a hwpoisoned large page */ |
| 1085 | 1087 | #define VM_FAULT_SET_HINDEX(x) ((x) << 12) |
| @@ -85,11 +85,6 @@ static inline void oom_killer_enable(void) · 84 unmodified lines | ||
| 85 | 85 | oom_killer_disabled = false; |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | −static inline bool oom_gfp_allowed(gfp_t gfp_mask) | |
| 89 | −{ | |
| 90 | − return (gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY); | |
| 91 | −} | |
| 92 | − | |
| 93 | 88 | extern struct task_struct *find_lock_task_mm(struct task_struct *p); |
| 94 | 89 | |
| 95 | 90 | static inline bool task_will_free_mem(struct task_struct *task) |
| @@ -450,11 +450,6 @@ struct perf_event { · 449 unmodified lines | ||
| 450 | 450 | #endif /* CONFIG_PERF_EVENTS */ |
| 451 | 451 | }; |
| 452 | 452 | |
| 453 | −enum perf_event_context_type { | |
| 454 | − task_context, | |
| 455 | − cpu_context, | |
| 456 | −}; | |
| 457 | − | |
| 458 | 453 | /** |
| 459 | 454 | * struct perf_event_context - event context structure |
| 460 | 455 | * |
| @@ -462,7 +457,6 @@ enum perf_event_context_type { · 1 unmodified line | ||
| 462 | 457 | */ |
| 463 | 458 | struct perf_event_context { |
| 464 | 459 | struct pmu *pmu; |
| 465 | − enum perf_event_context_type type; | |
| 466 | 460 | /* |
| 467 | 461 | * Protect the states of the events in the list, |
| 468 | 462 | * nr_active, and the list: |
| @@ -10,9 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | extern const char linux_banner[]; |
| 11 | 11 | extern const char linux_proc_banner[]; |
| 12 | 12 | |
| 13 | −extern char *log_buf_addr_get(void); | |
| 14 | −extern u32 log_buf_len_get(void); | |
| 15 | − | |
| 16 | 13 | static inline int printk_get_level(const char *buffer) |
| 17 | 14 | { |
| 18 | 15 | if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { |
| @@ -163,6 +160,8 @@ extern int kptr_restrict; · 144 unmodified lines | ||
| 163 | 160 | |
| 164 | 161 | extern void wake_up_klogd(void); |
| 165 | 162 | |
| 163 | +char *log_buf_addr_get(void); | |
| 164 | +u32 log_buf_len_get(void); | |
| 166 | 165 | void log_buf_kexec_setup(void); |
| 167 | 166 | void __init setup_log_buf(int early); |
| 168 | 167 | void dump_stack_set_arch_desc(const char *fmt, ...); |
| @@ -198,6 +197,16 @@ static inline void wake_up_klogd(void) · 29 unmodified lines | ||
| 198 | 197 | { |
| 199 | 198 | } |
| 200 | 199 | |
| 200 | +static inline char *log_buf_addr_get(void) | |
| 201 | +{ | |
| 202 | + return NULL; | |
| 203 | +} | |
| 204 | + | |
| 205 | +static inline u32 log_buf_len_get(void) | |
| 206 | +{ | |
| 207 | + return 0; | |
| 208 | +} | |
| 209 | + | |
| 201 | 210 | static inline void log_buf_kexec_setup(void) |
| 202 | 211 | { |
| 203 | 212 | } |
| @@ -321,6 +321,49 @@ struct dquot_operations { · 320 unmodified lines | ||
| 321 | 321 | |
| 322 | 322 | struct path; |
| 323 | 323 | |
| 324 | +/* Structure for communicating via ->get_dqblk() & ->set_dqblk() */ | |
| 325 | +struct qc_dqblk { | |
| 326 | + int d_fieldmask; /* mask of fields to change in ->set_dqblk() */ | |
| 327 | + u64 d_spc_hardlimit; /* absolute limit on used space */ | |
| 328 | + u64 d_spc_softlimit; /* preferred limit on used space */ | |
| 329 | + u64 d_ino_hardlimit; /* maximum # allocated inodes */ | |
| 330 | + u64 d_ino_softlimit; /* preferred inode limit */ | |
| 331 | + u64 d_space; /* Space owned by the user */ | |
| 332 | + u64 d_ino_count; /* # inodes owned by the user */ | |
| 333 | + s64 d_ino_timer; /* zero if within inode limits */ | |
| 334 | + /* if not, we refuse service */ | |
| 335 | + s64 d_spc_timer; /* similar to above; for space */ | |
| 336 | + int d_ino_warns; /* # warnings issued wrt num inodes */ | |
| 337 | + int d_spc_warns; /* # warnings issued wrt used space */ | |
| 338 | + u64 d_rt_spc_hardlimit; /* absolute limit on realtime space */ | |
| 339 | + u64 d_rt_spc_softlimit; /* preferred limit on RT space */ | |
| 340 | + u64 d_rt_space; /* realtime space owned */ | |
| 341 | + s64 d_rt_spc_timer; /* similar to above; for RT space */ | |
| 342 | + int d_rt_spc_warns; /* # warnings issued wrt RT space */ | |
| 343 | +}; | |
| 344 | + | |
| 345 | +/* Field specifiers for ->set_dqblk() in struct qc_dqblk */ | |
| 346 | +#define QC_INO_SOFT (1<<0) | |
| 347 | +#define QC_INO_HARD (1<<1) | |
| 348 | +#define QC_SPC_SOFT (1<<2) | |
| 349 | +#define QC_SPC_HARD (1<<3) | |
| 350 | +#define QC_RT_SPC_SOFT (1<<4) | |
| 351 | +#define QC_RT_SPC_HARD (1<<5) | |
| 352 | +#define QC_LIMIT_MASK (QC_INO_SOFT | QC_INO_HARD | QC_SPC_SOFT | QC_SPC_HARD | \ | |
| 353 | + QC_RT_SPC_SOFT | QC_RT_SPC_HARD) | |
| 354 | +#define QC_SPC_TIMER (1<<6) | |
| 355 | +#define QC_INO_TIMER (1<<7) | |
| 356 | +#define QC_RT_SPC_TIMER (1<<8) | |
| 357 | +#define QC_TIMER_MASK (QC_SPC_TIMER | QC_INO_TIMER | QC_RT_SPC_TIMER) | |
| 358 | +#define QC_SPC_WARNS (1<<9) | |
| 359 | +#define QC_INO_WARNS (1<<10) | |
| 360 | +#define QC_RT_SPC_WARNS (1<<11) | |
| 361 | +#define QC_WARNS_MASK (QC_SPC_WARNS | QC_INO_WARNS | QC_RT_SPC_WARNS) | |
| 362 | +#define QC_SPACE (1<<12) | |
| 363 | +#define QC_INO_COUNT (1<<13) | |
| 364 | +#define QC_RT_SPACE (1<<14) | |
| 365 | +#define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE) | |
| 366 | + | |
| 324 | 367 | /* Operations handling requests from userspace */ |
| 325 | 368 | struct quotactl_ops { |
| 326 | 369 | int (*quota_on)(struct super_block *, int, int, struct path *); |
| @@ -329,8 +372,8 @@ struct quotactl_ops { · 2 unmodified lines | ||
| 329 | 372 | int (*quota_sync)(struct super_block *, int); |
| 330 | 373 | int (*get_info)(struct super_block *, int, struct if_dqinfo *); |
| 331 | 374 | int (*set_info)(struct super_block *, int, struct if_dqinfo *); |
| 332 | − int (*get_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); | |
| 333 | − int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); | |
| 375 | + int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); | |
| 376 | + int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); | |
| 334 | 377 | int (*get_xstate)(struct super_block *, struct fs_quota_stat *); |
| 335 | 378 | int (*set_xstate)(struct super_block *, unsigned int, int); |
| 336 | 379 | int (*get_xstatev)(struct super_block *, struct fs_quota_statv *); |
| @@ -98,9 +98,9 @@ int dquot_quota_sync(struct super_block *sb, int type); · 97 unmodified lines | ||
| 98 | 98 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
| 99 | 99 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
| 100 | 100 | int dquot_get_dqblk(struct super_block *sb, struct kqid id, |
| 101 | − struct fs_disk_quota *di); | |
| 101 | + struct qc_dqblk *di); | |
| 102 | 102 | int dquot_set_dqblk(struct super_block *sb, struct kqid id, |
| 103 | − struct fs_disk_quota *di); | |
| 103 | + struct qc_dqblk *di); | |
| 104 | 104 | |
| 105 | 105 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); |
| 106 | 106 | int dquot_transfer(struct inode *inode, struct iattr *iattr); |
| @@ -39,11 +39,12 @@ struct inet_skb_parm { · 38 unmodified lines | ||
| 39 | 39 | struct ip_options opt; /* Compiled IP options */ |
| 40 | 40 | unsigned char flags; |
| 41 | 41 | |
| 42 | −#define IPSKB_FORWARDED 1 | |
| 43 | −#define IPSKB_XFRM_TUNNEL_SIZE 2 | |
| 44 | −#define IPSKB_XFRM_TRANSFORMED 4 | |
| 45 | −#define IPSKB_FRAG_COMPLETE 8 | |
| 46 | −#define IPSKB_REROUTED 16 | |
| 42 | +#define IPSKB_FORWARDED BIT(0) | |
| 43 | +#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) | |
| 44 | +#define IPSKB_XFRM_TRANSFORMED BIT(2) | |
| 45 | +#define IPSKB_FRAG_COMPLETE BIT(3) | |
| 46 | +#define IPSKB_REROUTED BIT(4) | |
| 47 | +#define IPSKB_DOREDIRECT BIT(5) | |
| 47 | 48 | |
| 48 | 49 | u16 frag_max_size; |
| 49 | 50 | }; |
| @@ -150,7 +150,7 @@ static int map_lookup_elem(union bpf_attr *attr) · 149 unmodified lines | ||
| 150 | 150 | int ufd = attr->map_fd; |
| 151 | 151 | struct fd f = fdget(ufd); |
| 152 | 152 | struct bpf_map *map; |
| 153 | − void *key, *value; | |
| 153 | + void *key, *value, *ptr; | |
| 154 | 154 | int err; |
| 155 | 155 | |
| 156 | 156 | if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM)) |
| @@ -169,20 +169,29 @@ static int map_lookup_elem(union bpf_attr *attr) · 12 unmodified lines | ||
| 169 | 169 | if (copy_from_user(key, ukey, map->key_size) != 0) |
| 170 | 170 | goto free_key; |
| 171 | 171 | |
| 172 | − err = -ENOENT; | |
| 173 | − rcu_read_lock(); | |
| 174 | − value = map->ops->map_lookup_elem(map, key); | |
| 172 | + err = -ENOMEM; | |
| 173 | + value = kmalloc(map->value_size, GFP_USER); | |
| 175 | 174 | if (!value) |
| 176 | − goto err_unlock; | |
| 175 | + goto free_key; | |
| 176 | + | |
| 177 | + rcu_read_lock(); | |
| 178 | + ptr = map->ops->map_lookup_elem(map, key); | |
| 179 | + if (ptr) | |
| 180 | + memcpy(value, ptr, map->value_size); | |
| 181 | + rcu_read_unlock(); | |
| 182 | + | |
| 183 | + err = -ENOENT; | |
| 184 | + if (!ptr) | |
| 185 | + goto free_value; | |
| 177 | 186 | |
| 178 | 187 | err = -EFAULT; |
| 179 | 188 | if (copy_to_user(uvalue, value, map->value_size) != 0) |
| 180 | − goto err_unlock; | |
| 189 | + goto free_value; | |
| 181 | 190 | |
| 182 | 191 | err = 0; |
| 183 | 192 | |
| 184 | −err_unlock: | |
| 185 | − rcu_read_unlock(); | |
| 193 | +free_value: | |
| 194 | + kfree(value); | |
| 186 | 195 | free_key: |
| 187 | 196 | kfree(key); |
| 188 | 197 | err_put: |
| @@ -1909,7 +1909,7 @@ static void cgroup_kill_sb(struct super_block *sb) · 1908 unmodified lines | ||
| 1909 | 1909 | * |
| 1910 | 1910 | * And don't kill the default root. |
| 1911 | 1911 | */ |
| 1912 | − if (css_has_online_children(&root->cgrp.self) || | |
| 1912 | + if (!list_empty(&root->cgrp.self.children) || | |
| 1913 | 1913 | root == &cgrp_dfl_root) |
| 1914 | 1914 | cgroup_put(&root->cgrp); |
| 1915 | 1915 | else |
| @@ -6776,7 +6776,6 @@ skip_type: · 6775 unmodified lines | ||
| 6776 | 6776 | __perf_event_init_context(&cpuctx->ctx); |
| 6777 | 6777 | lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); |
| 6778 | 6778 | lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); |
| 6779 | − cpuctx->ctx.type = cpu_context; | |
| 6780 | 6779 | cpuctx->ctx.pmu = pmu; |
| 6781 | 6780 | |
| 6782 | 6781 | __perf_cpu_hrtimer_init(cpuctx, cpu); |
| @@ -7420,7 +7419,19 @@ SYSCALL_DEFINE5(perf_event_open, · 637 unmodified lines | ||
| 7420 | 7419 | * task or CPU context: |
| 7421 | 7420 | */ |
| 7422 | 7421 | if (move_group) { |
| 7423 | − if (group_leader->ctx->type != ctx->type) | |
| 7422 | + /* | |
| 7423 | + * Make sure we're both on the same task, or both | |
| 7424 | + * per-cpu events. | |
| 7425 | + */ | |
| 7426 | + if (group_leader->ctx->task != ctx->task) | |
| 7427 | + goto err_context; | |
| 7428 | + | |
| 7429 | + /* | |
| 7430 | + * Make sure we're both events for the same CPU; | |
| 7431 | + * grouping events for different CPUs is broken; since | |
| 7432 | + * you can never concurrently schedule them anyhow. | |
| 7433 | + */ | |
| 7434 | + if (group_leader->cpu != event->cpu) | |
| 7424 | 7435 | goto err_context; |
| 7425 | 7436 | } else { |
| 7426 | 7437 | if (group_leader->ctx != ctx) |
| @@ -7292,13 +7292,12 @@ void __might_sleep(const char *file, int line, int preempt_offset) · 7291 unmodified lines | ||
| 7292 | 7292 | * since we will exit with TASK_RUNNING make sure we enter with it, |
| 7293 | 7293 | * otherwise we will destroy state. |
| 7294 | 7294 | */ |
| 7295 | − if (WARN_ONCE(current->state != TASK_RUNNING, | |
| 7295 | + WARN_ONCE(current->state != TASK_RUNNING && current->task_state_change, | |
| 7296 | 7296 | "do not call blocking ops when !TASK_RUNNING; " |
| 7297 | 7297 | "state=%lx set at [<%p>] %pS\n", |
| 7298 | 7298 | current->state, |
| 7299 | 7299 | (void *)current->task_state_change, |
| 7300 | − (void *)current->task_state_change)) | |
| 7301 | − __set_current_state(TASK_RUNNING); | |
| 7300 | + (void *)current->task_state_change); | |
| 7302 | 7301 | |
| 7303 | 7302 | ___might_sleep(file, line, preempt_offset); |
| 7304 | 7303 | } |
| @@ -296,7 +296,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, · 295 unmodified lines | ||
| 296 | 296 | return -ENOMEM; |
| 297 | 297 | if (ret & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) |
| 298 | 298 | return *flags & FOLL_HWPOISON ? -EHWPOISON : -EFAULT; |
| 299 | − if (ret & VM_FAULT_SIGBUS) | |
| 299 | + if (ret & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) | |
| 300 | 300 | return -EFAULT; |
| 301 | 301 | BUG(); |
| 302 | 302 | } |
| @@ -571,7 +571,7 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, · 268 unmodified lines | ||
| 571 | 571 | return -ENOMEM; |
| 572 | 572 | if (ret & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) |
| 573 | 573 | return -EHWPOISON; |
| 574 | − if (ret & VM_FAULT_SIGBUS) | |
| 574 | + if (ret & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) | |
| 575 | 575 | return -EFAULT; |
| 576 | 576 | BUG(); |
| 577 | 577 | } |
| @@ -376,7 +376,7 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr) · 375 unmodified lines | ||
| 376 | 376 | else |
| 377 | 377 | ret = VM_FAULT_WRITE; |
| 378 | 378 | put_page(page); |
| 379 | − } while (!(ret & (VM_FAULT_WRITE | VM_FAULT_SIGBUS | VM_FAULT_OOM))); | |
| 379 | + } while (!(ret & (VM_FAULT_WRITE | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | VM_FAULT_OOM))); | |
| 380 | 380 | /* |
| 381 | 381 | * We must loop because handle_mm_fault() may back out if there's |
| 382 | 382 | * any difficulty e.g. if pte accessed bit gets updated concurrently. |
| @@ -1477,9 +1477,9 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) · 1476 unmodified lines | ||
| 1477 | 1477 | |
| 1478 | 1478 | pr_info("Task in "); |
| 1479 | 1479 | pr_cont_cgroup_path(task_cgroup(p, memory_cgrp_id)); |
| 1480 | − pr_info(" killed as a result of limit of "); | |
| 1480 | + pr_cont(" killed as a result of limit of "); | |
| 1481 | 1481 | pr_cont_cgroup_path(memcg->css.cgroup); |
| 1482 | − pr_info("\n"); | |
| 1482 | + pr_cont("\n"); | |
| 1483 | 1483 | |
| 1484 | 1484 | rcu_read_unlock(); |
| 1485 | 1485 | |
| @@ -2632,7 +2632,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, · 2631 unmodified lines | ||
| 2632 | 2632 | |
| 2633 | 2633 | /* Check if we need to add a guard page to the stack */ |
| 2634 | 2634 | if (check_stack_guard_page(vma, address) < 0) |
| 2635 | − return VM_FAULT_SIGBUS; | |
| 2635 | + return VM_FAULT_SIGSEGV; | |
| 2636 | 2636 | |
| 2637 | 2637 | /* Use the zero-page for reads */ |
| 2638 | 2638 | if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm)) { |
| @@ -2332,12 +2332,21 @@ static inline struct page * · 2331 unmodified lines | ||
| 2332 | 2332 | __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, |
| 2333 | 2333 | struct zonelist *zonelist, enum zone_type high_zoneidx, |
| 2334 | 2334 | nodemask_t *nodemask, struct zone *preferred_zone, |
| 2335 | − int classzone_idx, int migratetype) | |
| 2335 | + int classzone_idx, int migratetype, unsigned long *did_some_progress) | |
| 2336 | 2336 | { |
| 2337 | 2337 | struct page *page; |
| 2338 | 2338 | |
| 2339 | − /* Acquire the per-zone oom lock for each zone */ | |
| 2339 | + *did_some_progress = 0; | |
| 2340 | + | |
| 2341 | + if (oom_killer_disabled) | |
| 2342 | + return NULL; | |
| 2343 | + | |
| 2344 | + /* | |
| 2345 | + * Acquire the per-zone oom lock for each zone. If that | |
| 2346 | + * fails, somebody else is making progress for us. | |
| 2347 | + */ | |
| 2340 | 2348 | if (!oom_zonelist_trylock(zonelist, gfp_mask)) { |
| 2349 | + *did_some_progress = 1; | |
| 2341 | 2350 | schedule_timeout_uninterruptible(1); |
| 2342 | 2351 | return NULL; |
| 2343 | 2352 | } |
| @@ -2363,12 +2372,18 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, · 19 unmodified lines | ||
| 2363 | 2372 | goto out; |
| 2364 | 2373 | |
| 2365 | 2374 | if (!(gfp_mask & __GFP_NOFAIL)) { |
| 2375 | + /* Coredumps can quickly deplete all memory reserves */ | |
| 2376 | + if (current->flags & PF_DUMPCORE) | |
| 2377 | + goto out; | |
| 2366 | 2378 | /* The OOM killer will not help higher order allocs */ |
| 2367 | 2379 | if (order > PAGE_ALLOC_COSTLY_ORDER) |
| 2368 | 2380 | goto out; |
| 2369 | 2381 | /* The OOM killer does not needlessly kill tasks for lowmem */ |
| 2370 | 2382 | if (high_zoneidx < ZONE_NORMAL) |
| 2371 | 2383 | goto out; |
| 2384 | + /* The OOM killer does not compensate for light reclaim */ | |
| 2385 | + if (!(gfp_mask & __GFP_FS)) | |
| 2386 | + goto out; | |
| 2372 | 2387 | /* |
| 2373 | 2388 | * GFP_THISNODE contains __GFP_NORETRY and we never hit this. |
| 2374 | 2389 | * Sanity check for bare calls of __GFP_THISNODE, not real OOM. |
| @@ -2381,7 +2396,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, · 6 unmodified lines | ||
| 2381 | 2396 | } |
| 2382 | 2397 | /* Exhausted what can be done so it's blamo time */ |
| 2383 | 2398 | out_of_memory(zonelist, gfp_mask, order, nodemask, false); |
| 2384 | − | |
| 2399 | + *did_some_progress = 1; | |
| 2385 | 2400 | out: |
| 2386 | 2401 | oom_zonelist_unlock(zonelist, gfp_mask); |
| 2387 | 2402 | return page; |
| @@ -2658,7 +2673,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, · 270 unmodified lines | ||
| 2658 | 2673 | (gfp_mask & GFP_THISNODE) == GFP_THISNODE) |
| 2659 | 2674 | goto nopage; |
| 2660 | 2675 | |
| 2661 | −restart: | |
| 2676 | +retry: | |
| 2662 | 2677 | if (!(gfp_mask & __GFP_NO_KSWAPD)) |
| 2663 | 2678 | wake_all_kswapds(order, zonelist, high_zoneidx, |
| 2664 | 2679 | preferred_zone, nodemask); |
| @@ -2681,7 +2696,6 @@ restart: · 16 unmodified lines | ||
| 2681 | 2696 | classzone_idx = zonelist_zone_idx(preferred_zoneref); |
| 2682 | 2697 | } |
| 2683 | 2698 | |
| 2684 | −rebalance: | |
| 2685 | 2699 | /* This is the last chance, in general, before the goto nopage. */ |
| 2686 | 2700 | page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, |
| 2687 | 2701 | high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, |
| @@ -2788,54 +2802,28 @@ rebalance: · 100 unmodified lines | ||
| 2788 | 2802 | if (page) |
| 2789 | 2803 | goto got_pg; |
| 2790 | 2804 | |
| 2791 | − /* | |
| 2792 | − * If we failed to make any progress reclaiming, then we are | |
| 2793 | − * running out of options and have to consider going OOM | |
| 2794 | − */ | |
| 2795 | − if (!did_some_progress) { | |
| 2796 | − if (oom_gfp_allowed(gfp_mask)) { | |
| 2797 | − if (oom_killer_disabled) | |
| 2798 | − goto nopage; | |
| 2799 | − /* Coredumps can quickly deplete all memory reserves */ | |
| 2800 | − if ((current->flags & PF_DUMPCORE) && | |
| 2801 | − !(gfp_mask & __GFP_NOFAIL)) | |
| 2802 | − goto nopage; | |
| 2803 | − page = __alloc_pages_may_oom(gfp_mask, order, | |
| 2804 | − zonelist, high_zoneidx, | |
| 2805 | − nodemask, preferred_zone, | |
| 2806 | − classzone_idx, migratetype); | |
| 2807 | − if (page) | |
| 2808 | − goto got_pg; | |
| 2809 | − | |
| 2810 | − if (!(gfp_mask & __GFP_NOFAIL)) { | |
| 2811 | − /* | |
| 2812 | − * The oom killer is not called for high-order | |
| 2813 | − * allocations that may fail, so if no progress | |
| 2814 | − * is being made, there are no other options and | |
| 2815 | − * retrying is unlikely to help. | |
| 2816 | − */ | |
| 2817 | − if (order > PAGE_ALLOC_COSTLY_ORDER) | |
| 2818 | − goto nopage; | |
| 2819 | − /* | |
| 2820 | − * The oom killer is not called for lowmem | |
| 2821 | − * allocations to prevent needlessly killing | |
| 2822 | − * innocent tasks. | |
| 2823 | − */ | |
| 2824 | − if (high_zoneidx < ZONE_NORMAL) | |
| 2825 | − goto nopage; | |
| 2826 | − } | |
| 2827 | − | |
| 2828 | − goto restart; | |
| 2829 | − } | |
| 2830 | − } | |
| 2831 | − | |
| 2832 | 2805 | /* Check if we should retry the allocation */ |
| 2833 | 2806 | pages_reclaimed += did_some_progress; |
| 2834 | 2807 | if (should_alloc_retry(gfp_mask, order, did_some_progress, |
| 2835 | 2808 | pages_reclaimed)) { |
| 2809 | + /* | |
| 2810 | + * If we fail to make progress by freeing individual | |
| 2811 | + * pages, but the allocation wants us to keep going, | |
| 2812 | + * start OOM killing tasks. | |
| 2813 | + */ | |
| 2814 | + if (!did_some_progress) { | |
| 2815 | + page = __alloc_pages_may_oom(gfp_mask, order, zonelist, | |
| 2816 | + high_zoneidx, nodemask, | |
| 2817 | + preferred_zone, classzone_idx, | |
| 2818 | + migratetype,&did_some_progress); | |
| 2819 | + if (page) | |
| 2820 | + goto got_pg; | |
| 2821 | + if (!did_some_progress) | |
| 2822 | + goto nopage; | |
| 2823 | + } | |
| 2836 | 2824 | /* Wait for some write requests to complete then retry */ |
| 2837 | 2825 | wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50); |
| 2838 | − goto rebalance; | |
| 2826 | + goto retry; | |
| 2839 | 2827 | } else { |
| 2840 | 2828 | /* |
| 2841 | 2829 | * High-order allocations do not necessarily loop after |
| @@ -2656,7 +2656,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, · 2655 unmodified lines | ||
| 2656 | 2656 | * should make reasonable progress. |
| 2657 | 2657 | */ |
| 2658 | 2658 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
| 2659 | − gfp_mask, nodemask) { | |
| 2659 | + gfp_zone(gfp_mask), nodemask) { | |
| 2660 | 2660 | if (zone_idx(zone) > ZONE_NORMAL) |
| 2661 | 2661 | continue; |
| 2662 | 2662 | |
| @@ -46,6 +46,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds) · 45 unmodified lines | ||
| 46 | 46 | snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x", |
| 47 | 47 | ds->index, ds->pd->sw_addr); |
| 48 | 48 | ds->slave_mii_bus->parent = ds->master_dev; |
| 49 | + ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; | |
| 49 | 50 | } |
| 50 | 51 | |
| 51 | 52 | |
| @@ -129,7 +129,8 @@ int ip_forward(struct sk_buff *skb) · 128 unmodified lines | ||
| 129 | 129 | * We now generate an ICMP HOST REDIRECT giving the route |
| 130 | 130 | * we calculated. |
| 131 | 131 | */ |
| 132 | − if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb)) | |
| 132 | + if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr && | |
| 133 | + !skb_sec_path(skb)) | |
| 133 | 134 | ip_rt_send_redirect(skb); |
| 134 | 135 | |
| 135 | 136 | skb->priority = rt_tos2priority(iph->tos); |
| @@ -966,8 +966,11 @@ bool ping_rcv(struct sk_buff *skb) · 965 unmodified lines | ||
| 966 | 966 | |
| 967 | 967 | sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); |
| 968 | 968 | if (sk != NULL) { |
| 969 | + struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); | |
| 970 | + | |
| 969 | 971 | pr_debug("rcv on socket %p\n", sk); |
| 970 | − ping_queue_rcv_skb(sk, skb_get(skb)); | |
| 972 | + if (skb2) | |
| 973 | + ping_queue_rcv_skb(sk, skb2); | |
| 971 | 974 | sock_put(sk); |
| 972 | 975 | return true; |
| 973 | 976 | } |
| @@ -1554,11 +1554,10 @@ static int __mkroute_input(struct sk_buff *skb, · 1553 unmodified lines | ||
| 1554 | 1554 | |
| 1555 | 1555 | do_cache = res->fi && !itag; |
| 1556 | 1556 | if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && |
| 1557 | + skb->protocol == htons(ETH_P_IP) && | |
| 1557 | 1558 | (IN_DEV_SHARED_MEDIA(out_dev) || |
| 1558 | − inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { | |
| 1559 | − flags |= RTCF_DOREDIRECT; | |
| 1560 | − do_cache = false; | |
| 1561 | − } | |
| 1559 | + inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) | |
| 1560 | + IPCB(skb)->flags |= IPSKB_DOREDIRECT; | |
| 1562 | 1561 | |
| 1563 | 1562 | if (skb->protocol != htons(ETH_P_IP)) { |
| 1564 | 1563 | /* Not IP (i.e. ARP). Do not create route, if it is |
| @@ -2303,6 +2302,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, · 738 unmodified lines | ||
| 2303 | 2302 | r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; |
| 2304 | 2303 | if (rt->rt_flags & RTCF_NOTIFY) |
| 2305 | 2304 | r->rtm_flags |= RTM_F_NOTIFY; |
| 2305 | + if (IPCB(skb)->flags & IPSKB_DOREDIRECT) | |
| 2306 | + r->rtm_flags |= RTCF_DOREDIRECT; | |
| 2306 | 2307 | |
| 2307 | 2308 | if (nla_put_be32(skb, RTA_DST, dst)) |
| 2308 | 2309 | goto nla_put_failure; |
| @@ -99,11 +99,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin · 98 unmodified lines | ||
| 99 | 99 | s_slot = cb->args[0]; |
| 100 | 100 | num = s_num = cb->args[1]; |
| 101 | 101 | |
| 102 | − for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) { | |
| 102 | + for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) { | |
| 103 | 103 | struct sock *sk; |
| 104 | 104 | struct hlist_nulls_node *node; |
| 105 | 105 | struct udp_hslot *hslot = &table->hash[slot]; |
| 106 | 106 | |
| 107 | + num = 0; | |
| 108 | + | |
| 107 | 109 | if (hlist_nulls_empty(&hslot->head)) |
| 108 | 110 | continue; |
| 109 | 111 | |
| @@ -659,6 +659,29 @@ static int fib6_commit_metrics(struct dst_entry *dst, · 658 unmodified lines | ||
| 659 | 659 | return 0; |
| 660 | 660 | } |
| 661 | 661 | |
| 662 | +static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, | |
| 663 | + struct net *net) | |
| 664 | +{ | |
| 665 | + if (atomic_read(&rt->rt6i_ref) != 1) { | |
| 666 | + /* This route is used as dummy address holder in some split | |
| 667 | + * nodes. It is not leaked, but it still holds other resources, | |
| 668 | + * which must be released in time. So, scan ascendant nodes | |
| 669 | + * and replace dummy references to this route with references | |
| 670 | + * to still alive ones. | |
| 671 | + */ | |
| 672 | + while (fn) { | |
| 673 | + if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { | |
| 674 | + fn->leaf = fib6_find_prefix(net, fn); | |
| 675 | + atomic_inc(&fn->leaf->rt6i_ref); | |
| 676 | + rt6_release(rt); | |
| 677 | + } | |
| 678 | + fn = fn->parent; | |
| 679 | + } | |
| 680 | + /* No more references are possible at this point. */ | |
| 681 | + BUG_ON(atomic_read(&rt->rt6i_ref) != 1); | |
| 682 | + } | |
| 683 | +} | |
| 684 | + | |
| 662 | 685 | /* |
| 663 | 686 | * Insert routing information in a node. |
| 664 | 687 | */ |
| @@ -807,11 +830,12 @@ add: · 142 unmodified lines | ||
| 807 | 830 | rt->dst.rt6_next = iter->dst.rt6_next; |
| 808 | 831 | atomic_inc(&rt->rt6i_ref); |
| 809 | 832 | inet6_rt_notify(RTM_NEWROUTE, rt, info); |
| 810 | − rt6_release(iter); | |
| 811 | 833 | if (!(fn->fn_flags & RTN_RTINFO)) { |
| 812 | 834 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; |
| 813 | 835 | fn->fn_flags |= RTN_RTINFO; |
| 814 | 836 | } |
| 837 | + fib6_purge_rt(iter, fn, info->nl_net); | |
| 838 | + rt6_release(iter); | |
| 815 | 839 | } |
| 816 | 840 | |
| 817 | 841 | return 0; |
| @@ -1322,24 +1346,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, · 504 unmodified lines | ||
| 1322 | 1346 | fn = fib6_repair_tree(net, fn); |
| 1323 | 1347 | } |
| 1324 | 1348 | |
| 1325 | − if (atomic_read(&rt->rt6i_ref) != 1) { | |
| 1326 | − /* This route is used as dummy address holder in some split | |
| 1327 | − * nodes. It is not leaked, but it still holds other resources, | |
| 1328 | − * which must be released in time. So, scan ascendant nodes | |
| 1329 | − * and replace dummy references to this route with references | |
| 1330 | − * to still alive ones. | |
| 1331 | − */ | |
| 1332 | − while (fn) { | |
| 1333 | − if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { | |
| 1334 | − fn->leaf = fib6_find_prefix(net, fn); | |
| 1335 | − atomic_inc(&fn->leaf->rt6i_ref); | |
| 1336 | − rt6_release(rt); | |
| 1337 | − } | |
| 1338 | − fn = fn->parent; | |
| 1339 | − } | |
| 1340 | − /* No more references are possible at this point. */ | |
| 1341 | − BUG_ON(atomic_read(&rt->rt6i_ref) != 1); | |
| 1342 | − } | |
| 1349 | + fib6_purge_rt(rt, fn, net); | |
| 1343 | 1350 | |
| 1344 | 1351 | inet6_rt_notify(RTM_DELROUTE, rt, info); |
| 1345 | 1352 | rt6_release(rt); |
| @@ -1242,12 +1242,16 @@ restart: · 1241 unmodified lines | ||
| 1242 | 1242 | rt = net->ipv6.ip6_null_entry; |
| 1243 | 1243 | else if (rt->dst.error) { |
| 1244 | 1244 | rt = net->ipv6.ip6_null_entry; |
| 1245 | − } else if (rt == net->ipv6.ip6_null_entry) { | |
| 1245 | + goto out; | |
| 1246 | + } | |
| 1247 | + | |
| 1248 | + if (rt == net->ipv6.ip6_null_entry) { | |
| 1246 | 1249 | fn = fib6_backtrack(fn, &fl6->saddr); |
| 1247 | 1250 | if (fn) |
| 1248 | 1251 | goto restart; |
| 1249 | 1252 | } |
| 1250 | 1253 | |
| 1254 | +out: | |
| 1251 | 1255 | dst_hold(&rt->dst); |
| 1252 | 1256 | |
| 1253 | 1257 | read_unlock_bh(&table->tb6_lock); |
| @@ -130,12 +130,18 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) · 129 unmodified lines | ||
| 130 | 130 | { |
| 131 | 131 | struct flowi6 *fl6 = &fl->u.ip6; |
| 132 | 132 | int onlyproto = 0; |
| 133 | − u16 offset = skb_network_header_len(skb); | |
| 134 | 133 | const struct ipv6hdr *hdr = ipv6_hdr(skb); |
| 134 | + u16 offset = sizeof(*hdr); | |
| 135 | 135 | struct ipv6_opt_hdr *exthdr; |
| 136 | 136 | const unsigned char *nh = skb_network_header(skb); |
| 137 | − u8 nexthdr = nh[IP6CB(skb)->nhoff]; | |
| 137 | + u16 nhoff = IP6CB(skb)->nhoff; | |
| 138 | 138 | int oif = 0; |
| 139 | + u8 nexthdr; | |
| 140 | + | |
| 141 | + if (!nhoff) | |
| 142 | + nhoff = offsetof(struct ipv6hdr, nexthdr); | |
| 143 | + | |
| 144 | + nexthdr = nh[nhoff]; | |
| 139 | 145 | |
| 140 | 146 | if (skb_dst(skb)) |
| 141 | 147 | oif = skb_dst(skb)->dev->ifindex; |
| @@ -18,28 +18,28 @@ static struct ctl_table llc2_timeout_table[] = { · 17 unmodified lines | ||
| 18 | 18 | { |
| 19 | 19 | .procname = "ack", |
| 20 | 20 | .data = &sysctl_llc2_ack_timeout, |
| 21 | − .maxlen = sizeof(long), | |
| 21 | + .maxlen = sizeof(sysctl_llc2_ack_timeout), | |
| 22 | 22 | .mode = 0644, |
| 23 | 23 | .proc_handler = proc_dointvec_jiffies, |
| 24 | 24 | }, |
| 25 | 25 | { |
| 26 | 26 | .procname = "busy", |
| 27 | 27 | .data = &sysctl_llc2_busy_timeout, |
| 28 | − .maxlen = sizeof(long), | |
| 28 | + .maxlen = sizeof(sysctl_llc2_busy_timeout), | |
| 29 | 29 | .mode = 0644, |
| 30 | 30 | .proc_handler = proc_dointvec_jiffies, |
| 31 | 31 | }, |
| 32 | 32 | { |
| 33 | 33 | .procname = "p", |
| 34 | 34 | .data = &sysctl_llc2_p_timeout, |
| 35 | − .maxlen = sizeof(long), | |
| 35 | + .maxlen = sizeof(sysctl_llc2_p_timeout), | |
| 36 | 36 | .mode = 0644, |
| 37 | 37 | .proc_handler = proc_dointvec_jiffies, |
| 38 | 38 | }, |
| 39 | 39 | { |
| 40 | 40 | .procname = "rej", |
| 41 | 41 | .data = &sysctl_llc2_rej_timeout, |
| 42 | − .maxlen = sizeof(long), | |
| 42 | + .maxlen = sizeof(sysctl_llc2_rej_timeout), | |
| 43 | 43 | .mode = 0644, |
| 44 | 44 | .proc_handler = proc_dointvec_jiffies, |
| 45 | 45 | }, |
| @@ -86,20 +86,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) · 85 unmodified lines | ||
| 86 | 86 | } |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | − /* tear down aggregation sessions and remove STAs */ | |
| 90 | − mutex_lock(&local->sta_mtx); | |
| 91 | − list_for_each_entry(sta, &local->sta_list, list) { | |
| 92 | − if (sta->uploaded) { | |
| 93 | − enum ieee80211_sta_state state; | |
| 94 | − | |
| 95 | − state = sta->sta_state; | |
| 96 | − for (; state > IEEE80211_STA_NOTEXIST; state--) | |
| 97 | − WARN_ON(drv_sta_state(local, sta->sdata, sta, | |
| 98 | − state, state - 1)); | |
| 99 | − } | |
| 100 | − } | |
| 101 | − mutex_unlock(&local->sta_mtx); | |
| 102 | − | |
| 103 | 89 | /* remove all interfaces that were created in the driver */ |
| 104 | 90 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 105 | 91 | if (!ieee80211_sdata_running(sdata)) |
| @@ -111,6 +97,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) · 5 unmodified lines | ||
| 111 | 97 | case NL80211_IFTYPE_STATION: |
| 112 | 98 | ieee80211_mgd_quiesce(sdata); |
| 113 | 99 | break; |
| 100 | + case NL80211_IFTYPE_WDS: | |
| 101 | + /* tear down aggregation sessions and remove STAs */ | |
| 102 | + mutex_lock(&local->sta_mtx); | |
| 103 | + sta = sdata->u.wds.sta; | |
| 104 | + if (sta && sta->uploaded) { | |
| 105 | + enum ieee80211_sta_state state; | |
| 106 | + | |
| 107 | + state = sta->sta_state; | |
| 108 | + for (; state > IEEE80211_STA_NOTEXIST; state--) | |
| 109 | + WARN_ON(drv_sta_state(local, sta->sdata, | |
| 110 | + sta, state, | |
| 111 | + state - 1)); | |
| 112 | + } | |
| 113 | + mutex_unlock(&local->sta_mtx); | |
| 114 | + break; | |
| 114 | 115 | default: |
| 115 | 116 | break; |
| 116 | 117 | } |
| @@ -272,7 +272,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, · 271 unmodified lines | ||
| 272 | 272 | else if (rate && rate->flags & IEEE80211_RATE_ERP_G) |
| 273 | 273 | channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; |
| 274 | 274 | else if (rate) |
| 275 | − channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; | |
| 275 | + channel_flags |= IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ; | |
| 276 | 276 | else |
| 277 | 277 | channel_flags |= IEEE80211_CHAN_2GHZ; |
| 278 | 278 | put_unaligned_le16(channel_flags, pos); |
| @@ -180,6 +180,11 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, · 179 unmodified lines | ||
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | bpf_size = bpf_len * sizeof(*bpf_ops); |
| 183 | + if (bpf_size != nla_len(tb[TCA_BPF_OPS])) { | |
| 184 | + ret = -EINVAL; | |
| 185 | + goto errout; | |
| 186 | + } | |
| 187 | + | |
| 183 | 188 | bpf_ops = kzalloc(bpf_size, GFP_KERNEL); |
| 184 | 189 | if (bpf_ops == NULL) { |
| 185 | 190 | ret = -ENOMEM; |
| @@ -215,15 +220,21 @@ static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp, · 29 unmodified lines | ||
| 215 | 220 | struct cls_bpf_head *head) |
| 216 | 221 | { |
| 217 | 222 | unsigned int i = 0x80000000; |
| 223 | + u32 handle; | |
| 218 | 224 | |
| 219 | 225 | do { |
| 220 | 226 | if (++head->hgen == 0x7FFFFFFF) |
| 221 | 227 | head->hgen = 1; |
| 222 | 228 | } while (--i > 0 && cls_bpf_get(tp, head->hgen)); |
| 223 | − if (i == 0) | |
| 229 | + | |
| 230 | + if (unlikely(i == 0)) { | |
| 224 | 231 | pr_err("Insufficient number of handles\n"); |
| 232 | + handle = 0; | |
| 233 | + } else { | |
| 234 | + handle = head->hgen; | |
| 235 | + } | |
| 225 | 236 | |
| 226 | − return i; | |
| 237 | + return handle; | |
| 227 | 238 | } |
| 228 | 239 | |
| 229 | 240 | static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, |
| @@ -1182,7 +1182,6 @@ void sctp_assoc_update(struct sctp_association *asoc, · 1181 unmodified lines | ||
| 1182 | 1182 | asoc->peer.peer_hmacs = new->peer.peer_hmacs; |
| 1183 | 1183 | new->peer.peer_hmacs = NULL; |
| 1184 | 1184 | |
| 1185 | − sctp_auth_key_put(asoc->asoc_shared_key); | |
| 1186 | 1185 | sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); |
| 1187 | 1186 | } |
| 1188 | 1187 | |
| @@ -869,9 +869,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, · 868 unmodified lines | ||
| 869 | 869 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, |
| 870 | 870 | struct sock_iocb *siocb) |
| 871 | 871 | { |
| 872 | − if (!is_sync_kiocb(iocb)) | |
| 873 | − BUG(); | |
| 874 | − | |
| 875 | 872 | siocb->kiocb = iocb; |
| 876 | 873 | iocb->private = siocb; |
| 877 | 874 | return siocb; |
| @@ -2854,6 +2854,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) · 2853 unmodified lines | ||
| 2854 | 2854 | if (!rdev->ops->get_key) |
| 2855 | 2855 | return -EOPNOTSUPP; |
| 2856 | 2856 | |
| 2857 | + if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | |
| 2858 | + return -ENOENT; | |
| 2859 | + | |
| 2857 | 2860 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
| 2858 | 2861 | if (!msg) |
| 2859 | 2862 | return -ENOMEM; |
| @@ -2873,10 +2876,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) · 13 unmodified lines | ||
| 2873 | 2876 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) |
| 2874 | 2877 | goto nla_put_failure; |
| 2875 | 2878 | |
| 2876 | − if (pairwise && mac_addr && | |
| 2877 | − !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | |
| 2878 | − return -ENOENT; | |
| 2879 | − | |
| 2880 | 2879 | err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, |
| 2881 | 2880 | get_key_callback); |
| 2882 | 2881 | |
| @@ -3047,7 +3046,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) · 164 unmodified lines | ||
| 3047 | 3046 | wdev_lock(dev->ieee80211_ptr); |
| 3048 | 3047 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
| 3049 | 3048 | |
| 3050 | − if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && | |
| 3049 | + if (key.type == NL80211_KEYTYPE_GROUP && mac_addr && | |
| 3051 | 3050 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) |
| 3052 | 3051 | err = -ENOENT; |
| 3053 | 3052 | |
| @@ -308,6 +308,12 @@ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) · 307 unmodified lines | ||
| 308 | 308 | goto out; |
| 309 | 309 | } |
| 310 | 310 | |
| 311 | + if (ieee80211_is_mgmt(fc)) { | |
| 312 | + if (ieee80211_has_order(fc)) | |
| 313 | + hdrlen += IEEE80211_HT_CTL_LEN; | |
| 314 | + goto out; | |
| 315 | + } | |
| 316 | + | |
| 311 | 317 | if (ieee80211_is_ctl(fc)) { |
| 312 | 318 | /* |
| 313 | 319 | * ACK and CTS are 10 bytes, all others 16. To see how |
| @@ -69,9 +69,9 @@ static void test_hashmap_sanity(int i, void *data) · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | /* iterate over two elements */ |
| 71 | 71 | assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 && |
| 72 | − next_key == 2); | |
| 72 | + (next_key == 1 || next_key == 2)); | |
| 73 | 73 | assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 && |
| 74 | − next_key == 1); | |
| 74 | + (next_key == 1 || next_key == 2)); | |
| 75 | 75 | assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 && |
| 76 | 76 | errno == ENOENT); |
| 77 | 77 | |
| @@ -348,7 +348,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 347 unmodified lines | ||
| 348 | 348 | struct atmel_pcm_dma_params *dma_params; |
| 349 | 349 | int dir, channels, bits; |
| 350 | 350 | u32 tfmr, rfmr, tcmr, rcmr; |
| 351 | − int start_event; | |
| 352 | 351 | int ret; |
| 353 | 352 | int fslen, fslen_ext; |
| 354 | 353 | |
| @@ -457,19 +456,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 102 unmodified lines | ||
| 457 | 456 | * The SSC transmit clock is obtained from the BCLK signal on |
| 458 | 457 | * on the TK line, and the SSC receive clock is |
| 459 | 458 | * generated from the transmit clock. |
| 460 | − * | |
| 461 | − * For single channel data, one sample is transferred | |
| 462 | − * on the falling edge of the LRC clock. | |
| 463 | − * For two channel data, one sample is | |
| 464 | − * transferred on both edges of the LRC clock. | |
| 465 | 459 | */ |
| 466 | − start_event = ((channels == 1) | |
| 467 | − ? SSC_START_FALLING_RF | |
| 468 | − : SSC_START_EDGE_RF); | |
| 469 | − | |
| 470 | 460 | rcmr = SSC_BF(RCMR_PERIOD, 0) |
| 471 | 461 | | SSC_BF(RCMR_STTDLY, START_DELAY) |
| 472 | − | SSC_BF(RCMR_START, start_event) | |
| 462 | + | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | |
| 473 | 463 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
| 474 | 464 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
| 475 | 465 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
| @@ -478,14 +468,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 478 | 468 | rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
| 479 | 469 | | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
| 480 | 470 | | SSC_BF(RFMR_FSLEN, 0) |
| 481 | − | SSC_BF(RFMR_DATNB, 0) | |
| 471 | + | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 482 | 472 | | SSC_BIT(RFMR_MSBF) |
| 483 | 473 | | SSC_BF(RFMR_LOOP, 0) |
| 484 | 474 | | SSC_BF(RFMR_DATLEN, (bits - 1)); |
| 485 | 475 | |
| 486 | 476 | tcmr = SSC_BF(TCMR_PERIOD, 0) |
| 487 | 477 | | SSC_BF(TCMR_STTDLY, START_DELAY) |
| 488 | − | SSC_BF(TCMR_START, start_event) | |
| 478 | + | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | |
| 489 | 479 | | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
| 490 | 480 | | SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
| 491 | 481 | | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? |
| @@ -495,7 +485,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 3 unmodified lines | ||
| 495 | 485 | | SSC_BF(TFMR_FSDEN, 0) |
| 496 | 486 | | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
| 497 | 487 | | SSC_BF(TFMR_FSLEN, 0) |
| 498 | − | SSC_BF(TFMR_DATNB, 0) | |
| 488 | + | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 499 | 489 | | SSC_BIT(TFMR_MSBF) |
| 500 | 490 | | SSC_BF(TFMR_DATDEF, 0) |
| 501 | 491 | | SSC_BF(TFMR_DATLEN, (bits - 1)); |
| @@ -512,7 +502,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 10 unmodified lines | ||
| 512 | 502 | rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
| 513 | 503 | | SSC_BF(RCMR_STTDLY, 1) |
| 514 | 504 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
| 515 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 505 | + | SSC_BF(RCMR_CKI, SSC_CKI_FALLING) | |
| 516 | 506 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
| 517 | 507 | | SSC_BF(RCMR_CKS, SSC_CKS_DIV); |
| 518 | 508 | |
| @@ -527,7 +517,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 8 unmodified lines | ||
| 527 | 517 | tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
| 528 | 518 | | SSC_BF(TCMR_STTDLY, 1) |
| 529 | 519 | | SSC_BF(TCMR_START, SSC_START_RISING_RF) |
| 530 | − | SSC_BF(TCMR_CKI, SSC_CKI_RISING) | |
| 520 | + | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | |
| 531 | 521 | | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
| 532 | 522 | | SSC_BF(TCMR_CKS, SSC_CKS_DIV); |
| 533 | 523 | |
| @@ -556,7 +546,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 22 unmodified lines | ||
| 556 | 546 | rcmr = SSC_BF(RCMR_PERIOD, 0) |
| 557 | 547 | | SSC_BF(RCMR_STTDLY, START_DELAY) |
| 558 | 548 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
| 559 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 549 | + | SSC_BF(RCMR_CKI, SSC_CKI_FALLING) | |
| 560 | 550 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
| 561 | 551 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
| 562 | 552 | SSC_CKS_PIN : SSC_CKS_CLOCK); |
| @@ -2124,6 +2124,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match); · 2123 unmodified lines | ||
| 2124 | 2124 | static struct acpi_device_id rt5640_acpi_match[] = { |
| 2125 | 2125 | { "INT33CA", 0 }, |
| 2126 | 2126 | { "10EC5640", 0 }, |
| 2127 | + { "10EC5642", 0 }, | |
| 2127 | 2128 | { }, |
| 2128 | 2129 | }; |
| 2129 | 2130 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); |
| @@ -483,21 +483,21 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) · 482 unmodified lines | ||
| 483 | 483 | /* setting i2s data format */ |
| 484 | 484 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 485 | 485 | case SND_SOC_DAIFMT_DSP_A: |
| 486 | − i2sctl |= SGTL5000_I2S_MODE_PCM; | |
| 486 | + i2sctl |= SGTL5000_I2S_MODE_PCM << SGTL5000_I2S_MODE_SHIFT; | |
| 487 | 487 | break; |
| 488 | 488 | case SND_SOC_DAIFMT_DSP_B: |
| 489 | − i2sctl |= SGTL5000_I2S_MODE_PCM; | |
| 489 | + i2sctl |= SGTL5000_I2S_MODE_PCM << SGTL5000_I2S_MODE_SHIFT; | |
| 490 | 490 | i2sctl |= SGTL5000_I2S_LRALIGN; |
| 491 | 491 | break; |
| 492 | 492 | case SND_SOC_DAIFMT_I2S: |
| 493 | − i2sctl |= SGTL5000_I2S_MODE_I2S_LJ; | |
| 493 | + i2sctl |= SGTL5000_I2S_MODE_I2S_LJ << SGTL5000_I2S_MODE_SHIFT; | |
| 494 | 494 | break; |
| 495 | 495 | case SND_SOC_DAIFMT_RIGHT_J: |
| 496 | − i2sctl |= SGTL5000_I2S_MODE_RJ; | |
| 496 | + i2sctl |= SGTL5000_I2S_MODE_RJ << SGTL5000_I2S_MODE_SHIFT; | |
| 497 | 497 | i2sctl |= SGTL5000_I2S_LRPOL; |
| 498 | 498 | break; |
| 499 | 499 | case SND_SOC_DAIFMT_LEFT_J: |
| 500 | − i2sctl |= SGTL5000_I2S_MODE_I2S_LJ; | |
| 500 | + i2sctl |= SGTL5000_I2S_MODE_I2S_LJ << SGTL5000_I2S_MODE_SHIFT; | |
| 501 | 501 | i2sctl |= SGTL5000_I2S_LRALIGN; |
| 502 | 502 | break; |
| 503 | 503 | default: |
| @@ -1462,6 +1462,9 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, · 958 unmodified lines | ||
| 1462 | 1462 | if (ret) |
| 1463 | 1463 | return ret; |
| 1464 | 1464 | |
| 1465 | + /* Need 8 clocks before I2C accesses */ | |
| 1466 | + udelay(1); | |
| 1467 | + | |
| 1465 | 1468 | /* read chip information */ |
| 1466 | 1469 | ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®); |
| 1467 | 1470 | if (ret) |
| @@ -1046,7 +1046,7 @@ static int aic3x_prepare(struct snd_pcm_substream *substream, · 1045 unmodified lines | ||
| 1046 | 1046 | delay += aic3x->tdm_delay; |
| 1047 | 1047 | |
| 1048 | 1048 | /* Configure data delay */ |
| 1049 | − snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, aic3x->tdm_delay); | |
| 1049 | + snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay); | |
| 1050 | 1050 | |
| 1051 | 1051 | return 0; |
| 1052 | 1052 | } |
| @@ -717,6 +717,8 @@ static int wm8731_i2c_probe(struct i2c_client *i2c, · 716 unmodified lines | ||
| 717 | 717 | if (wm8731 == NULL) |
| 718 | 718 | return -ENOMEM; |
| 719 | 719 | |
| 720 | + mutex_init(&wm8731->lock); | |
| 721 | + | |
| 720 | 722 | wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); |
| 721 | 723 | if (IS_ERR(wm8731->regmap)) { |
| 722 | 724 | ret = PTR_ERR(wm8731->regmap); |
| @@ -651,11 +651,11 @@ static void hsw_notification_work(struct work_struct *work) · 650 unmodified lines | ||
| 651 | 651 | } |
| 652 | 652 | |
| 653 | 653 | /* tell DSP that notification has been handled */ |
| 654 | − sst_dsp_shim_update_bits_unlocked(hsw->dsp, SST_IPCD, | |
| 654 | + sst_dsp_shim_update_bits(hsw->dsp, SST_IPCD, | |
| 655 | 655 | SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE); |
| 656 | 656 | |
| 657 | 657 | /* unmask busy interrupt */ |
| 658 | − sst_dsp_shim_update_bits_unlocked(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0); | |
| 658 | + sst_dsp_shim_update_bits(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0); | |
| 659 | 659 | } |
| 660 | 660 | |
| 661 | 661 | static struct ipc_message *reply_find_msg(struct sst_hsw *hsw, u32 header) |
| @@ -5,7 +5,10 @@ · 4 unmodified lines | ||
| 5 | 5 | * ANY CHANGES MADE HERE WILL BE LOST! |
| 6 | 6 | * |
| 7 | 7 | */ |
| 8 | − | |
| 8 | +#include <stdbool.h> | |
| 9 | +#ifndef HAS_BOOL | |
| 10 | +# define HAS_BOOL 1 | |
| 11 | +#endif | |
| 9 | 12 | #line 1 "Context.xs" |
| 10 | 13 | /* |
| 11 | 14 | * Context.xs. XS interfaces for perf script. |
| @@ -177,14 +177,17 @@ static int lock__parse(struct ins_operands *ops) · 176 unmodified lines | ||
| 177 | 177 | goto out_free_ops; |
| 178 | 178 | |
| 179 | 179 | ops->locked.ins = ins__find(name); |
| 180 | + free(name); | |
| 181 | + | |
| 180 | 182 | if (ops->locked.ins == NULL) |
| 181 | 183 | goto out_free_ops; |
| 182 | 184 | |
| 183 | 185 | if (!ops->locked.ins->ops) |
| 184 | 186 | return 0; |
| 185 | 187 | |
| 186 | − if (ops->locked.ins->ops->parse) | |
| 187 | − ops->locked.ins->ops->parse(ops->locked.ops); | |
| 188 | + if (ops->locked.ins->ops->parse && | |
| 189 | + ops->locked.ins->ops->parse(ops->locked.ops) < 0) | |
| 190 | + goto out_free_ops; | |
| 188 | 191 | |
| 189 | 192 | return 0; |
| 190 | 193 | |
| @@ -208,6 +211,13 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, · 17 unmodified lines | ||
| 208 | 211 | |
| 209 | 212 | static void lock__delete(struct ins_operands *ops) |
| 210 | 213 | { |
| 214 | + struct ins *ins = ops->locked.ins; | |
| 215 | + | |
| 216 | + if (ins && ins->ops->free) | |
| 217 | + ins->ops->free(ops->locked.ops); | |
| 218 | + else | |
| 219 | + ins__delete(ops->locked.ops); | |
| 220 | + | |
| 211 | 221 | zfree(&ops->locked.ops); |
| 212 | 222 | zfree(&ops->target.raw); |
| 213 | 223 | zfree(&ops->target.name); |
| @@ -531,8 +541,8 @@ static void disasm_line__init_ins(struct disasm_line *dl) · 317 unmodified lines | ||
| 531 | 541 | if (!dl->ins->ops) |
| 532 | 542 | return; |
| 533 | 543 | |
| 534 | − if (dl->ins->ops->parse) | |
| 535 | − dl->ins->ops->parse(&dl->ops); | |
| 544 | + if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops) < 0) | |
| 545 | + dl->ins = NULL; | |
| 536 | 546 | } |
| 537 | 547 | |
| 538 | 548 | static int disasm_line__parse(char *line, char **namep, char **rawp) |
| @@ -1445,7 +1445,7 @@ int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused, · 1444 unmodified lines | ||
| 1445 | 1445 | case ENOENT: |
| 1446 | 1446 | scnprintf(buf, size, "%s", |
| 1447 | 1447 | "Error:\tUnable to find debugfs\n" |
| 1448 | − "Hint:\tWas your kernel was compiled with debugfs support?\n" | |
| 1448 | + "Hint:\tWas your kernel compiled with debugfs support?\n" | |
| 1449 | 1449 | "Hint:\tIs the debugfs filesystem mounted?\n" |
| 1450 | 1450 | "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); |
| 1451 | 1451 | break; |
| @@ -116,6 +116,22 @@ struct thread; · 115 unmodified lines | ||
| 116 | 116 | #define map__for_each_symbol(map, pos, n) \ |
| 117 | 117 | dso__for_each_symbol(map->dso, pos, n, map->type) |
| 118 | 118 | |
| 119 | +/* map__for_each_symbol_with_name - iterate over the symbols in the given map | |
| 120 | + * that have the given name | |
| 121 | + * | |
| 122 | + * @map: the 'struct map *' in which symbols itereated | |
| 123 | + * @sym_name: the symbol name | |
| 124 | + * @pos: the 'struct symbol *' to use as a loop cursor | |
| 125 | + * @filter: to use when loading the DSO | |
| 126 | + */ | |
| 127 | +#define __map__for_each_symbol_by_name(map, sym_name, pos, filter) \ | |
| 128 | + for (pos = map__find_symbol_by_name(map, sym_name, filter); \ | |
| 129 | + pos && strcmp(pos->name, sym_name) == 0; \ | |
| 130 | + pos = symbol__next_by_name(pos)) | |
| 131 | + | |
| 132 | +#define map__for_each_symbol_by_name(map, sym_name, pos) \ | |
| 133 | + __map__for_each_symbol_by_name(map, sym_name, (pos), NULL) | |
| 134 | + | |
| 119 | 135 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); |
| 120 | 136 | |
| 121 | 137 | void map__init(struct map *map, enum map_type type, |
| @@ -446,7 +446,7 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs, · 445 unmodified lines | ||
| 446 | 446 | } |
| 447 | 447 | |
| 448 | 448 | for (i = 0; i < ntevs; i++) { |
| 449 | − if (tevs[i].point.address) { | |
| 449 | + if (tevs[i].point.address && !tevs[i].point.retprobe) { | |
| 450 | 450 | tmp = strdup(reloc_sym->name); |
| 451 | 451 | if (!tmp) |
| 452 | 452 | return -ENOMEM; |
| @@ -2193,18 +2193,17 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, · 1740 unmodified lines | ||
| 2193 | 2193 | return ret; |
| 2194 | 2194 | } |
| 2195 | 2195 | |
| 2196 | −static char *looking_function_name; | |
| 2197 | −static int num_matched_functions; | |
| 2198 | − | |
| 2199 | −static int probe_function_filter(struct map *map __maybe_unused, | |
| 2200 | − struct symbol *sym) | |
| 2196 | +static int find_probe_functions(struct map *map, char *name) | |
| 2201 | 2197 | { |
| 2202 | − if ((sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) && | |
| 2203 | − strcmp(looking_function_name, sym->name) == 0) { | |
| 2204 | − num_matched_functions++; | |
| 2205 | − return 0; | |
| 2198 | + int found = 0; | |
| 2199 | + struct symbol *sym; | |
| 2200 | + | |
| 2201 | + map__for_each_symbol_by_name(map, name, sym) { | |
| 2202 | + if (sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) | |
| 2203 | + found++; | |
| 2206 | 2204 | } |
| 2207 | − return 1; | |
| 2205 | + | |
| 2206 | + return found; | |
| 2208 | 2207 | } |
| 2209 | 2208 | |
| 2210 | 2209 | #define strdup_or_goto(str, label) \ |
| @@ -2222,10 +2221,10 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 11 unmodified lines | ||
| 2222 | 2221 | struct kmap *kmap = NULL; |
| 2223 | 2222 | struct ref_reloc_sym *reloc_sym = NULL; |
| 2224 | 2223 | struct symbol *sym; |
| 2225 | − struct rb_node *nd; | |
| 2226 | 2224 | struct probe_trace_event *tev; |
| 2227 | 2225 | struct perf_probe_point *pp = &pev->point; |
| 2228 | 2226 | struct probe_trace_point *tp; |
| 2227 | + int num_matched_functions; | |
| 2229 | 2228 | int ret, i; |
| 2230 | 2229 | |
| 2231 | 2230 | /* Init maps of given executable or kernel */ |
| @@ -2242,10 +2241,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 10 unmodified lines | ||
| 2242 | 2241 | * Load matched symbols: Since the different local symbols may have |
| 2243 | 2242 | * same name but different addresses, this lists all the symbols. |
| 2244 | 2243 | */ |
| 2245 | − num_matched_functions = 0; | |
| 2246 | − looking_function_name = pp->function; | |
| 2247 | − ret = map__load(map, probe_function_filter); | |
| 2248 | − if (ret || num_matched_functions == 0) { | |
| 2244 | + num_matched_functions = find_probe_functions(map, pp->function); | |
| 2245 | + if (num_matched_functions == 0) { | |
| 2249 | 2246 | pr_err("Failed to find symbol %s in %s\n", pp->function, |
| 2250 | 2247 | target ? : "kernel"); |
| 2251 | 2248 | ret = -ENOENT; |
| @@ -2257,7 +2254,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 5 unmodified lines | ||
| 2257 | 2254 | goto out; |
| 2258 | 2255 | } |
| 2259 | 2256 | |
| 2260 | − if (!pev->uprobes) { | |
| 2257 | + if (!pev->uprobes && !pp->retprobe) { | |
| 2261 | 2258 | kmap = map__kmap(map); |
| 2262 | 2259 | reloc_sym = kmap->ref_reloc_sym; |
| 2263 | 2260 | if (!reloc_sym) { |
| @@ -2275,7 +2272,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, · 11 unmodified lines | ||
| 2275 | 2272 | } |
| 2276 | 2273 | |
| 2277 | 2274 | ret = 0; |
| 2278 | − map__for_each_symbol(map, sym, nd) { | |
| 2275 | + | |
| 2276 | + map__for_each_symbol_by_name(map, pp->function, sym) { | |
| 2279 | 2277 | tev = (*tevs) + ret; |
| 2280 | 2278 | tp = &tev->point; |
| 2281 | 2279 | if (ret == num_matched_functions) { |
| @@ -396,6 +396,7 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, · 395 unmodified lines | ||
| 396 | 396 | const char *name) |
| 397 | 397 | { |
| 398 | 398 | struct rb_node *n; |
| 399 | + struct symbol_name_rb_node *s; | |
| 399 | 400 | |
| 400 | 401 | if (symbols == NULL) |
| 401 | 402 | return NULL; |
| @@ -403,7 +404,6 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, · 1 unmodified line | ||
| 403 | 404 | n = symbols->rb_node; |
| 404 | 405 | |
| 405 | 406 | while (n) { |
| 406 | − struct symbol_name_rb_node *s; | |
| 407 | 407 | int cmp; |
| 408 | 408 | |
| 409 | 409 | s = rb_entry(n, struct symbol_name_rb_node, rb_node); |
| @@ -414,10 +414,24 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, · 4 unmodified lines | ||
| 414 | 414 | else if (cmp > 0) |
| 415 | 415 | n = n->rb_right; |
| 416 | 416 | else |
| 417 | − return &s->sym; | |
| 417 | + break; | |
| 418 | 418 | } |
| 419 | 419 | |
| 420 | − return NULL; | |
| 420 | + if (n == NULL) | |
| 421 | + return NULL; | |
| 422 | + | |
| 423 | + /* return first symbol that has same name (if any) */ | |
| 424 | + for (n = rb_prev(n); n; n = rb_prev(n)) { | |
| 425 | + struct symbol_name_rb_node *tmp; | |
| 426 | + | |
| 427 | + tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); | |
| 428 | + if (strcmp(tmp->sym.name, s->sym.name)) | |
| 429 | + break; | |
| 430 | + | |
| 431 | + s = tmp; | |
| 432 | + } | |
| 433 | + | |
| 434 | + return &s->sym; | |
| 421 | 435 | } |
| 422 | 436 | |
| 423 | 437 | struct symbol *dso__find_symbol(struct dso *dso, |
| @@ -436,6 +450,17 @@ struct symbol *dso__next_symbol(struct symbol *sym) · 12 unmodified lines | ||
| 436 | 450 | return symbols__next(sym); |
| 437 | 451 | } |
| 438 | 452 | |
| 453 | +struct symbol *symbol__next_by_name(struct symbol *sym) | |
| 454 | +{ | |
| 455 | + struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym); | |
| 456 | + struct rb_node *n = rb_next(&s->rb_node); | |
| 457 | + | |
| 458 | + return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL; | |
| 459 | +} | |
| 460 | + | |
| 461 | + /* | |
| 462 | + * Teturns first symbol that matched with @name. | |
| 463 | + */ | |
| 439 | 464 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, |
| 440 | 465 | const char *name) |
| 441 | 466 | { |
| @@ -231,6 +231,7 @@ struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, · 230 unmodified lines | ||
| 231 | 231 | u64 addr); |
| 232 | 232 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, |
| 233 | 233 | const char *name); |
| 234 | +struct symbol *symbol__next_by_name(struct symbol *sym); | |
| 234 | 235 | |
| 235 | 236 | struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); |
| 236 | 237 | struct symbol *dso__next_symbol(struct symbol *sym); |