Cross-merge networking fixes after downstream PR. Conflicts: drivers/net/phy/aquantia/aquantia.h 219343755eae ("net: phy: aquantia: add missing include guards") 61578f679378 ("net: phy: aquantia: add support for PHY LEDs") drivers/net/ethernet/wangxun/libwx/wx_hw.c bd07a9817846 ("net: txgbe: remove separate irq request for MSI and INTx") b501d261a5b3 ("net: txgbe: add FDIR ATR support") https://lore.kernel.org/all/20240703112936.483c1975@canb.auug.org.au/ include/linux/mlx5/mlx5_ifc.h 048a403648fc ("net/mlx5: IFC updates for changing max EQs") 99be56171fa9 ("net/mlx5e: SHAMPO, Re-enable HW-GRO") https://lore.kernel.org/all/20240701133951.6926b2e3@canb.auug.org.au/ Adjacent changes: drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 4130c67cd123 ("wifi: iwlwifi: mvm: check vif for NULL/ERR_PTR before dereference") 3f3126515fbe ("wifi: iwlwifi: mvm: add mvm-specific guard") include/net/mac80211.h 816c6bec09ed ("wifi: mac80211: fix BSS_CHANGED_UNSOL_BCAST_PROBE_RESP") 5a009b42e041 ("wifi: mac80211: track changes in AP's TPE")
Unified · Split
| @@ -788,25 +788,6 @@ · 787 unmodified lines | ||
| 788 | 788 | Documentation/networking/netconsole.rst for an |
| 789 | 789 | alternative. |
| 790 | 790 | |
| 791 | − <DEVNAME>:<n>.<n>[,options] | |
| 792 | − Use the specified serial port on the serial core bus. | |
| 793 | − The addressing uses DEVNAME of the physical serial port | |
| 794 | − device, followed by the serial core controller instance, | |
| 795 | − and the serial port instance. The options are the same | |
| 796 | − as documented for the ttyS addressing above. | |
| 797 | − | |
| 798 | − The mapping of the serial ports to the tty instances | |
| 799 | − can be viewed with: | |
| 800 | − | |
| 801 | − $ ls -d /sys/bus/serial-base/devices/*:*.*/tty/* | |
| 802 | − /sys/bus/serial-base/devices/00:04:0.0/tty/ttyS0 | |
| 803 | − | |
| 804 | − In the above example, the console can be addressed with | |
| 805 | − console=00:04:0.0. Note that a console addressed this | |
| 806 | − way will only get added when the related device driver | |
| 807 | − is ready. The use of an earlycon parameter in addition to | |
| 808 | − the console may be desired for console output early on. | |
| 809 | − | |
| 810 | 791 | uart[8250],io,<addr>[,options] |
| 811 | 792 | uart[8250],mmio,<addr>[,options] |
| 812 | 793 | uart[8250],mmio16,<addr>[,options] |
| @@ -328,6 +328,12 @@ CXL Memory Device · 327 unmodified lines | ||
| 328 | 328 | .. kernel-doc:: drivers/cxl/mem.c |
| 329 | 329 | :doc: cxl mem |
| 330 | 330 | |
| 331 | +.. kernel-doc:: drivers/cxl/cxlmem.h | |
| 332 | + :internal: | |
| 333 | + | |
| 334 | +.. kernel-doc:: drivers/cxl/core/memdev.c | |
| 335 | + :identifiers: | |
| 336 | + | |
| 331 | 337 | CXL Port |
| 332 | 338 | -------- |
| 333 | 339 | .. kernel-doc:: drivers/cxl/port.c |
| @@ -341,6 +347,15 @@ CXL Core · 7 unmodified lines | ||
| 341 | 347 | .. kernel-doc:: drivers/cxl/cxl.h |
| 342 | 348 | :internal: |
| 343 | 349 | |
| 350 | +.. kernel-doc:: drivers/cxl/core/hdm.c | |
| 351 | + :doc: cxl core hdm | |
| 352 | + | |
| 353 | +.. kernel-doc:: drivers/cxl/core/hdm.c | |
| 354 | + :identifiers: | |
| 355 | + | |
| 356 | +.. kernel-doc:: drivers/cxl/core/cdat.c | |
| 357 | + :identifiers: | |
| 358 | + | |
| 344 | 359 | .. kernel-doc:: drivers/cxl/core/port.c |
| 345 | 360 | :doc: cxl core |
| 346 | 361 | |
| @@ -128,7 +128,7 @@ executed to make module versioning work. · 127 unmodified lines | ||
| 128 | 128 | |
| 129 | 129 | modules_install |
| 130 | 130 | Install the external module(s). The default location is |
| 131 | − /lib/modules/<kernel_release>/extra/, but a prefix may | |
| 131 | + /lib/modules/<kernel_release>/updates/, but a prefix may | |
| 132 | 132 | be added with INSTALL_MOD_PATH (discussed in section 5). |
| 133 | 133 | |
| 134 | 134 | clean |
| @@ -417,7 +417,7 @@ directory: · 282 unmodified lines | ||
| 417 | 417 | |
| 418 | 418 | And external modules are installed in: |
| 419 | 419 | |
| 420 | − /lib/modules/$(KERNELRELEASE)/extra/ | |
| 420 | + /lib/modules/$(KERNELRELEASE)/updates/ | |
| 421 | 421 | |
| 422 | 422 | 5.1 INSTALL_MOD_PATH |
| 423 | 423 | -------------------- |
| @@ -438,10 +438,10 @@ And external modules are installed in: · 14 unmodified lines | ||
| 438 | 438 | ------------------- |
| 439 | 439 | |
| 440 | 440 | External modules are by default installed to a directory under |
| 441 | − /lib/modules/$(KERNELRELEASE)/extra/, but you may wish to | |
| 441 | + /lib/modules/$(KERNELRELEASE)/updates/, but you may wish to | |
| 442 | 442 | locate modules for a specific functionality in a separate |
| 443 | 443 | directory. For this purpose, use INSTALL_MOD_DIR to specify an |
| 444 | − alternative name to "extra.":: | |
| 444 | + alternative name to "updates.":: | |
| 445 | 445 | |
| 446 | 446 | $ make INSTALL_MOD_DIR=gandalf -C $KDIR \ |
| 447 | 447 | M=$PWD modules_install |
| @@ -186,6 +186,7 @@ Code Seq# Include File Comments · 185 unmodified lines | ||
| 186 | 186 | 'Q' all linux/soundcard.h |
| 187 | 187 | 'R' 00-1F linux/random.h conflict! |
| 188 | 188 | 'R' 01 linux/rfkill.h conflict! |
| 189 | +'R' 20-2F linux/trace_mmap.h | |
| 189 | 190 | 'R' C0-DF net/bluetooth/rfcomm.h |
| 190 | 191 | 'R' E0 uapi/linux/fsl_mc.h |
| 191 | 192 | 'S' all linux/cdrom.h conflict! |
| @@ -1044,7 +1044,7 @@ M: Joerg Roedel <joro@8bytes.org> · 1043 unmodified lines | ||
| 1044 | 1044 | R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> |
| 1045 | 1045 | L: iommu@lists.linux.dev |
| 1046 | 1046 | S: Maintained |
| 1047 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | |
| 1047 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git | |
| 1048 | 1048 | F: drivers/iommu/amd/ |
| 1049 | 1049 | F: include/linux/amd-iommu.h |
| 1050 | 1050 | |
| @@ -11157,7 +11157,7 @@ M: David Woodhouse <dwmw2@infradead.org> · 10106 unmodified lines | ||
| 11157 | 11157 | M: Lu Baolu <baolu.lu@linux.intel.com> |
| 11158 | 11158 | L: iommu@lists.linux.dev |
| 11159 | 11159 | S: Supported |
| 11160 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | |
| 11160 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git | |
| 11161 | 11161 | F: drivers/iommu/intel/ |
| 11162 | 11162 | |
| 11163 | 11163 | INTEL IPU3 CSI-2 CIO2 DRIVER |
| @@ -11530,7 +11530,7 @@ IOMMU DMA-API LAYER · 366 unmodified lines | ||
| 11530 | 11530 | M: Robin Murphy <robin.murphy@arm.com> |
| 11531 | 11531 | L: iommu@lists.linux.dev |
| 11532 | 11532 | S: Maintained |
| 11533 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | |
| 11533 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git | |
| 11534 | 11534 | F: drivers/iommu/dma-iommu.c |
| 11535 | 11535 | F: drivers/iommu/dma-iommu.h |
| 11536 | 11536 | F: drivers/iommu/iova.c |
| @@ -11542,7 +11542,7 @@ M: Will Deacon <will@kernel.org> · 5 unmodified lines | ||
| 11542 | 11542 | R: Robin Murphy <robin.murphy@arm.com> |
| 11543 | 11543 | L: iommu@lists.linux.dev |
| 11544 | 11544 | S: Maintained |
| 11545 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | |
| 11545 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git | |
| 11546 | 11546 | F: Documentation/devicetree/bindings/iommu/ |
| 11547 | 11547 | F: Documentation/userspace-api/iommu.rst |
| 11548 | 11548 | F: drivers/iommu/ |
| @@ -19324,7 +19324,7 @@ F: drivers/perf/riscv_pmu_legacy.c · 7775 unmodified lines | ||
| 19324 | 19324 | F: drivers/perf/riscv_pmu_sbi.c |
| 19325 | 19325 | |
| 19326 | 19326 | RISC-V THEAD SoC SUPPORT |
| 19327 | −M: Jisheng Zhang <jszhang@kernel.org> | |
| 19327 | +M: Drew Fustini <drew@pdp7.com> | |
| 19328 | 19328 | M: Guo Ren <guoren@kernel.org> |
| 19329 | 19329 | M: Fu Wei <wefu@redhat.com> |
| 19330 | 19330 | L: linux-riscv@lists.infradead.org |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 10 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc5 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -128,6 +128,7 @@ · 127 unmodified lines | ||
| 128 | 128 | pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>; |
| 129 | 129 | power-domains = <&power RK3066_PD_VIO>; |
| 130 | 130 | rockchip,grf = <&grf>; |
| 131 | + #sound-dai-cells = <0>; | |
| 131 | 132 | status = "disabled"; |
| 132 | 133 | |
| 133 | 134 | ports { |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | /dts-v1/; |
| 8 | + | |
| 9 | +#include <dt-bindings/leds/common.h> | |
| 8 | 10 | #include "rk3308.dtsi" |
| 9 | 11 | |
| 10 | 12 | / { |
| @@ -24,17 +26,21 @@ · 13 unmodified lines | ||
| 24 | 26 | leds { |
| 25 | 27 | compatible = "gpio-leds"; |
| 26 | 28 | pinctrl-names = "default"; |
| 27 | − pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>; | |
| 29 | + pinctrl-0 = <&green_led>, <&heartbeat_led>; | |
| 28 | 30 | |
| 29 | 31 | green-led { |
| 32 | + color = <LED_COLOR_ID_GREEN>; | |
| 30 | 33 | default-state = "on"; |
| 34 | + function = LED_FUNCTION_POWER; | |
| 31 | 35 | gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; |
| 32 | 36 | label = "rockpis:green:power"; |
| 33 | 37 | linux,default-trigger = "default-on"; |
| 34 | 38 | }; |
| 35 | 39 | |
| 36 | 40 | blue-led { |
| 41 | + color = <LED_COLOR_ID_BLUE>; | |
| 37 | 42 | default-state = "on"; |
| 43 | + function = LED_FUNCTION_HEARTBEAT; | |
| 38 | 44 | gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; |
| 39 | 45 | label = "rockpis:blue:user"; |
| 40 | 46 | linux,default-trigger = "heartbeat"; |
| @@ -126,10 +132,12 @@ · 85 unmodified lines | ||
| 126 | 132 | }; |
| 127 | 133 | |
| 128 | 134 | &emmc { |
| 129 | − bus-width = <4>; | |
| 130 | 135 | cap-mmc-highspeed; |
| 131 | − mmc-hs200-1_8v; | |
| 136 | + cap-sd-highspeed; | |
| 137 | + no-sdio; | |
| 132 | 138 | non-removable; |
| 139 | + pinctrl-names = "default"; | |
| 140 | + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>; | |
| 133 | 141 | vmmc-supply = <&vcc_io>; |
| 134 | 142 | status = "okay"; |
| 135 | 143 | }; |
| @@ -214,11 +222,11 @@ · 78 unmodified lines | ||
| 214 | 222 | pinctrl-0 = <&rtc_32k>; |
| 215 | 223 | |
| 216 | 224 | leds { |
| 217 | − green_led_gio: green-led-gpio { | |
| 225 | + green_led: green-led { | |
| 218 | 226 | rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; |
| 219 | 227 | }; |
| 220 | 228 | |
| 221 | − heartbeat_led_gpio: heartbeat-led-gpio { | |
| 229 | + heartbeat_led: heartbeat-led { | |
| 222 | 230 | rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; |
| 223 | 231 | }; |
| 224 | 232 | }; |
| @@ -811,7 +811,7 @@ · 810 unmodified lines | ||
| 811 | 811 | clocks = <&cru SCLK_I2S2_8CH_TX_OUT>, |
| 812 | 812 | <&cru SCLK_I2S2_8CH_RX_OUT>, |
| 813 | 813 | <&cru PCLK_ACODEC>; |
| 814 | − reset-names = "codec-reset"; | |
| 814 | + reset-names = "codec"; | |
| 815 | 815 | resets = <&cru SRST_ACODEC_P>; |
| 816 | 816 | #sound-dai-cells = <0>; |
| 817 | 817 | status = "disabled"; |
| @@ -241,8 +241,8 @@ · 240 unmodified lines | ||
| 241 | 241 | rk805: pmic@18 { |
| 242 | 242 | compatible = "rockchip,rk805"; |
| 243 | 243 | reg = <0x18>; |
| 244 | − interrupt-parent = <&gpio2>; | |
| 245 | − interrupts = <6 IRQ_TYPE_LEVEL_LOW>; | |
| 244 | + interrupt-parent = <&gpio0>; | |
| 245 | + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; | |
| 246 | 246 | #clock-cells = <1>; |
| 247 | 247 | clock-output-names = "xin32k", "rk805-clkout2"; |
| 248 | 248 | gpio-controller; |
| @@ -793,6 +793,7 @@ · 792 unmodified lines | ||
| 793 | 793 | dma-names = "tx"; |
| 794 | 794 | pinctrl-names = "default"; |
| 795 | 795 | pinctrl-0 = <&spdif_tx>; |
| 796 | + #sound-dai-cells = <0>; | |
| 796 | 797 | status = "disabled"; |
| 797 | 798 | }; |
| 798 | 799 | |
| @@ -804,6 +805,7 @@ · 5 unmodified lines | ||
| 804 | 805 | clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>; |
| 805 | 806 | dmas = <&dmac_bus 6>, <&dmac_bus 7>; |
| 806 | 807 | dma-names = "tx", "rx"; |
| 808 | + #sound-dai-cells = <0>; | |
| 807 | 809 | status = "disabled"; |
| 808 | 810 | }; |
| 809 | 811 | |
| @@ -817,6 +819,7 @@ · 7 unmodified lines | ||
| 817 | 819 | dma-names = "tx", "rx"; |
| 818 | 820 | pinctrl-names = "default"; |
| 819 | 821 | pinctrl-0 = <&i2s_8ch_bus>; |
| 822 | + #sound-dai-cells = <0>; | |
| 820 | 823 | status = "disabled"; |
| 821 | 824 | }; |
| 822 | 825 | |
| @@ -450,7 +450,7 @@ ap_i2c_audio: &i2c8 { · 449 unmodified lines | ||
| 450 | 450 | dlg,btn-cfg = <50>; |
| 451 | 451 | dlg,mic-det-thr = <500>; |
| 452 | 452 | dlg,jack-ins-deb = <20>; |
| 453 | − dlg,jack-det-rate = "32ms_64ms"; | |
| 453 | + dlg,jack-det-rate = "32_64"; | |
| 454 | 454 | dlg,jack-rem-deb = <1>; |
| 455 | 455 | |
| 456 | 456 | dlg,a-d-btn-thr = <0xa>; |
| @@ -289,7 +289,7 @@ · 288 unmodified lines | ||
| 289 | 289 | regulator-name = "vdd_gpu"; |
| 290 | 290 | regulator-always-on; |
| 291 | 291 | regulator-boot-on; |
| 292 | − regulator-min-microvolt = <900000>; | |
| 292 | + regulator-min-microvolt = <500000>; | |
| 293 | 293 | regulator-max-microvolt = <1350000>; |
| 294 | 294 | regulator-ramp-delay = <6001>; |
| 295 | 295 | |
| @@ -444,6 +444,7 @@ · 443 unmodified lines | ||
| 444 | 444 | &sdmmc { |
| 445 | 445 | bus-width = <4>; |
| 446 | 446 | cap-sd-highspeed; |
| 447 | + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; | |
| 447 | 448 | disable-wp; |
| 448 | 449 | max-frequency = <150000000>; |
| 449 | 450 | no-sdio; |
| @@ -435,6 +435,7 @@ · 434 unmodified lines | ||
| 435 | 435 | &sdmmc { |
| 436 | 436 | bus-width = <4>; |
| 437 | 437 | cap-sd-highspeed; |
| 438 | + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; | |
| 438 | 439 | disable-wp; |
| 439 | 440 | max-frequency = <150000000>; |
| 440 | 441 | no-sdio; |
| @@ -383,6 +383,7 @@ · 382 unmodified lines | ||
| 383 | 383 | bus-width = <4>; |
| 384 | 384 | cap-mmc-highspeed; |
| 385 | 385 | cap-sd-highspeed; |
| 386 | + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; | |
| 386 | 387 | disable-wp; |
| 387 | 388 | sd-uhs-sdr104; |
| 388 | 389 | vmmc-supply = <&vcc_3v3_s3>; |
| @@ -344,6 +344,11 @@ · 343 unmodified lines | ||
| 344 | 344 | }; |
| 345 | 345 | }; |
| 346 | 346 | |
| 347 | +&pwm0 { | |
| 348 | + pinctrl-0 = <&pwm0m1_pins>; | |
| 349 | + pinctrl-names = "default"; | |
| 350 | +}; | |
| 351 | + | |
| 347 | 352 | &saradc { |
| 348 | 353 | vref-supply = <&vcc_1v8_s0>; |
| 349 | 354 | status = "okay"; |
| @@ -288,9 +288,9 @@ · 287 unmodified lines | ||
| 288 | 288 | pinctrl-0 = <&i2c7m0_xfer>; |
| 289 | 289 | status = "okay"; |
| 290 | 290 | |
| 291 | − es8316: audio-codec@11 { | |
| 291 | + es8316: audio-codec@10 { | |
| 292 | 292 | compatible = "everest,es8316"; |
| 293 | − reg = <0x11>; | |
| 293 | + reg = <0x10>; | |
| 294 | 294 | assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; |
| 295 | 295 | assigned-clock-rates = <12288000>; |
| 296 | 296 | clocks = <&cru I2S0_8CH_MCLKOUT>; |
| @@ -366,6 +366,7 @@ · 365 unmodified lines | ||
| 366 | 366 | bus-width = <4>; |
| 367 | 367 | cap-mmc-highspeed; |
| 368 | 368 | cap-sd-highspeed; |
| 369 | + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; | |
| 369 | 370 | disable-wp; |
| 370 | 371 | max-frequency = <150000000>; |
| 371 | 372 | no-sdio; |
| @@ -393,6 +394,7 @@ · 21 unmodified lines | ||
| 393 | 394 | pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, |
| 394 | 395 | <&rk806_dvs2_null>, <&rk806_dvs3_null>; |
| 395 | 396 | spi-max-frequency = <1000000>; |
| 397 | + system-power-controller; | |
| 396 | 398 | |
| 397 | 399 | vcc1-supply = <&vcc5v0_sys>; |
| 398 | 400 | vcc2-supply = <&vcc5v0_sys>; |
| @@ -170,6 +170,7 @@ · 169 unmodified lines | ||
| 170 | 170 | #define PTE_CONT (_AT(pteval_t, 1) << 52) /* Contiguous range */ |
| 171 | 171 | #define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ |
| 172 | 172 | #define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ |
| 173 | +#define PTE_SWBITS_MASK _AT(pteval_t, (BIT(63) | GENMASK(58, 55))) | |
| 173 | 174 | |
| 174 | 175 | #define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (50 - PAGE_SHIFT)) - 1) << PAGE_SHIFT) |
| 175 | 176 | #ifdef CONFIG_ARM64_PA_BITS_52 |
| @@ -840,7 +840,7 @@ __SYSCALL(__NR_pselect6_time64, compat_sys_pselect6_time64) · 839 unmodified lines | ||
| 840 | 840 | #define __NR_ppoll_time64 414 |
| 841 | 841 | __SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64) |
| 842 | 842 | #define __NR_io_pgetevents_time64 416 |
| 843 | −__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) | |
| 843 | +__SYSCALL(__NR_io_pgetevents_time64, compat_sys_io_pgetevents_time64) | |
| 844 | 844 | #define __NR_recvmmsg_time64 417 |
| 845 | 845 | __SYSCALL(__NR_recvmmsg_time64, compat_sys_recvmmsg_time64) |
| 846 | 846 | #define __NR_mq_timedsend_time64 418 |
| @@ -173,7 +173,7 @@ static void __init remap_idmap_for_lpa2(void) · 172 unmodified lines | ||
| 173 | 173 | * Don't bother with the FDT, we no longer need it after this. |
| 174 | 174 | */ |
| 175 | 175 | memset(init_idmap_pg_dir, 0, |
| 176 | − (u64)init_idmap_pg_dir - (u64)init_idmap_pg_end); | |
| 176 | + (u64)init_idmap_pg_end - (u64)init_idmap_pg_dir); | |
| 177 | 177 | |
| 178 | 178 | create_init_idmap(init_idmap_pg_dir, mask); |
| 179 | 179 | dsb(ishst); |
| @@ -53,17 +53,15 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno, · 52 unmodified lines | ||
| 53 | 53 | syscall_set_return_value(current, regs, 0, ret); |
| 54 | 54 | |
| 55 | 55 | /* |
| 56 | − * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), | |
| 57 | − * but not enough for arm64 stack utilization comfort. To keep | |
| 58 | − * reasonable stack head room, reduce the maximum offset to 9 bits. | |
| 56 | + * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 | |
| 57 | + * bits. The actual entropy will be further reduced by the compiler | |
| 58 | + * when applying stack alignment constraints: the AAPCS mandates a | |
| 59 | + * 16-byte aligned SP at function boundaries, which will remove the | |
| 60 | + * 4 low bits from any entropy chosen here. | |
| 59 | 61 | * |
| 60 | − * The actual entropy will be further reduced by the compiler when | |
| 61 | − * applying stack alignment constraints: the AAPCS mandates a | |
| 62 | − * 16-byte (i.e. 4-bit) aligned SP at function boundaries. | |
| 63 | − * | |
| 64 | − * The resulting 5 bits of entropy is seen in SP[8:4]. | |
| 62 | + * The resulting 6 bits of entropy is seen in SP[9:4]. | |
| 65 | 63 | */ |
| 66 | − choose_random_kstack_offset(get_random_u16() & 0x1FF); | |
| 64 | + choose_random_kstack_offset(get_random_u16()); | |
| 67 | 65 | } |
| 68 | 66 | |
| 69 | 67 | static inline bool has_syscall_work(unsigned long flags) |
| @@ -124,7 +124,8 @@ bool pgattr_change_is_safe(u64 old, u64 new) · 123 unmodified lines | ||
| 124 | 124 | * The following mapping attributes may be updated in live |
| 125 | 125 | * kernel mappings without the need for break-before-make. |
| 126 | 126 | */ |
| 127 | − pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG; | |
| 127 | + pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG | | |
| 128 | + PTE_SWBITS_MASK; | |
| 128 | 129 | |
| 129 | 130 | /* creating or taking down mappings is always safe */ |
| 130 | 131 | if (!pte_valid(__pte(old)) || !pte_valid(__pte(new))) |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #define __ARCH_WANT_SYS_CLONE3 |
| 7 | 7 | #define __ARCH_WANT_SET_GET_RLIMIT |
| 8 | 8 | #define __ARCH_WANT_TIME32_SYSCALLS |
| 9 | +#define __ARCH_WANT_SYNC_FILE_RANGE2 | |
| 9 | 10 | #include <asm-generic/unistd.h> |
| 10 | 11 | |
| 11 | 12 | #define __NR_set_thread_area (__NR_arch_specific_syscall + 0) |
| @@ -20,7 +20,7 @@ SYSCALL_DEFINE6(mmap2, · 19 unmodified lines | ||
| 20 | 20 | unsigned long, prot, |
| 21 | 21 | unsigned long, flags, |
| 22 | 22 | unsigned long, fd, |
| 23 | − off_t, offset) | |
| 23 | + unsigned long, offset) | |
| 24 | 24 | { |
| 25 | 25 | if (unlikely(offset & (~PAGE_MASK >> 12))) |
| 26 | 26 | return -EINVAL; |
| @@ -0,0 +1,6 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | + | |
| 3 | +#include <asm-generic/syscalls.h> | |
| 4 | + | |
| 5 | +asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice, | |
| 6 | + u32 a2, u32 a3, u32 a4, u32 a5); | |
| @@ -36,5 +36,6 @@ · 35 unmodified lines | ||
| 36 | 36 | #define __ARCH_WANT_SYS_VFORK |
| 37 | 37 | #define __ARCH_WANT_SYS_FORK |
| 38 | 38 | #define __ARCH_WANT_TIME32_SYSCALLS |
| 39 | +#define __ARCH_WANT_SYNC_FILE_RANGE2 | |
| 39 | 40 | |
| 40 | 41 | #include <asm-generic/unistd.h> |
| @@ -14,6 +14,13 @@ · 13 unmodified lines | ||
| 14 | 14 | #undef __SYSCALL |
| 15 | 15 | #define __SYSCALL(nr, call) [nr] = (call), |
| 16 | 16 | |
| 17 | +SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice, | |
| 18 | + SC_ARG64(offset), SC_ARG64(len)) | |
| 19 | +{ | |
| 20 | + return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice); | |
| 21 | +} | |
| 22 | +#define sys_fadvise64_64 sys_hexagon_fadvise64_64 | |
| 23 | + | |
| 17 | 24 | void *sys_call_table[__NR_syscalls] = { |
| 18 | 25 | #include <asm/unistd.h> |
| 19 | 26 | }; |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #define __SYSCALL(nr, call) [nr] = (call), |
| 23 | 23 | |
| 24 | 24 | SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long, |
| 25 | − prot, unsigned long, flags, unsigned long, fd, off_t, offset) | |
| 25 | + prot, unsigned long, flags, unsigned long, fd, unsigned long, offset) | |
| 26 | 26 | { |
| 27 | 27 | if (offset & ~PAGE_MASK) |
| 28 | 28 | return -EINVAL; |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, |
| 37 | 37 | unsigned long, prot, unsigned long, flags, unsigned long, fd, |
| 38 | − off_t, pgoff) | |
| 38 | + unsigned long, pgoff) | |
| 39 | 39 | { |
| 40 | 40 | if (pgoff & ~PAGE_MASK) |
| 41 | 41 | return -EINVAL; |
| @@ -354,7 +354,7 @@ · 353 unmodified lines | ||
| 354 | 354 | 412 n32 utimensat_time64 sys_utimensat |
| 355 | 355 | 413 n32 pselect6_time64 compat_sys_pselect6_time64 |
| 356 | 356 | 414 n32 ppoll_time64 compat_sys_ppoll_time64 |
| 357 | −416 n32 io_pgetevents_time64 sys_io_pgetevents | |
| 357 | +416 n32 io_pgetevents_time64 compat_sys_io_pgetevents_time64 | |
| 358 | 358 | 417 n32 recvmmsg_time64 compat_sys_recvmmsg_time64 |
| 359 | 359 | 418 n32 mq_timedsend_time64 sys_mq_timedsend |
| 360 | 360 | 419 n32 mq_timedreceive_time64 sys_mq_timedreceive |
| @@ -403,7 +403,7 @@ · 402 unmodified lines | ||
| 403 | 403 | 412 o32 utimensat_time64 sys_utimensat sys_utimensat |
| 404 | 404 | 413 o32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 |
| 405 | 405 | 414 o32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 |
| 406 | −416 o32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents | |
| 406 | +416 o32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 | |
| 407 | 407 | 417 o32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 |
| 408 | 408 | 418 o32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend |
| 409 | 409 | 419 o32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive |
| @@ -16,6 +16,7 @@ config PARISC · 15 unmodified lines | ||
| 16 | 16 | select ARCH_HAS_UBSAN |
| 17 | 17 | select ARCH_HAS_PTE_SPECIAL |
| 18 | 18 | select ARCH_NO_SG_CHAIN |
| 19 | + select ARCH_SPLIT_ARG64 if !64BIT | |
| 19 | 20 | select ARCH_SUPPORTS_HUGETLBFS if PA20 |
| 20 | 21 | select ARCH_SUPPORTS_MEMORY_FAILURE |
| 21 | 22 | select ARCH_STACKWALK |
| @@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, · 22 unmodified lines | ||
| 23 | 23 | current->comm, current->pid, r20); |
| 24 | 24 | return -ENOSYS; |
| 25 | 25 | } |
| 26 | − | |
| 27 | −asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags, | |
| 28 | − compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd, | |
| 29 | − const char __user * pathname) | |
| 30 | −{ | |
| 31 | − return sys_fanotify_mark(fanotify_fd, flags, | |
| 32 | − ((__u64)mask1 << 32) | mask0, | |
| 33 | − dfd, pathname); | |
| 34 | −} | |
| @@ -108,7 +108,7 @@ · 107 unmodified lines | ||
| 108 | 108 | 95 common fchown sys_fchown |
| 109 | 109 | 96 common getpriority sys_getpriority |
| 110 | 110 | 97 common setpriority sys_setpriority |
| 111 | −98 common recv sys_recv | |
| 111 | +98 common recv sys_recv compat_sys_recv | |
| 112 | 112 | 99 common statfs sys_statfs compat_sys_statfs |
| 113 | 113 | 100 common fstatfs sys_fstatfs compat_sys_fstatfs |
| 114 | 114 | 101 common stat64 sys_stat64 |
| @@ -135,7 +135,7 @@ · 20 unmodified lines | ||
| 135 | 135 | 120 common clone sys_clone_wrapper |
| 136 | 136 | 121 common setdomainname sys_setdomainname |
| 137 | 137 | 122 common sendfile sys_sendfile compat_sys_sendfile |
| 138 | −123 common recvfrom sys_recvfrom | |
| 138 | +123 common recvfrom sys_recvfrom compat_sys_recvfrom | |
| 139 | 139 | 124 32 adjtimex sys_adjtimex_time32 |
| 140 | 140 | 124 64 adjtimex sys_adjtimex |
| 141 | 141 | 125 common mprotect sys_mprotect |
| @@ -364,7 +364,7 @@ · 222 unmodified lines | ||
| 364 | 364 | 320 common accept4 sys_accept4 |
| 365 | 365 | 321 common prlimit64 sys_prlimit64 |
| 366 | 366 | 322 common fanotify_init sys_fanotify_init |
| 367 | −323 common fanotify_mark sys_fanotify_mark sys32_fanotify_mark | |
| 367 | +323 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark | |
| 368 | 368 | 324 32 clock_adjtime sys_clock_adjtime32 |
| 369 | 369 | 324 64 clock_adjtime sys_clock_adjtime |
| 370 | 370 | 325 common name_to_handle_at sys_name_to_handle_at |
| @@ -230,8 +230,10 @@ · 229 unmodified lines | ||
| 230 | 230 | 178 nospu rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend |
| 231 | 231 | 179 32 pread64 sys_ppc_pread64 compat_sys_ppc_pread64 |
| 232 | 232 | 179 64 pread64 sys_pread64 |
| 233 | +179 spu pread64 sys_pread64 | |
| 233 | 234 | 180 32 pwrite64 sys_ppc_pwrite64 compat_sys_ppc_pwrite64 |
| 234 | 235 | 180 64 pwrite64 sys_pwrite64 |
| 236 | +180 spu pwrite64 sys_pwrite64 | |
| 235 | 237 | 181 common chown sys_chown |
| 236 | 238 | 182 common getcwd sys_getcwd |
| 237 | 239 | 183 common capget sys_capget |
| @@ -246,6 +248,7 @@ · 8 unmodified lines | ||
| 246 | 248 | 190 common ugetrlimit sys_getrlimit compat_sys_getrlimit |
| 247 | 249 | 191 32 readahead sys_ppc_readahead compat_sys_ppc_readahead |
| 248 | 250 | 191 64 readahead sys_readahead |
| 251 | +191 spu readahead sys_readahead | |
| 249 | 252 | 192 32 mmap2 sys_mmap2 compat_sys_mmap2 |
| 250 | 253 | 193 32 truncate64 sys_ppc_truncate64 compat_sys_ppc_truncate64 |
| 251 | 254 | 194 32 ftruncate64 sys_ppc_ftruncate64 compat_sys_ppc_ftruncate64 |
| @@ -293,6 +296,7 @@ · 41 unmodified lines | ||
| 293 | 296 | 232 nospu set_tid_address sys_set_tid_address |
| 294 | 297 | 233 32 fadvise64 sys_ppc32_fadvise64 compat_sys_ppc32_fadvise64 |
| 295 | 298 | 233 64 fadvise64 sys_fadvise64 |
| 299 | +233 spu fadvise64 sys_fadvise64 | |
| 296 | 300 | 234 nospu exit_group sys_exit_group |
| 297 | 301 | 235 nospu lookup_dcookie sys_ni_syscall |
| 298 | 302 | 236 common epoll_create sys_epoll_create |
| @@ -502,7 +506,7 @@ · 203 unmodified lines | ||
| 502 | 506 | 412 32 utimensat_time64 sys_utimensat sys_utimensat |
| 503 | 507 | 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 |
| 504 | 508 | 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 |
| 505 | −416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents | |
| 509 | +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 | |
| 506 | 510 | 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 |
| 507 | 511 | 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend |
| 508 | 512 | 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive |
| @@ -15,6 +15,10 @@ · 14 unmodified lines | ||
| 15 | 15 | model = "Kendryte KD233"; |
| 16 | 16 | compatible = "canaan,kendryte-kd233", "canaan,kendryte-k210"; |
| 17 | 17 | |
| 18 | + aliases { | |
| 19 | + serial0 = &uarths0; | |
| 20 | + }; | |
| 21 | + | |
| 18 | 22 | chosen { |
| 19 | 23 | bootargs = "earlycon console=ttySIF0"; |
| 20 | 24 | stdout-path = "serial0:115200n8"; |
| @@ -46,7 +50,6 @@ · 25 unmodified lines | ||
| 46 | 50 | &fpioa { |
| 47 | 51 | pinctrl-0 = <&jtag_pinctrl>; |
| 48 | 52 | pinctrl-names = "default"; |
| 49 | − status = "okay"; | |
| 50 | 53 | |
| 51 | 54 | jtag_pinctrl: jtag-pinmux { |
| 52 | 55 | pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>, |
| @@ -118,6 +121,7 @@ · 65 unmodified lines | ||
| 118 | 121 | #sound-dai-cells = <1>; |
| 119 | 122 | pinctrl-0 = <&i2s0_pinctrl>; |
| 120 | 123 | pinctrl-names = "default"; |
| 124 | + status = "okay"; | |
| 121 | 125 | }; |
| 122 | 126 | |
| 123 | 127 | &spi0 { |
| @@ -125,6 +129,7 @@ · 1 unmodified line | ||
| 125 | 129 | pinctrl-names = "default"; |
| 126 | 130 | num-cs = <1>; |
| 127 | 131 | cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; |
| 132 | + status = "okay"; | |
| 128 | 133 | |
| 129 | 134 | panel@0 { |
| 130 | 135 | compatible = "canaan,kd233-tft", "ilitek,ili9341"; |
| @@ -16,13 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | #size-cells = <1>; |
| 17 | 17 | compatible = "canaan,kendryte-k210"; |
| 18 | 18 | |
| 19 | − aliases { | |
| 20 | − serial0 = &uarths0; | |
| 21 | − serial1 = &uart1; | |
| 22 | − serial2 = &uart2; | |
| 23 | − serial3 = &uart3; | |
| 24 | − }; | |
| 25 | − | |
| 26 | 19 | /* |
| 27 | 20 | * The K210 has an sv39 MMU following the privileged specification v1.9. |
| 28 | 21 | * Since this is a non-ratified draft specification, the kernel does not |
| @@ -137,6 +130,7 @@ · 108 unmodified lines | ||
| 137 | 130 | reg = <0x38000000 0x1000>; |
| 138 | 131 | interrupts = <33>; |
| 139 | 132 | clocks = <&sysclk K210_CLK_CPU>; |
| 133 | + status = "disabled"; | |
| 140 | 134 | }; |
| 141 | 135 | |
| 142 | 136 | gpio0: gpio-controller@38001000 { |
| @@ -152,6 +146,7 @@ · 9 unmodified lines | ||
| 152 | 146 | <62>, <63>, <64>, <65>; |
| 153 | 147 | gpio-controller; |
| 154 | 148 | ngpios = <32>; |
| 149 | + status = "disabled"; | |
| 155 | 150 | }; |
| 156 | 151 | |
| 157 | 152 | dmac0: dma-controller@50000000 { |
| @@ -187,6 +182,7 @@ · 29 unmodified lines | ||
| 187 | 182 | <&sysclk K210_CLK_GPIO>; |
| 188 | 183 | clock-names = "bus", "db"; |
| 189 | 184 | resets = <&sysrst K210_RST_GPIO>; |
| 185 | + status = "disabled"; | |
| 190 | 186 | |
| 191 | 187 | gpio1_0: gpio-port@0 { |
| 192 | 188 | #gpio-cells = <2>; |
| @@ -214,6 +210,7 @@ · 21 unmodified lines | ||
| 214 | 210 | dsr-override; |
| 215 | 211 | cts-override; |
| 216 | 212 | ri-override; |
| 213 | + status = "disabled"; | |
| 217 | 214 | }; |
| 218 | 215 | |
| 219 | 216 | uart2: serial@50220000 { |
| @@ -230,6 +227,7 @@ · 10 unmodified lines | ||
| 230 | 227 | dsr-override; |
| 231 | 228 | cts-override; |
| 232 | 229 | ri-override; |
| 230 | + status = "disabled"; | |
| 233 | 231 | }; |
| 234 | 232 | |
| 235 | 233 | uart3: serial@50230000 { |
| @@ -246,6 +244,7 @@ · 10 unmodified lines | ||
| 246 | 244 | dsr-override; |
| 247 | 245 | cts-override; |
| 248 | 246 | ri-override; |
| 247 | + status = "disabled"; | |
| 249 | 248 | }; |
| 250 | 249 | |
| 251 | 250 | spi2: spi@50240000 { |
| @@ -259,6 +258,7 @@ · 7 unmodified lines | ||
| 259 | 258 | <&sysclk K210_CLK_APB0>; |
| 260 | 259 | clock-names = "ssi_clk", "pclk"; |
| 261 | 260 | resets = <&sysrst K210_RST_SPI2>; |
| 261 | + status = "disabled"; | |
| 262 | 262 | }; |
| 263 | 263 | |
| 264 | 264 | i2s0: i2s@50250000 { |
| @@ -268,6 +268,7 @@ · 3 unmodified lines | ||
| 268 | 268 | clocks = <&sysclk K210_CLK_I2S0>; |
| 269 | 269 | clock-names = "i2sclk"; |
| 270 | 270 | resets = <&sysrst K210_RST_I2S0>; |
| 271 | + status = "disabled"; | |
| 271 | 272 | }; |
| 272 | 273 | |
| 273 | 274 | i2s1: i2s@50260000 { |
| @@ -277,6 +278,7 @@ · 3 unmodified lines | ||
| 277 | 278 | clocks = <&sysclk K210_CLK_I2S1>; |
| 278 | 279 | clock-names = "i2sclk"; |
| 279 | 280 | resets = <&sysrst K210_RST_I2S1>; |
| 281 | + status = "disabled"; | |
| 280 | 282 | }; |
| 281 | 283 | |
| 282 | 284 | i2s2: i2s@50270000 { |
| @@ -286,6 +288,7 @@ · 3 unmodified lines | ||
| 286 | 288 | clocks = <&sysclk K210_CLK_I2S2>; |
| 287 | 289 | clock-names = "i2sclk"; |
| 288 | 290 | resets = <&sysrst K210_RST_I2S2>; |
| 291 | + status = "disabled"; | |
| 289 | 292 | }; |
| 290 | 293 | |
| 291 | 294 | i2c0: i2c@50280000 { |
| @@ -296,6 +299,7 @@ · 4 unmodified lines | ||
| 296 | 299 | <&sysclk K210_CLK_APB0>; |
| 297 | 300 | clock-names = "ref", "pclk"; |
| 298 | 301 | resets = <&sysrst K210_RST_I2C0>; |
| 302 | + status = "disabled"; | |
| 299 | 303 | }; |
| 300 | 304 | |
| 301 | 305 | i2c1: i2c@50290000 { |
| @@ -306,6 +310,7 @@ · 4 unmodified lines | ||
| 306 | 310 | <&sysclk K210_CLK_APB0>; |
| 307 | 311 | clock-names = "ref", "pclk"; |
| 308 | 312 | resets = <&sysrst K210_RST_I2C1>; |
| 313 | + status = "disabled"; | |
| 309 | 314 | }; |
| 310 | 315 | |
| 311 | 316 | i2c2: i2c@502a0000 { |
| @@ -316,6 +321,7 @@ · 4 unmodified lines | ||
| 316 | 321 | <&sysclk K210_CLK_APB0>; |
| 317 | 322 | clock-names = "ref", "pclk"; |
| 318 | 323 | resets = <&sysrst K210_RST_I2C2>; |
| 324 | + status = "disabled"; | |
| 319 | 325 | }; |
| 320 | 326 | |
| 321 | 327 | fpioa: pinmux@502b0000 { |
| @@ -464,6 +470,7 @@ · 142 unmodified lines | ||
| 464 | 470 | reset-names = "spi"; |
| 465 | 471 | num-cs = <4>; |
| 466 | 472 | reg-io-width = <4>; |
| 473 | + status = "disabled"; | |
| 467 | 474 | }; |
| 468 | 475 | |
| 469 | 476 | spi1: spi@53000000 { |
| @@ -479,6 +486,7 @@ · 9 unmodified lines | ||
| 479 | 486 | reset-names = "spi"; |
| 480 | 487 | num-cs = <4>; |
| 481 | 488 | reg-io-width = <4>; |
| 489 | + status = "disabled"; | |
| 482 | 490 | }; |
| 483 | 491 | |
| 484 | 492 | spi3: spi@54000000 { |
| @@ -495,6 +503,7 @@ · 10 unmodified lines | ||
| 495 | 503 | |
| 496 | 504 | num-cs = <4>; |
| 497 | 505 | reg-io-width = <4>; |
| 506 | + status = "disabled"; | |
| 498 | 507 | }; |
| 499 | 508 | }; |
| 500 | 509 | }; |
| @@ -15,6 +15,10 @@ · 14 unmodified lines | ||
| 15 | 15 | model = "Kendryte K210 generic"; |
| 16 | 16 | compatible = "canaan,kendryte-k210"; |
| 17 | 17 | |
| 18 | + aliases { | |
| 19 | + serial0 = &uarths0; | |
| 20 | + }; | |
| 21 | + | |
| 18 | 22 | chosen { |
| 19 | 23 | bootargs = "earlycon console=ttySIF0"; |
| 20 | 24 | stdout-path = "serial0:115200n8"; |
| @@ -24,7 +28,6 @@ · 3 unmodified lines | ||
| 24 | 28 | &fpioa { |
| 25 | 29 | pinctrl-0 = <&jtag_pins>; |
| 26 | 30 | pinctrl-names = "default"; |
| 27 | − status = "okay"; | |
| 28 | 31 | |
| 29 | 32 | jtag_pins: jtag-pinmux { |
| 30 | 33 | pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>, |
| @@ -17,6 +17,10 @@ · 16 unmodified lines | ||
| 17 | 17 | compatible = "sipeed,maix-bit", "sipeed,maix-bitm", |
| 18 | 18 | "canaan,kendryte-k210"; |
| 19 | 19 | |
| 20 | + aliases { | |
| 21 | + serial0 = &uarths0; | |
| 22 | + }; | |
| 23 | + | |
| 20 | 24 | chosen { |
| 21 | 25 | bootargs = "earlycon console=ttySIF0"; |
| 22 | 26 | stdout-path = "serial0:115200n8"; |
| @@ -58,7 +62,6 @@ · 35 unmodified lines | ||
| 58 | 62 | &fpioa { |
| 59 | 63 | pinctrl-names = "default"; |
| 60 | 64 | pinctrl-0 = <&jtag_pinctrl>; |
| 61 | − status = "okay"; | |
| 62 | 65 | |
| 63 | 66 | jtag_pinctrl: jtag-pinmux { |
| 64 | 67 | pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>, |
| @@ -156,6 +159,7 @@ · 91 unmodified lines | ||
| 156 | 159 | #sound-dai-cells = <1>; |
| 157 | 160 | pinctrl-0 = <&i2s0_pinctrl>; |
| 158 | 161 | pinctrl-names = "default"; |
| 162 | + status = "okay"; | |
| 159 | 163 | }; |
| 160 | 164 | |
| 161 | 165 | &i2c1 { |
| @@ -170,6 +174,7 @@ · 8 unmodified lines | ||
| 170 | 174 | pinctrl-names = "default"; |
| 171 | 175 | num-cs = <1>; |
| 172 | 176 | cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; |
| 177 | + status = "okay"; | |
| 173 | 178 | |
| 174 | 179 | panel@0 { |
| 175 | 180 | compatible = "sitronix,st7789v"; |
| @@ -199,6 +204,8 @@ · 23 unmodified lines | ||
| 199 | 204 | }; |
| 200 | 205 | |
| 201 | 206 | &spi3 { |
| 207 | + status = "okay"; | |
| 208 | + | |
| 202 | 209 | flash@0 { |
| 203 | 210 | compatible = "jedec,spi-nor"; |
| 204 | 211 | reg = <0>; |
| @@ -17,6 +17,10 @@ · 16 unmodified lines | ||
| 17 | 17 | compatible = "sipeed,maix-dock-m1", "sipeed,maix-dock-m1w", |
| 18 | 18 | "canaan,kendryte-k210"; |
| 19 | 19 | |
| 20 | + aliases { | |
| 21 | + serial0 = &uarths0; | |
| 22 | + }; | |
| 23 | + | |
| 20 | 24 | chosen { |
| 21 | 25 | bootargs = "earlycon console=ttySIF0"; |
| 22 | 26 | stdout-path = "serial0:115200n8"; |
| @@ -63,7 +67,6 @@ · 40 unmodified lines | ||
| 63 | 67 | &fpioa { |
| 64 | 68 | pinctrl-0 = <&jtag_pinctrl>; |
| 65 | 69 | pinctrl-names = "default"; |
| 66 | − status = "okay"; | |
| 67 | 70 | |
| 68 | 71 | jtag_pinctrl: jtag-pinmux { |
| 69 | 72 | pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>, |
| @@ -159,6 +162,7 @@ · 89 unmodified lines | ||
| 159 | 162 | #sound-dai-cells = <1>; |
| 160 | 163 | pinctrl-0 = <&i2s0_pinctrl>; |
| 161 | 164 | pinctrl-names = "default"; |
| 165 | + status = "okay"; | |
| 162 | 166 | }; |
| 163 | 167 | |
| 164 | 168 | &i2c1 { |
| @@ -173,6 +177,7 @@ · 8 unmodified lines | ||
| 173 | 177 | pinctrl-names = "default"; |
| 174 | 178 | num-cs = <1>; |
| 175 | 179 | cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; |
| 180 | + status = "okay"; | |
| 176 | 181 | |
| 177 | 182 | panel@0 { |
| 178 | 183 | compatible = "sitronix,st7789v"; |
| @@ -16,6 +16,10 @@ · 15 unmodified lines | ||
| 16 | 16 | model = "SiPeed MAIX GO"; |
| 17 | 17 | compatible = "sipeed,maix-go", "canaan,kendryte-k210"; |
| 18 | 18 | |
| 19 | + aliases { | |
| 20 | + serial0 = &uarths0; | |
| 21 | + }; | |
| 22 | + | |
| 19 | 23 | chosen { |
| 20 | 24 | bootargs = "earlycon console=ttySIF0"; |
| 21 | 25 | stdout-path = "serial0:115200n8"; |
| @@ -69,7 +73,6 @@ · 47 unmodified lines | ||
| 69 | 73 | &fpioa { |
| 70 | 74 | pinctrl-0 = <&jtag_pinctrl>; |
| 71 | 75 | pinctrl-names = "default"; |
| 72 | − status = "okay"; | |
| 73 | 76 | |
| 74 | 77 | jtag_pinctrl: jtag-pinmux { |
| 75 | 78 | pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>, |
| @@ -167,6 +170,7 @@ · 91 unmodified lines | ||
| 167 | 170 | #sound-dai-cells = <1>; |
| 168 | 171 | pinctrl-0 = <&i2s0_pinctrl>; |
| 169 | 172 | pinctrl-names = "default"; |
| 173 | + status = "okay"; | |
| 170 | 174 | }; |
| 171 | 175 | |
| 172 | 176 | &i2c1 { |
| @@ -181,6 +185,7 @@ · 8 unmodified lines | ||
| 181 | 185 | pinctrl-names = "default"; |
| 182 | 186 | num-cs = <1>; |
| 183 | 187 | cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; |
| 188 | + status = "okay"; | |
| 184 | 189 | |
| 185 | 190 | panel@0 { |
| 186 | 191 | compatible = "sitronix,st7789v"; |
| @@ -209,6 +214,8 @@ · 22 unmodified lines | ||
| 209 | 214 | }; |
| 210 | 215 | |
| 211 | 216 | &spi3 { |
| 217 | + status = "okay"; | |
| 218 | + | |
| 212 | 219 | flash@0 { |
| 213 | 220 | compatible = "jedec,spi-nor"; |
| 214 | 221 | reg = <0>; |
| @@ -15,6 +15,10 @@ · 14 unmodified lines | ||
| 15 | 15 | model = "SiPeed MAIXDUINO"; |
| 16 | 16 | compatible = "sipeed,maixduino", "canaan,kendryte-k210"; |
| 17 | 17 | |
| 18 | + aliases { | |
| 19 | + serial0 = &uarths0; | |
| 20 | + }; | |
| 21 | + | |
| 18 | 22 | chosen { |
| 19 | 23 | bootargs = "earlycon console=ttySIF0"; |
| 20 | 24 | stdout-path = "serial0:115200n8"; |
| @@ -39,8 +43,6 @@ · 18 unmodified lines | ||
| 39 | 43 | }; |
| 40 | 44 | |
| 41 | 45 | &fpioa { |
| 42 | − status = "okay"; | |
| 43 | − | |
| 44 | 46 | uarths_pinctrl: uarths-pinmux { |
| 45 | 47 | pinmux = <K210_FPIOA(4, K210_PCF_UARTHS_RX)>, /* Header "0" */ |
| 46 | 48 | <K210_FPIOA(5, K210_PCF_UARTHS_TX)>; /* Header "1" */ |
| @@ -132,6 +134,7 @@ · 85 unmodified lines | ||
| 132 | 134 | #sound-dai-cells = <1>; |
| 133 | 135 | pinctrl-0 = <&i2s0_pinctrl>; |
| 134 | 136 | pinctrl-names = "default"; |
| 137 | + status = "okay"; | |
| 135 | 138 | }; |
| 136 | 139 | |
| 137 | 140 | &i2c1 { |
| @@ -146,6 +149,7 @@ · 8 unmodified lines | ||
| 146 | 149 | pinctrl-names = "default"; |
| 147 | 150 | num-cs = <1>; |
| 148 | 151 | cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; |
| 152 | + status = "okay"; | |
| 149 | 153 | |
| 150 | 154 | panel@0 { |
| 151 | 155 | compatible = "sitronix,st7789v"; |
| @@ -174,6 +178,8 @@ · 22 unmodified lines | ||
| 174 | 178 | }; |
| 175 | 179 | |
| 176 | 180 | &spi3 { |
| 181 | + status = "okay"; | |
| 182 | + | |
| 177 | 183 | flash@0 { |
| 178 | 184 | compatible = "jedec,spi-nor"; |
| 179 | 185 | reg = <0>; |
| @@ -244,7 +244,7 @@ · 243 unmodified lines | ||
| 244 | 244 | regulator-boot-on; |
| 245 | 245 | regulator-always-on; |
| 246 | 246 | regulator-min-microvolt = <1800000>; |
| 247 | − regulator-max-microvolt = <1800000>; | |
| 247 | + regulator-max-microvolt = <3300000>; | |
| 248 | 248 | regulator-name = "emmc_vdd"; |
| 249 | 249 | }; |
| 250 | 250 | }; |
| @@ -145,7 +145,7 @@ · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | /* parts of opcode for RVF, RVD and RVQ */ |
| 147 | 147 | #define RVFDQ_FL_FS_WIDTH_OFF 12 |
| 148 | −#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(3, 0) | |
| 148 | +#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(2, 0) | |
| 149 | 149 | #define RVFDQ_FL_FS_WIDTH_W 2 |
| 150 | 150 | #define RVFDQ_FL_FS_WIDTH_D 3 |
| 151 | 151 | #define RVFDQ_LS_FS_WIDTH_Q 4 |
| @@ -120,9 +120,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) · 119 unmodified lines | ||
| 120 | 120 | out = ftrace_make_nop(mod, rec, MCOUNT_ADDR); |
| 121 | 121 | mutex_unlock(&text_mutex); |
| 122 | 122 | |
| 123 | − if (!mod) | |
| 124 | − local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE); | |
| 125 | − | |
| 126 | 123 | return out; |
| 127 | 124 | } |
| 128 | 125 | |
| @@ -156,9 +153,9 @@ static int __ftrace_modify_code(void *data) · 27 unmodified lines | ||
| 156 | 153 | } else { |
| 157 | 154 | while (atomic_read(¶m->cpu_count) <= num_online_cpus()) |
| 158 | 155 | cpu_relax(); |
| 159 | − } | |
| 160 | 156 | |
| 161 | − local_flush_icache_all(); | |
| 157 | + local_flush_icache_all(); | |
| 158 | + } | |
| 162 | 159 | |
| 163 | 160 | return 0; |
| 164 | 161 | } |
| @@ -89,6 +89,14 @@ static int __patch_insn_set(void *addr, u8 c, size_t len) · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | memset(waddr, c, len); |
| 91 | 91 | |
| 92 | + /* | |
| 93 | + * We could have just patched a function that is about to be | |
| 94 | + * called so make sure we don't execute partially patched | |
| 95 | + * instructions by flushing the icache as soon as possible. | |
| 96 | + */ | |
| 97 | + local_flush_icache_range((unsigned long)waddr, | |
| 98 | + (unsigned long)waddr + len); | |
| 99 | + | |
| 92 | 100 | patch_unmap(FIX_TEXT_POKE0); |
| 93 | 101 | |
| 94 | 102 | if (across_pages) |
| @@ -135,6 +143,14 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len) · 40 unmodified lines | ||
| 135 | 143 | |
| 136 | 144 | ret = copy_to_kernel_nofault(waddr, insn, len); |
| 137 | 145 | |
| 146 | + /* | |
| 147 | + * We could have just patched a function that is about to be | |
| 148 | + * called so make sure we don't execute partially patched | |
| 149 | + * instructions by flushing the icache as soon as possible. | |
| 150 | + */ | |
| 151 | + local_flush_icache_range((unsigned long)waddr, | |
| 152 | + (unsigned long)waddr + len); | |
| 153 | + | |
| 138 | 154 | patch_unmap(FIX_TEXT_POKE0); |
| 139 | 155 | |
| 140 | 156 | if (across_pages) |
| @@ -189,9 +205,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len) · 48 unmodified lines | ||
| 189 | 205 | |
| 190 | 206 | ret = patch_insn_set(tp, c, len); |
| 191 | 207 | |
| 192 | − if (!ret) | |
| 193 | − flush_icache_range((uintptr_t)tp, (uintptr_t)tp + len); | |
| 194 | − | |
| 195 | 208 | return ret; |
| 196 | 209 | } |
| 197 | 210 | NOKPROBE_SYMBOL(patch_text_set_nosync); |
| @@ -224,9 +237,6 @@ int patch_text_nosync(void *addr, const void *insns, size_t len) · 26 unmodified lines | ||
| 224 | 237 | |
| 225 | 238 | ret = patch_insn_write(tp, insns, len); |
| 226 | 239 | |
| 227 | − if (!ret) | |
| 228 | − flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len); | |
| 229 | − | |
| 230 | 240 | return ret; |
| 231 | 241 | } |
| 232 | 242 | NOKPROBE_SYMBOL(patch_text_nosync); |
| @@ -253,9 +263,9 @@ static int patch_text_cb(void *data) · 20 unmodified lines | ||
| 253 | 263 | } else { |
| 254 | 264 | while (atomic_read(&patch->cpu_count) <= num_online_cpus()) |
| 255 | 265 | cpu_relax(); |
| 256 | − } | |
| 257 | 266 | |
| 258 | − local_flush_icache_all(); | |
| 267 | + local_flush_icache_all(); | |
| 268 | + } | |
| 259 | 269 | |
| 260 | 270 | return ret; |
| 261 | 271 | } |
| @@ -156,7 +156,7 @@ unsigned long __get_wchan(struct task_struct *task) · 155 unmodified lines | ||
| 156 | 156 | return pc; |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | −noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, | |
| 159 | +noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, | |
| 160 | 160 | struct task_struct *task, struct pt_regs *regs) |
| 161 | 161 | { |
| 162 | 162 | walk_stackframe(task, regs, consume_entry, cookie); |
| @@ -23,7 +23,7 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, · 22 unmodified lines | ||
| 23 | 23 | #ifdef CONFIG_64BIT |
| 24 | 24 | SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, |
| 25 | 25 | unsigned long, prot, unsigned long, flags, |
| 26 | − unsigned long, fd, off_t, offset) | |
| 26 | + unsigned long, fd, unsigned long, offset) | |
| 27 | 27 | { |
| 28 | 28 | return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0); |
| 29 | 29 | } |
| @@ -32,7 +32,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, · 2 unmodified lines | ||
| 32 | 32 | #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT) |
| 33 | 33 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, |
| 34 | 34 | unsigned long, prot, unsigned long, flags, |
| 35 | − unsigned long, fd, off_t, offset) | |
| 35 | + unsigned long, fd, unsigned long, offset) | |
| 36 | 36 | { |
| 37 | 37 | /* |
| 38 | 38 | * Note that the shift for mmap2 is constant (12), |
| @@ -170,11 +170,14 @@ static void kaslr_adjust_got(unsigned long offset) · 169 unmodified lines | ||
| 170 | 170 | u64 *entry; |
| 171 | 171 | |
| 172 | 172 | /* |
| 173 | − * Even without -fPIE, Clang still uses a global offset table for some | |
| 174 | − * reason. Adjust the GOT entries. | |
| 173 | + * Adjust GOT entries, except for ones for undefined weak symbols | |
| 174 | + * that resolved to zero. This also skips the first three reserved | |
| 175 | + * entries on s390x that are zero. | |
| 175 | 176 | */ |
| 176 | − for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) | |
| 177 | − *entry += offset - __START_KERNEL; | |
| 177 | + for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) { | |
| 178 | + if (*entry) | |
| 179 | + *entry += offset - __START_KERNEL; | |
| 180 | + } | |
| 178 | 181 | } |
| 179 | 182 | |
| 180 | 183 | /* |
| @@ -601,17 +601,16 @@ CONFIG_WATCHDOG=y · 600 unmodified lines | ||
| 601 | 601 | CONFIG_WATCHDOG_NOWAYOUT=y |
| 602 | 602 | CONFIG_SOFT_WATCHDOG=m |
| 603 | 603 | CONFIG_DIAG288_WATCHDOG=m |
| 604 | +CONFIG_DRM=m | |
| 605 | +CONFIG_DRM_VIRTIO_GPU=m | |
| 604 | 606 | CONFIG_FB=y |
| 605 | 607 | # CONFIG_FB_DEVICE is not set |
| 606 | −CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 607 | −CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | |
| 608 | 608 | # CONFIG_HID_SUPPORT is not set |
| 609 | 609 | # CONFIG_USB_SUPPORT is not set |
| 610 | 610 | CONFIG_INFINIBAND=m |
| 611 | 611 | CONFIG_INFINIBAND_USER_ACCESS=m |
| 612 | 612 | CONFIG_MLX4_INFINIBAND=m |
| 613 | 613 | CONFIG_MLX5_INFINIBAND=m |
| 614 | −CONFIG_SYNC_FILE=y | |
| 615 | 614 | CONFIG_VFIO=m |
| 616 | 615 | CONFIG_VFIO_PCI=m |
| 617 | 616 | CONFIG_MLX5_VFIO_PCI=m |
| @@ -592,17 +592,16 @@ CONFIG_WATCHDOG_CORE=y · 591 unmodified lines | ||
| 592 | 592 | CONFIG_WATCHDOG_NOWAYOUT=y |
| 593 | 593 | CONFIG_SOFT_WATCHDOG=m |
| 594 | 594 | CONFIG_DIAG288_WATCHDOG=m |
| 595 | +CONFIG_DRM=m | |
| 596 | +CONFIG_DRM_VIRTIO_GPU=m | |
| 595 | 597 | CONFIG_FB=y |
| 596 | 598 | # CONFIG_FB_DEVICE is not set |
| 597 | −CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 598 | −CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | |
| 599 | 599 | # CONFIG_HID_SUPPORT is not set |
| 600 | 600 | # CONFIG_USB_SUPPORT is not set |
| 601 | 601 | CONFIG_INFINIBAND=m |
| 602 | 602 | CONFIG_INFINIBAND_USER_ACCESS=m |
| 603 | 603 | CONFIG_MLX4_INFINIBAND=m |
| 604 | 604 | CONFIG_MLX5_INFINIBAND=m |
| 605 | −CONFIG_SYNC_FILE=y | |
| 606 | 605 | CONFIG_VFIO=m |
| 607 | 606 | CONFIG_VFIO_PCI=m |
| 608 | 607 | CONFIG_MLX5_VFIO_PCI=m |
| @@ -54,7 +54,7 @@ static __always_inline void arch_exit_to_user_mode(void) · 53 unmodified lines | ||
| 54 | 54 | static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, |
| 55 | 55 | unsigned long ti_work) |
| 56 | 56 | { |
| 57 | − choose_random_kstack_offset(get_tod_clock_fast() & 0xff); | |
| 57 | + choose_random_kstack_offset(get_tod_clock_fast()); | |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare |
| @@ -38,33 +38,6 @@ · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | #include "entry.h" |
| 40 | 40 | |
| 41 | −/* | |
| 42 | − * Perform the mmap() system call. Linux for S/390 isn't able to handle more | |
| 43 | − * than 5 system call parameters, so this system call uses a memory block | |
| 44 | − * for parameter passing. | |
| 45 | − */ | |
| 46 | − | |
| 47 | −struct s390_mmap_arg_struct { | |
| 48 | − unsigned long addr; | |
| 49 | − unsigned long len; | |
| 50 | − unsigned long prot; | |
| 51 | − unsigned long flags; | |
| 52 | − unsigned long fd; | |
| 53 | − unsigned long offset; | |
| 54 | −}; | |
| 55 | − | |
| 56 | −SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg) | |
| 57 | −{ | |
| 58 | − struct s390_mmap_arg_struct a; | |
| 59 | − int error = -EFAULT; | |
| 60 | − | |
| 61 | − if (copy_from_user(&a, arg, sizeof(a))) | |
| 62 | − goto out; | |
| 63 | − error = ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); | |
| 64 | −out: | |
| 65 | − return error; | |
| 66 | −} | |
| 67 | − | |
| 68 | 41 | #ifdef CONFIG_SYSVIPC |
| 69 | 42 | /* |
| 70 | 43 | * sys_ipc() is the de-multiplexer for the SysV IPC calls. |
| @@ -418,7 +418,7 @@ · 417 unmodified lines | ||
| 418 | 418 | 412 32 utimensat_time64 - sys_utimensat |
| 419 | 419 | 413 32 pselect6_time64 - compat_sys_pselect6_time64 |
| 420 | 420 | 414 32 ppoll_time64 - compat_sys_ppoll_time64 |
| 421 | −416 32 io_pgetevents_time64 - sys_io_pgetevents | |
| 421 | +416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64 | |
| 422 | 422 | 417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64 |
| 423 | 423 | 418 32 mq_timedsend_time64 - sys_mq_timedsend |
| 424 | 424 | 419 32 mq_timedreceive_time64 - sys_mq_timedreceive |
| @@ -410,7 +410,7 @@ static void __init cpu_enable_directed_irq(void *unused) · 409 unmodified lines | ||
| 410 | 410 | union zpci_sic_iib iib = {{0}}; |
| 411 | 411 | union zpci_sic_iib ziib = {{0}}; |
| 412 | 412 | |
| 413 | − iib.cdiib.dibv_addr = (u64) zpci_ibv[smp_processor_id()]->vector; | |
| 413 | + iib.cdiib.dibv_addr = virt_to_phys(zpci_ibv[smp_processor_id()]->vector); | |
| 414 | 414 | |
| 415 | 415 | zpci_set_irq_ctrl(SIC_IRQ_MODE_SET_CPU, 0, &iib); |
| 416 | 416 | zpci_set_irq_ctrl(SIC_IRQ_MODE_D_SINGLE, PCI_ISC, &ziib); |
| @@ -59,3 +59,14 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, · 58 unmodified lines | ||
| 59 | 59 | (u64)len0 << 32 | len1, advice); |
| 60 | 60 | #endif |
| 61 | 61 | } |
| 62 | + | |
| 63 | +/* | |
| 64 | + * swap the arguments the way that libc wants them instead of | |
| 65 | + * moving flags ahead of the 64-bit nbytes argument | |
| 66 | + */ | |
| 67 | +SYSCALL_DEFINE6(sh_sync_file_range6, int, fd, SC_ARG64(offset), | |
| 68 | + SC_ARG64(nbytes), unsigned int, flags) | |
| 69 | +{ | |
| 70 | + return ksys_sync_file_range(fd, SC_VAL64(loff_t, offset), | |
| 71 | + SC_VAL64(loff_t, nbytes), flags); | |
| 72 | +} | |
| @@ -321,7 +321,7 @@ · 320 unmodified lines | ||
| 321 | 321 | 311 common set_robust_list sys_set_robust_list |
| 322 | 322 | 312 common get_robust_list sys_get_robust_list |
| 323 | 323 | 313 common splice sys_splice |
| 324 | −314 common sync_file_range sys_sync_file_range | |
| 324 | +314 common sync_file_range sys_sh_sync_file_range6 | |
| 325 | 325 | 315 common tee sys_tee |
| 326 | 326 | 316 common vmsplice sys_vmsplice |
| 327 | 327 | 317 common move_pages sys_move_pages |
| @@ -395,6 +395,7 @@ · 67 unmodified lines | ||
| 395 | 395 | 385 common pkey_alloc sys_pkey_alloc |
| 396 | 396 | 386 common pkey_free sys_pkey_free |
| 397 | 397 | 387 common rseq sys_rseq |
| 398 | +388 common sync_file_range2 sys_sync_file_range2 | |
| 398 | 399 | # room for arch specific syscalls |
| 399 | 400 | 393 common semget sys_semget |
| 400 | 401 | 394 common semctl sys_semctl |
| @@ -18,224 +18,3 @@ sys32_mmap2: · 17 unmodified lines | ||
| 18 | 18 | sethi %hi(sys_mmap), %g1 |
| 19 | 19 | jmpl %g1 + %lo(sys_mmap), %g0 |
| 20 | 20 | sllx %o5, 12, %o5 |
| 21 | − | |
| 22 | − .align 32 | |
| 23 | − .globl sys32_socketcall | |
| 24 | −sys32_socketcall: /* %o0=call, %o1=args */ | |
| 25 | − cmp %o0, 1 | |
| 26 | − bl,pn %xcc, do_einval | |
| 27 | − cmp %o0, 18 | |
| 28 | − bg,pn %xcc, do_einval | |
| 29 | − sub %o0, 1, %o0 | |
| 30 | − sllx %o0, 5, %o0 | |
| 31 | − sethi %hi(__socketcall_table_begin), %g2 | |
| 32 | − or %g2, %lo(__socketcall_table_begin), %g2 | |
| 33 | − jmpl %g2 + %o0, %g0 | |
| 34 | − nop | |
| 35 | −do_einval: | |
| 36 | − retl | |
| 37 | − mov -EINVAL, %o0 | |
| 38 | − | |
| 39 | − .align 32 | |
| 40 | −__socketcall_table_begin: | |
| 41 | − | |
| 42 | − /* Each entry is exactly 32 bytes. */ | |
| 43 | −do_sys_socket: /* sys_socket(int, int, int) */ | |
| 44 | −1: ldswa [%o1 + 0x0] %asi, %o0 | |
| 45 | − sethi %hi(sys_socket), %g1 | |
| 46 | −2: ldswa [%o1 + 0x8] %asi, %o2 | |
| 47 | − jmpl %g1 + %lo(sys_socket), %g0 | |
| 48 | −3: ldswa [%o1 + 0x4] %asi, %o1 | |
| 49 | − nop | |
| 50 | − nop | |
| 51 | − nop | |
| 52 | −do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */ | |
| 53 | −4: ldswa [%o1 + 0x0] %asi, %o0 | |
| 54 | − sethi %hi(sys_bind), %g1 | |
| 55 | −5: ldswa [%o1 + 0x8] %asi, %o2 | |
| 56 | − jmpl %g1 + %lo(sys_bind), %g0 | |
| 57 | −6: lduwa [%o1 + 0x4] %asi, %o1 | |
| 58 | − nop | |
| 59 | − nop | |
| 60 | − nop | |
| 61 | −do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */ | |
| 62 | −7: ldswa [%o1 + 0x0] %asi, %o0 | |
| 63 | − sethi %hi(sys_connect), %g1 | |
| 64 | −8: ldswa [%o1 + 0x8] %asi, %o2 | |
| 65 | − jmpl %g1 + %lo(sys_connect), %g0 | |
| 66 | −9: lduwa [%o1 + 0x4] %asi, %o1 | |
| 67 | − nop | |
| 68 | − nop | |
| 69 | − nop | |
| 70 | −do_sys_listen: /* sys_listen(int, int) */ | |
| 71 | −10: ldswa [%o1 + 0x0] %asi, %o0 | |
| 72 | − sethi %hi(sys_listen), %g1 | |
| 73 | − jmpl %g1 + %lo(sys_listen), %g0 | |
| 74 | −11: ldswa [%o1 + 0x4] %asi, %o1 | |
| 75 | − nop | |
| 76 | − nop | |
| 77 | − nop | |
| 78 | − nop | |
| 79 | −do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */ | |
| 80 | −12: ldswa [%o1 + 0x0] %asi, %o0 | |
| 81 | − sethi %hi(sys_accept), %g1 | |
| 82 | −13: lduwa [%o1 + 0x8] %asi, %o2 | |
| 83 | − jmpl %g1 + %lo(sys_accept), %g0 | |
| 84 | −14: lduwa [%o1 + 0x4] %asi, %o1 | |
| 85 | − nop | |
| 86 | − nop | |
| 87 | − nop | |
| 88 | −do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */ | |
| 89 | −15: ldswa [%o1 + 0x0] %asi, %o0 | |
| 90 | − sethi %hi(sys_getsockname), %g1 | |
| 91 | −16: lduwa [%o1 + 0x8] %asi, %o2 | |
| 92 | − jmpl %g1 + %lo(sys_getsockname), %g0 | |
| 93 | −17: lduwa [%o1 + 0x4] %asi, %o1 | |
| 94 | − nop | |
| 95 | − nop | |
| 96 | − nop | |
| 97 | −do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */ | |
| 98 | −18: ldswa [%o1 + 0x0] %asi, %o0 | |
| 99 | − sethi %hi(sys_getpeername), %g1 | |
| 100 | −19: lduwa [%o1 + 0x8] %asi, %o2 | |
| 101 | − jmpl %g1 + %lo(sys_getpeername), %g0 | |
| 102 | −20: lduwa [%o1 + 0x4] %asi, %o1 | |
| 103 | − nop | |
| 104 | − nop | |
| 105 | − nop | |
| 106 | −do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */ | |
| 107 | −21: ldswa [%o1 + 0x0] %asi, %o0 | |
| 108 | − sethi %hi(sys_socketpair), %g1 | |
| 109 | −22: ldswa [%o1 + 0x8] %asi, %o2 | |
| 110 | −23: lduwa [%o1 + 0xc] %asi, %o3 | |
| 111 | − jmpl %g1 + %lo(sys_socketpair), %g0 | |
| 112 | −24: ldswa [%o1 + 0x4] %asi, %o1 | |
| 113 | − nop | |
| 114 | − nop | |
| 115 | −do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */ | |
| 116 | −25: ldswa [%o1 + 0x0] %asi, %o0 | |
| 117 | − sethi %hi(sys_send), %g1 | |
| 118 | −26: lduwa [%o1 + 0x8] %asi, %o2 | |
| 119 | −27: lduwa [%o1 + 0xc] %asi, %o3 | |
| 120 | − jmpl %g1 + %lo(sys_send), %g0 | |
| 121 | −28: lduwa [%o1 + 0x4] %asi, %o1 | |
| 122 | − nop | |
| 123 | − nop | |
| 124 | −do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */ | |
| 125 | −29: ldswa [%o1 + 0x0] %asi, %o0 | |
| 126 | − sethi %hi(sys_recv), %g1 | |
| 127 | −30: lduwa [%o1 + 0x8] %asi, %o2 | |
| 128 | −31: lduwa [%o1 + 0xc] %asi, %o3 | |
| 129 | − jmpl %g1 + %lo(sys_recv), %g0 | |
| 130 | −32: lduwa [%o1 + 0x4] %asi, %o1 | |
| 131 | − nop | |
| 132 | − nop | |
| 133 | −do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ | |
| 134 | −33: ldswa [%o1 + 0x0] %asi, %o0 | |
| 135 | − sethi %hi(sys_sendto), %g1 | |
| 136 | −34: lduwa [%o1 + 0x8] %asi, %o2 | |
| 137 | −35: lduwa [%o1 + 0xc] %asi, %o3 | |
| 138 | −36: lduwa [%o1 + 0x10] %asi, %o4 | |
| 139 | −37: ldswa [%o1 + 0x14] %asi, %o5 | |
| 140 | − jmpl %g1 + %lo(sys_sendto), %g0 | |
| 141 | −38: lduwa [%o1 + 0x4] %asi, %o1 | |
| 142 | −do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ | |
| 143 | −39: ldswa [%o1 + 0x0] %asi, %o0 | |
| 144 | − sethi %hi(sys_recvfrom), %g1 | |
| 145 | −40: lduwa [%o1 + 0x8] %asi, %o2 | |
| 146 | −41: lduwa [%o1 + 0xc] %asi, %o3 | |
| 147 | −42: lduwa [%o1 + 0x10] %asi, %o4 | |
| 148 | −43: lduwa [%o1 + 0x14] %asi, %o5 | |
| 149 | − jmpl %g1 + %lo(sys_recvfrom), %g0 | |
| 150 | −44: lduwa [%o1 + 0x4] %asi, %o1 | |
| 151 | −do_sys_shutdown: /* sys_shutdown(int, int) */ | |
| 152 | −45: ldswa [%o1 + 0x0] %asi, %o0 | |
| 153 | − sethi %hi(sys_shutdown), %g1 | |
| 154 | − jmpl %g1 + %lo(sys_shutdown), %g0 | |
| 155 | −46: ldswa [%o1 + 0x4] %asi, %o1 | |
| 156 | − nop | |
| 157 | − nop | |
| 158 | − nop | |
| 159 | − nop | |
| 160 | −do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */ | |
| 161 | −47: ldswa [%o1 + 0x0] %asi, %o0 | |
| 162 | − sethi %hi(sys_setsockopt), %g1 | |
| 163 | −48: ldswa [%o1 + 0x8] %asi, %o2 | |
| 164 | −49: lduwa [%o1 + 0xc] %asi, %o3 | |
| 165 | −50: ldswa [%o1 + 0x10] %asi, %o4 | |
| 166 | − jmpl %g1 + %lo(sys_setsockopt), %g0 | |
| 167 | −51: ldswa [%o1 + 0x4] %asi, %o1 | |
| 168 | − nop | |
| 169 | −do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */ | |
| 170 | −52: ldswa [%o1 + 0x0] %asi, %o0 | |
| 171 | − sethi %hi(sys_getsockopt), %g1 | |
| 172 | −53: ldswa [%o1 + 0x8] %asi, %o2 | |
| 173 | −54: lduwa [%o1 + 0xc] %asi, %o3 | |
| 174 | −55: lduwa [%o1 + 0x10] %asi, %o4 | |
| 175 | − jmpl %g1 + %lo(sys_getsockopt), %g0 | |
| 176 | −56: ldswa [%o1 + 0x4] %asi, %o1 | |
| 177 | − nop | |
| 178 | −do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */ | |
| 179 | −57: ldswa [%o1 + 0x0] %asi, %o0 | |
| 180 | − sethi %hi(compat_sys_sendmsg), %g1 | |
| 181 | −58: lduwa [%o1 + 0x8] %asi, %o2 | |
| 182 | − jmpl %g1 + %lo(compat_sys_sendmsg), %g0 | |
| 183 | −59: lduwa [%o1 + 0x4] %asi, %o1 | |
| 184 | − nop | |
| 185 | − nop | |
| 186 | − nop | |
| 187 | −do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */ | |
| 188 | −60: ldswa [%o1 + 0x0] %asi, %o0 | |
| 189 | − sethi %hi(compat_sys_recvmsg), %g1 | |
| 190 | −61: lduwa [%o1 + 0x8] %asi, %o2 | |
| 191 | − jmpl %g1 + %lo(compat_sys_recvmsg), %g0 | |
| 192 | −62: lduwa [%o1 + 0x4] %asi, %o1 | |
| 193 | − nop | |
| 194 | − nop | |
| 195 | − nop | |
| 196 | −do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */ | |
| 197 | −63: ldswa [%o1 + 0x0] %asi, %o0 | |
| 198 | − sethi %hi(sys_accept4), %g1 | |
| 199 | −64: lduwa [%o1 + 0x8] %asi, %o2 | |
| 200 | −65: ldswa [%o1 + 0xc] %asi, %o3 | |
| 201 | − jmpl %g1 + %lo(sys_accept4), %g0 | |
| 202 | −66: lduwa [%o1 + 0x4] %asi, %o1 | |
| 203 | − nop | |
| 204 | − nop | |
| 205 | − | |
| 206 | − .section __ex_table,"a" | |
| 207 | − .align 4 | |
| 208 | − .word 1b, __retl_efault, 2b, __retl_efault | |
| 209 | − .word 3b, __retl_efault, 4b, __retl_efault | |
| 210 | − .word 5b, __retl_efault, 6b, __retl_efault | |
| 211 | − .word 7b, __retl_efault, 8b, __retl_efault | |
| 212 | − .word 9b, __retl_efault, 10b, __retl_efault | |
| 213 | − .word 11b, __retl_efault, 12b, __retl_efault | |
| 214 | − .word 13b, __retl_efault, 14b, __retl_efault | |
| 215 | − .word 15b, __retl_efault, 16b, __retl_efault | |
| 216 | − .word 17b, __retl_efault, 18b, __retl_efault | |
| 217 | − .word 19b, __retl_efault, 20b, __retl_efault | |
| 218 | − .word 21b, __retl_efault, 22b, __retl_efault | |
| 219 | − .word 23b, __retl_efault, 24b, __retl_efault | |
| 220 | − .word 25b, __retl_efault, 26b, __retl_efault | |
| 221 | − .word 27b, __retl_efault, 28b, __retl_efault | |
| 222 | − .word 29b, __retl_efault, 30b, __retl_efault | |
| 223 | − .word 31b, __retl_efault, 32b, __retl_efault | |
| 224 | − .word 33b, __retl_efault, 34b, __retl_efault | |
| 225 | − .word 35b, __retl_efault, 36b, __retl_efault | |
| 226 | − .word 37b, __retl_efault, 38b, __retl_efault | |
| 227 | − .word 39b, __retl_efault, 40b, __retl_efault | |
| 228 | − .word 41b, __retl_efault, 42b, __retl_efault | |
| 229 | − .word 43b, __retl_efault, 44b, __retl_efault | |
| 230 | − .word 45b, __retl_efault, 46b, __retl_efault | |
| 231 | − .word 47b, __retl_efault, 48b, __retl_efault | |
| 232 | − .word 49b, __retl_efault, 50b, __retl_efault | |
| 233 | − .word 51b, __retl_efault, 52b, __retl_efault | |
| 234 | − .word 53b, __retl_efault, 54b, __retl_efault | |
| 235 | − .word 55b, __retl_efault, 56b, __retl_efault | |
| 236 | − .word 57b, __retl_efault, 58b, __retl_efault | |
| 237 | − .word 59b, __retl_efault, 60b, __retl_efault | |
| 238 | − .word 61b, __retl_efault, 62b, __retl_efault | |
| 239 | − .word 63b, __retl_efault, 64b, __retl_efault | |
| 240 | − .word 65b, __retl_efault, 66b, __retl_efault | |
| 241 | − .previous | |
| @@ -117,7 +117,7 @@ · 116 unmodified lines | ||
| 117 | 117 | 90 common dup2 sys_dup2 |
| 118 | 118 | 91 32 setfsuid32 sys_setfsuid |
| 119 | 119 | 92 common fcntl sys_fcntl compat_sys_fcntl |
| 120 | −93 common select sys_select | |
| 120 | +93 common select sys_select compat_sys_select | |
| 121 | 121 | 94 32 setfsgid32 sys_setfsgid |
| 122 | 122 | 95 common fsync sys_fsync |
| 123 | 123 | 96 common setpriority sys_setpriority |
| @@ -155,7 +155,7 @@ · 31 unmodified lines | ||
| 155 | 155 | 123 32 fchown sys_fchown16 |
| 156 | 156 | 123 64 fchown sys_fchown |
| 157 | 157 | 124 common fchmod sys_fchmod |
| 158 | −125 common recvfrom sys_recvfrom | |
| 158 | +125 common recvfrom sys_recvfrom compat_sys_recvfrom | |
| 159 | 159 | 126 32 setreuid sys_setreuid16 |
| 160 | 160 | 126 64 setreuid sys_setreuid |
| 161 | 161 | 127 32 setregid sys_setregid16 |
| @@ -247,7 +247,7 @@ · 85 unmodified lines | ||
| 247 | 247 | 204 32 readdir sys_old_readdir compat_sys_old_readdir |
| 248 | 248 | 204 64 readdir sys_nis_syscall |
| 249 | 249 | 205 common readahead sys_readahead compat_sys_readahead |
| 250 | −206 common socketcall sys_socketcall sys32_socketcall | |
| 250 | +206 common socketcall sys_socketcall compat_sys_socketcall | |
| 251 | 251 | 207 common syslog sys_syslog |
| 252 | 252 | 208 common lookup_dcookie sys_ni_syscall |
| 253 | 253 | 209 common fadvise64 sys_fadvise64 compat_sys_fadvise64 |
| @@ -461,7 +461,7 @@ · 207 unmodified lines | ||
| 461 | 461 | 412 32 utimensat_time64 sys_utimensat sys_utimensat |
| 462 | 462 | 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 |
| 463 | 463 | 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 |
| 464 | −416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents | |
| 464 | +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 | |
| 465 | 465 | 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 |
| 466 | 466 | 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend |
| 467 | 467 | 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive |
| @@ -420,7 +420,7 @@ · 419 unmodified lines | ||
| 420 | 420 | 412 i386 utimensat_time64 sys_utimensat |
| 421 | 421 | 413 i386 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 |
| 422 | 422 | 414 i386 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 |
| 423 | −416 i386 io_pgetevents_time64 sys_io_pgetevents | |
| 423 | +416 i386 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 | |
| 424 | 424 | 417 i386 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 |
| 425 | 425 | 418 i386 mq_timedsend_time64 sys_mq_timedsend |
| 426 | 426 | 419 i386 mq_timedreceive_time64 sys_mq_timedreceive |
| @@ -93,10 +93,9 @@ static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp, · 92 unmodified lines | ||
| 93 | 93 | \ |
| 94 | 94 | asm volatile(ALTERNATIVE(_lock_loc \ |
| 95 | 95 | "call cmpxchg8b_emu", \ |
| 96 | − _lock "cmpxchg8b %[ptr]", X86_FEATURE_CX8) \ | |
| 97 | − : [ptr] "+m" (*(_ptr)), \ | |
| 98 | − "+a" (o.low), "+d" (o.high) \ | |
| 99 | − : "b" (n.low), "c" (n.high), "S" (_ptr) \ | |
| 96 | + _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \ | |
| 97 | + : "+a" (o.low), "+d" (o.high) \ | |
| 98 | + : "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \ | |
| 100 | 99 | : "memory"); \ |
| 101 | 100 | \ |
| 102 | 101 | o.full; \ |
| @@ -122,12 +121,11 @@ static __always_inline u64 arch_cmpxchg64_local(volatile u64 *ptr, u64 old, u64 · 19 unmodified lines | ||
| 122 | 121 | \ |
| 123 | 122 | asm volatile(ALTERNATIVE(_lock_loc \ |
| 124 | 123 | "call cmpxchg8b_emu", \ |
| 125 | − _lock "cmpxchg8b %[ptr]", X86_FEATURE_CX8) \ | |
| 124 | + _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \ | |
| 126 | 125 | CC_SET(e) \ |
| 127 | 126 | : CC_OUT(e) (ret), \ |
| 128 | − [ptr] "+m" (*(_ptr)), \ | |
| 129 | 127 | "+a" (o.low), "+d" (o.high) \ |
| 130 | − : "b" (n.low), "c" (n.high), "S" (_ptr) \ | |
| 128 | + : "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \ | |
| 131 | 129 | : "memory"); \ |
| 132 | 130 | \ |
| 133 | 131 | if (unlikely(!ret)) \ |
| @@ -73,19 +73,16 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, · 72 unmodified lines | ||
| 73 | 73 | #endif |
| 74 | 74 | |
| 75 | 75 | /* |
| 76 | − * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), | |
| 77 | − * but not enough for x86 stack utilization comfort. To keep | |
| 78 | − * reasonable stack head room, reduce the maximum offset to 8 bits. | |
| 79 | − * | |
| 80 | − * The actual entropy will be further reduced by the compiler when | |
| 81 | − * applying stack alignment constraints (see cc_stack_align4/8 in | |
| 76 | + * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 | |
| 77 | + * bits. The actual entropy will be further reduced by the compiler | |
| 78 | + * when applying stack alignment constraints (see cc_stack_align4/8 in | |
| 82 | 79 | * arch/x86/Makefile), which will remove the 3 (x86_64) or 2 (ia32) |
| 83 | 80 | * low bits from any entropy chosen here. |
| 84 | 81 | * |
| 85 | − * Therefore, final stack offset entropy will be 5 (x86_64) or | |
| 86 | − * 6 (ia32) bits. | |
| 82 | + * Therefore, final stack offset entropy will be 7 (x86_64) or | |
| 83 | + * 8 (ia32) bits. | |
| 87 | 84 | */ |
| 88 | − choose_random_kstack_offset(rdtsc() & 0xFF); | |
| 85 | + choose_random_kstack_offset(rdtsc()); | |
| 89 | 86 | } |
| 90 | 87 | #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare |
| 91 | 88 | |
| @@ -27,25 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | unsigned long profile_pc(struct pt_regs *regs) |
| 29 | 29 | { |
| 30 | − unsigned long pc = instruction_pointer(regs); | |
| 31 | − | |
| 32 | − if (!user_mode(regs) && in_lock_functions(pc)) { | |
| 33 | −#ifdef CONFIG_FRAME_POINTER | |
| 34 | − return *(unsigned long *)(regs->bp + sizeof(long)); | |
| 35 | −#else | |
| 36 | − unsigned long *sp = (unsigned long *)regs->sp; | |
| 37 | − /* | |
| 38 | − * Return address is either directly at stack pointer | |
| 39 | − * or above a saved flags. Eflags has bits 22-31 zero, | |
| 40 | − * kernel addresses don't. | |
| 41 | − */ | |
| 42 | − if (sp[0] >> 22) | |
| 43 | − return sp[0]; | |
| 44 | − if (sp[1] >> 22) | |
| 45 | − return sp[1]; | |
| 46 | −#endif | |
| 47 | − } | |
| 48 | − return pc; | |
| 30 | + return instruction_pointer(regs); | |
| 49 | 31 | } |
| 50 | 32 | EXPORT_SYMBOL(profile_pc); |
| 51 | 33 | |
| @@ -1975,8 +1975,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 1974 unmodified lines | ||
| 1975 | 1975 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); |
| 1976 | 1976 | |
| 1977 | 1977 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
| 1978 | − if (!host) | |
| 1979 | − return -ENOMEM; | |
| 1978 | + if (!host) { | |
| 1979 | + rc = -ENOMEM; | |
| 1980 | + goto err_rm_sysfs_file; | |
| 1981 | + } | |
| 1980 | 1982 | host->private_data = hpriv; |
| 1981 | 1983 | |
| 1982 | 1984 | if (ahci_init_msi(pdev, n_ports, hpriv) < 0) { |
| @@ -2031,11 +2033,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 48 unmodified lines | ||
| 2031 | 2033 | /* initialize adapter */ |
| 2032 | 2034 | rc = ahci_configure_dma_masks(pdev, hpriv); |
| 2033 | 2035 | if (rc) |
| 2034 | − return rc; | |
| 2036 | + goto err_rm_sysfs_file; | |
| 2035 | 2037 | |
| 2036 | 2038 | rc = ahci_pci_reset_controller(host); |
| 2037 | 2039 | if (rc) |
| 2038 | − return rc; | |
| 2040 | + goto err_rm_sysfs_file; | |
| 2039 | 2041 | |
| 2040 | 2042 | ahci_pci_init_controller(host); |
| 2041 | 2043 | ahci_pci_print_info(host); |
| @@ -2044,10 +2046,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 2 unmodified lines | ||
| 2044 | 2046 | |
| 2045 | 2047 | rc = ahci_host_activate(host, &ahci_sht); |
| 2046 | 2048 | if (rc) |
| 2047 | − return rc; | |
| 2049 | + goto err_rm_sysfs_file; | |
| 2048 | 2050 | |
| 2049 | 2051 | pm_runtime_put_noidle(&pdev->dev); |
| 2050 | 2052 | return 0; |
| 2053 | + | |
| 2054 | +err_rm_sysfs_file: | |
| 2055 | + sysfs_remove_file_from_group(&pdev->dev.kobj, | |
| 2056 | + &dev_attr_remapped_nvme.attr, NULL); | |
| 2057 | + return rc; | |
| 2051 | 2058 | } |
| 2052 | 2059 | |
| 2053 | 2060 | static void ahci_shutdown_one(struct pci_dev *pdev) |
| @@ -4137,8 +4137,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { · 4136 unmodified lines | ||
| 4137 | 4137 | { "PIONEER BD-RW BDR-205", NULL, ATA_HORKAGE_NOLPM }, |
| 4138 | 4138 | |
| 4139 | 4139 | /* Crucial devices with broken LPM support */ |
| 4140 | − { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, | |
| 4141 | − { "CT240BX500SSD1", NULL, ATA_HORKAGE_NOLPM }, | |
| 4140 | + { "CT*0BX*00SSD1", NULL, ATA_HORKAGE_NOLPM }, | |
| 4142 | 4141 | |
| 4143 | 4142 | /* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */ |
| 4144 | 4143 | { "Crucial_CT512MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | |
| @@ -5490,6 +5489,18 @@ struct ata_port *ata_port_alloc(struct ata_host *host) · 1345 unmodified lines | ||
| 5490 | 5489 | return ap; |
| 5491 | 5490 | } |
| 5492 | 5491 | |
| 5492 | +void ata_port_free(struct ata_port *ap) | |
| 5493 | +{ | |
| 5494 | + if (!ap) | |
| 5495 | + return; | |
| 5496 | + | |
| 5497 | + kfree(ap->pmp_link); | |
| 5498 | + kfree(ap->slave_link); | |
| 5499 | + kfree(ap->ncq_sense_buf); | |
| 5500 | + kfree(ap); | |
| 5501 | +} | |
| 5502 | +EXPORT_SYMBOL_GPL(ata_port_free); | |
| 5503 | + | |
| 5493 | 5504 | static void ata_devres_release(struct device *gendev, void *res) |
| 5494 | 5505 | { |
| 5495 | 5506 | struct ata_host *host = dev_get_drvdata(gendev); |
| @@ -5516,12 +5527,7 @@ static void ata_host_release(struct kref *kref) · 20 unmodified lines | ||
| 5516 | 5527 | int i; |
| 5517 | 5528 | |
| 5518 | 5529 | for (i = 0; i < host->n_ports; i++) { |
| 5519 | − struct ata_port *ap = host->ports[i]; | |
| 5520 | − | |
| 5521 | − kfree(ap->pmp_link); | |
| 5522 | − kfree(ap->slave_link); | |
| 5523 | − kfree(ap->ncq_sense_buf); | |
| 5524 | − kfree(ap); | |
| 5530 | + ata_port_free(host->ports[i]); | |
| 5525 | 5531 | host->ports[i] = NULL; |
| 5526 | 5532 | } |
| 5527 | 5533 | kfree(host); |
| @@ -5571,8 +5577,10 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) · 43 unmodified lines | ||
| 5571 | 5577 | if (!host) |
| 5572 | 5578 | return NULL; |
| 5573 | 5579 | |
| 5574 | − if (!devres_open_group(dev, NULL, GFP_KERNEL)) | |
| 5575 | − goto err_free; | |
| 5580 | + if (!devres_open_group(dev, NULL, GFP_KERNEL)) { | |
| 5581 | + kfree(host); | |
| 5582 | + return NULL; | |
| 5583 | + } | |
| 5576 | 5584 | |
| 5577 | 5585 | dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); |
| 5578 | 5586 | if (!dr) |
| @@ -5604,8 +5612,6 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) · 25 unmodified lines | ||
| 5604 | 5612 | |
| 5605 | 5613 | err_out: |
| 5606 | 5614 | devres_release_group(dev, NULL); |
| 5607 | − err_free: | |
| 5608 | − kfree(host); | |
| 5609 | 5615 | return NULL; |
| 5610 | 5616 | } |
| 5611 | 5617 | EXPORT_SYMBOL_GPL(ata_host_alloc); |
| @@ -5904,7 +5910,7 @@ int ata_host_register(struct ata_host *host, const struct scsi_host_template *sh · 292 unmodified lines | ||
| 5904 | 5910 | * allocation time. |
| 5905 | 5911 | */ |
| 5906 | 5912 | for (i = host->n_ports; host->ports[i]; i++) |
| 5907 | − kfree(host->ports[i]); | |
| 5913 | + ata_port_free(host->ports[i]); | |
| 5908 | 5914 | |
| 5909 | 5915 | /* give ports names and add SCSI hosts */ |
| 5910 | 5916 | for (i = 0; i < host->n_ports; i++) { |
| @@ -382,7 +382,7 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, · 381 unmodified lines | ||
| 382 | 382 | |
| 383 | 383 | /* The first 4 bytes indicates the Intel PCIe specific packet type */ |
| 384 | 384 | pdata = skb_pull_data(skb, BTINTEL_PCIE_HCI_TYPE_LEN); |
| 385 | − if (!data) { | |
| 385 | + if (!pdata) { | |
| 386 | 386 | bt_dev_err(hdev, "Corrupted packet received"); |
| 387 | 387 | ret = -EILSEQ; |
| 388 | 388 | goto exit_error; |
| @@ -281,7 +281,7 @@ static u8 crc8_table[CRC8_TABLE_SIZE]; · 280 unmodified lines | ||
| 281 | 281 | |
| 282 | 282 | /* Default configurations */ |
| 283 | 283 | #define DEFAULT_H2C_WAKEUP_MODE WAKEUP_METHOD_BREAK |
| 284 | −#define DEFAULT_PS_MODE PS_MODE_DISABLE | |
| 284 | +#define DEFAULT_PS_MODE PS_MODE_ENABLE | |
| 285 | 285 | #define FW_INIT_BAUDRATE HCI_NXP_PRI_BAUDRATE |
| 286 | 286 | |
| 287 | 287 | static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode, |
| @@ -495,6 +495,10 @@ struct bcm4377_data; · 494 unmodified lines | ||
| 495 | 495 | * extended scanning |
| 496 | 496 | * broken_mws_transport_config: Set to true if the chip erroneously claims to |
| 497 | 497 | * support MWS Transport Configuration |
| 498 | + * broken_le_ext_adv_report_phy: Set to true if this chip stuffs flags inside | |
| 499 | + * reserved bits of Primary/Secondary_PHY inside | |
| 500 | + * LE Extended Advertising Report events which | |
| 501 | + * have to be ignored | |
| 498 | 502 | * send_calibration: Optional callback to send calibration data |
| 499 | 503 | * send_ptb: Callback to send "PTB" regulatory/calibration data |
| 500 | 504 | */ |
| @@ -513,6 +517,7 @@ struct bcm4377_hw { · 12 unmodified lines | ||
| 513 | 517 | unsigned long broken_ext_scan : 1; |
| 514 | 518 | unsigned long broken_mws_transport_config : 1; |
| 515 | 519 | unsigned long broken_le_coded : 1; |
| 520 | + unsigned long broken_le_ext_adv_report_phy : 1; | |
| 516 | 521 | |
| 517 | 522 | int (*send_calibration)(struct bcm4377_data *bcm4377); |
| 518 | 523 | int (*send_ptb)(struct bcm4377_data *bcm4377, |
| @@ -716,7 +721,7 @@ static void bcm4377_handle_ack(struct bcm4377_data *bcm4377, · 197 unmodified lines | ||
| 716 | 721 | ring->events[msgid] = NULL; |
| 717 | 722 | } |
| 718 | 723 | |
| 719 | − bitmap_release_region(ring->msgids, msgid, ring->n_entries); | |
| 724 | + bitmap_release_region(ring->msgids, msgid, 0); | |
| 720 | 725 | |
| 721 | 726 | unlock: |
| 722 | 727 | spin_unlock_irqrestore(&ring->lock, flags); |
| @@ -2373,6 +2378,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 1650 unmodified lines | ||
| 2373 | 2378 | set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks); |
| 2374 | 2379 | if (bcm4377->hw->broken_le_coded) |
| 2375 | 2380 | set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks); |
| 2381 | + if (bcm4377->hw->broken_le_ext_adv_report_phy) | |
| 2382 | + set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks); | |
| 2376 | 2383 | |
| 2377 | 2384 | pci_set_drvdata(pdev, bcm4377); |
| 2378 | 2385 | hci_set_drvdata(hdev, bcm4377); |
| @@ -2477,6 +2484,7 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = { · 98 unmodified lines | ||
| 2477 | 2484 | .clear_pciecfg_subsystem_ctrl_bit19 = true, |
| 2478 | 2485 | .broken_mws_transport_config = true, |
| 2479 | 2486 | .broken_le_coded = true, |
| 2487 | + .broken_le_ext_adv_report_phy = true, | |
| 2480 | 2488 | .send_calibration = bcm4387_send_calibration, |
| 2481 | 2489 | .send_ptb = bcm4378_send_ptb, |
| 2482 | 2490 | }, |
| @@ -2450,15 +2450,27 @@ static void qca_serdev_shutdown(struct device *dev) · 2449 unmodified lines | ||
| 2450 | 2450 | struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); |
| 2451 | 2451 | struct hci_uart *hu = &qcadev->serdev_hu; |
| 2452 | 2452 | struct hci_dev *hdev = hu->hdev; |
| 2453 | − struct qca_data *qca = hu->priv; | |
| 2454 | 2453 | const u8 ibs_wake_cmd[] = { 0xFD }; |
| 2455 | 2454 | const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 }; |
| 2456 | 2455 | |
| 2457 | 2456 | if (qcadev->btsoc_type == QCA_QCA6390) { |
| 2458 | − if (test_bit(QCA_BT_OFF, &qca->flags) || | |
| 2459 | − !test_bit(HCI_RUNNING, &hdev->flags)) | |
| 2457 | + /* The purpose of sending the VSC is to reset SOC into a initial | |
| 2458 | + * state and the state will ensure next hdev->setup() success. | |
| 2459 | + * if HCI_QUIRK_NON_PERSISTENT_SETUP is set, it means that | |
| 2460 | + * hdev->setup() can do its job regardless of SoC state, so | |
| 2461 | + * don't need to send the VSC. | |
| 2462 | + * if HCI_SETUP is set, it means that hdev->setup() was never | |
| 2463 | + * invoked and the SOC is already in the initial state, so | |
| 2464 | + * don't also need to send the VSC. | |
| 2465 | + */ | |
| 2466 | + if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks) || | |
| 2467 | + hci_dev_test_flag(hdev, HCI_SETUP)) | |
| 2460 | 2468 | return; |
| 2461 | 2469 | |
| 2470 | + /* The serdev must be in open state when conrol logic arrives | |
| 2471 | + * here, so also fix the use-after-free issue caused by that | |
| 2472 | + * the serdev is flushed or wrote after it is closed. | |
| 2473 | + */ | |
| 2462 | 2474 | serdev_device_write_flush(serdev); |
| 2463 | 2475 | ret = serdev_device_write_buf(serdev, ibs_wake_cmd, |
| 2464 | 2476 | sizeof(ibs_wake_cmd)); |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/bitops.h> |
| 9 | +#include <linux/clk.h> | |
| 9 | 10 | #include <linux/counter.h> |
| 10 | 11 | #include <linux/kernel.h> |
| 11 | 12 | #include <linux/mod_devicetable.h> |
| @@ -376,6 +377,7 @@ static int ti_eqep_probe(struct platform_device *pdev) · 364 unmodified lines | ||
| 376 | 377 | struct counter_device *counter; |
| 377 | 378 | struct ti_eqep_cnt *priv; |
| 378 | 379 | void __iomem *base; |
| 380 | + struct clk *clk; | |
| 379 | 381 | int err; |
| 380 | 382 | |
| 381 | 383 | counter = devm_counter_alloc(dev, sizeof(*priv)); |
| @@ -415,6 +417,10 @@ static int ti_eqep_probe(struct platform_device *pdev) · 33 unmodified lines | ||
| 415 | 417 | pm_runtime_enable(dev); |
| 416 | 418 | pm_runtime_get_sync(dev); |
| 417 | 419 | |
| 420 | + clk = devm_clk_get_enabled(dev, NULL); | |
| 421 | + if (IS_ERR(clk)) | |
| 422 | + return dev_err_probe(dev, PTR_ERR(clk), "failed to enable clock\n"); | |
| 423 | + | |
| 418 | 424 | err = counter_add(counter); |
| 419 | 425 | if (err < 0) { |
| 420 | 426 | pm_runtime_put_sync(dev); |
| @@ -355,15 +355,14 @@ static void intel_pstate_set_itmt_prio(int cpu) · 354 unmodified lines | ||
| 355 | 355 | int ret; |
| 356 | 356 | |
| 357 | 357 | ret = cppc_get_perf_caps(cpu, &cppc_perf); |
| 358 | − if (ret) | |
| 359 | − return; | |
| 360 | − | |
| 361 | 358 | /* |
| 362 | − * On some systems with overclocking enabled, CPPC.highest_perf is hardcoded to 0xff. | |
| 363 | − * In this case we can't use CPPC.highest_perf to enable ITMT. | |
| 364 | − * In this case we can look at MSR_HWP_CAPABILITIES bits [8:0] to decide. | |
| 359 | + * If CPPC is not available, fall back to MSR_HWP_CAPABILITIES bits [8:0]. | |
| 360 | + * | |
| 361 | + * Also, on some systems with overclocking enabled, CPPC.highest_perf is | |
| 362 | + * hardcoded to 0xff, so CPPC.highest_perf cannot be used to enable ITMT. | |
| 363 | + * Fall back to MSR_HWP_CAPABILITIES then too. | |
| 365 | 364 | */ |
| 366 | − if (cppc_perf.highest_perf == CPPC_MAX_PERF) | |
| 365 | + if (ret || cppc_perf.highest_perf == CPPC_MAX_PERF) | |
| 367 | 366 | cppc_perf.highest_perf = HWP_HIGHEST_PERF(READ_ONCE(all_cpu_data[cpu]->hwp_cap_cached)); |
| 368 | 367 | |
| 369 | 368 | /* |
| @@ -39,7 +39,8 @@ intel_qat-objs := adf_cfg.o \ · 38 unmodified lines | ||
| 39 | 39 | adf_sysfs_rl.o \ |
| 40 | 40 | qat_uclo.o \ |
| 41 | 41 | qat_hal.o \ |
| 42 | − qat_bl.o | |
| 42 | + qat_bl.o \ | |
| 43 | + qat_mig_dev.o | |
| 43 | 44 | |
| 44 | 45 | intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o \ |
| 45 | 46 | adf_fw_counters.o \ |
| @@ -56,6 +57,6 @@ intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o \ · 10 unmodified lines | ||
| 56 | 57 | intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o adf_pfvf_utils.o \ |
| 57 | 58 | adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \ |
| 58 | 59 | adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \ |
| 59 | − adf_gen2_pfvf.o adf_gen4_pfvf.o qat_mig_dev.o | |
| 60 | + adf_gen2_pfvf.o adf_gen4_pfvf.o | |
| 60 | 61 | |
| 61 | 62 | intel_qat-$(CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION) += adf_heartbeat_inject.o |
| @@ -52,6 +52,14 @@ int devm_cxl_add_passthrough_decoder(struct cxl_port *port) · 51 unmodified lines | ||
| 52 | 52 | struct cxl_dport *dport = NULL; |
| 53 | 53 | int single_port_map[1]; |
| 54 | 54 | unsigned long index; |
| 55 | + struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev); | |
| 56 | + | |
| 57 | + /* | |
| 58 | + * Capability checks are moot for passthrough decoders, support | |
| 59 | + * any and all possibilities. | |
| 60 | + */ | |
| 61 | + cxlhdm->interleave_mask = ~0U; | |
| 62 | + cxlhdm->iw_cap_mask = ~0UL; | |
| 55 | 63 | |
| 56 | 64 | cxlsd = cxl_switch_decoder_alloc(port, 1); |
| 57 | 65 | if (IS_ERR(cxlsd)) |
| @@ -79,6 +87,11 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm) · 21 unmodified lines | ||
| 79 | 87 | cxlhdm->interleave_mask |= GENMASK(11, 8); |
| 80 | 88 | if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_14_12, hdm_cap)) |
| 81 | 89 | cxlhdm->interleave_mask |= GENMASK(14, 12); |
| 90 | + cxlhdm->iw_cap_mask = BIT(1) | BIT(2) | BIT(4) | BIT(8); | |
| 91 | + if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY, hdm_cap)) | |
| 92 | + cxlhdm->iw_cap_mask |= BIT(3) | BIT(6) | BIT(12); | |
| 93 | + if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_16_WAY, hdm_cap)) | |
| 94 | + cxlhdm->iw_cap_mask |= BIT(16); | |
| 82 | 95 | } |
| 83 | 96 | |
| 84 | 97 | static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) |
| @@ -62,10 +62,14 @@ static int match_nvdimm_bridge(struct device *dev, void *data) · 61 unmodified lines | ||
| 62 | 62 | return is_cxl_nvdimm_bridge(dev); |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | −struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd) | |
| 65 | +/** | |
| 66 | + * cxl_find_nvdimm_bridge() - find a bridge device relative to a port | |
| 67 | + * @port: any descendant port of an nvdimm-bridge associated | |
| 68 | + * root-cxl-port | |
| 69 | + */ | |
| 70 | +struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port) | |
| 66 | 71 | { |
| 67 | − struct cxl_root *cxl_root __free(put_cxl_root) = | |
| 68 | − find_cxl_root(cxlmd->endpoint); | |
| 72 | + struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port); | |
| 69 | 73 | struct device *dev; |
| 70 | 74 | |
| 71 | 75 | if (!cxl_root) |
| @@ -242,18 +246,20 @@ static void cxlmd_release_nvdimm(void *_cxlmd) · 170 unmodified lines | ||
| 242 | 246 | |
| 243 | 247 | /** |
| 244 | 248 | * devm_cxl_add_nvdimm() - add a bridge between a cxl_memdev and an nvdimm |
| 249 | + * @parent_port: parent port for the (to be added) @cxlmd endpoint port | |
| 245 | 250 | * @cxlmd: cxl_memdev instance that will perform LIBNVDIMM operations |
| 246 | 251 | * |
| 247 | 252 | * Return: 0 on success negative error code on failure. |
| 248 | 253 | */ |
| 249 | −int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd) | |
| 254 | +int devm_cxl_add_nvdimm(struct cxl_port *parent_port, | |
| 255 | + struct cxl_memdev *cxlmd) | |
| 250 | 256 | { |
| 251 | 257 | struct cxl_nvdimm_bridge *cxl_nvb; |
| 252 | 258 | struct cxl_nvdimm *cxl_nvd; |
| 253 | 259 | struct device *dev; |
| 254 | 260 | int rc; |
| 255 | 261 | |
| 256 | − cxl_nvb = cxl_find_nvdimm_bridge(cxlmd); | |
| 262 | + cxl_nvb = cxl_find_nvdimm_bridge(parent_port); | |
| 257 | 263 | if (!cxl_nvb) |
| 258 | 264 | return -ENODEV; |
| 259 | 265 | |
| @@ -1101,6 +1101,26 @@ static int cxl_port_attach_region(struct cxl_port *port, · 1100 unmodified lines | ||
| 1101 | 1101 | } |
| 1102 | 1102 | cxld = cxl_rr->decoder; |
| 1103 | 1103 | |
| 1104 | + /* | |
| 1105 | + * the number of targets should not exceed the target_count | |
| 1106 | + * of the decoder | |
| 1107 | + */ | |
| 1108 | + if (is_switch_decoder(&cxld->dev)) { | |
| 1109 | + struct cxl_switch_decoder *cxlsd; | |
| 1110 | + | |
| 1111 | + cxlsd = to_cxl_switch_decoder(&cxld->dev); | |
| 1112 | + if (cxl_rr->nr_targets > cxlsd->nr_targets) { | |
| 1113 | + dev_dbg(&cxlr->dev, | |
| 1114 | + "%s:%s %s add: %s:%s @ %d overflows targets: %d\n", | |
| 1115 | + dev_name(port->uport_dev), dev_name(&port->dev), | |
| 1116 | + dev_name(&cxld->dev), dev_name(&cxlmd->dev), | |
| 1117 | + dev_name(&cxled->cxld.dev), pos, | |
| 1118 | + cxlsd->nr_targets); | |
| 1119 | + rc = -ENXIO; | |
| 1120 | + goto out_erase; | |
| 1121 | + } | |
| 1122 | + } | |
| 1123 | + | |
| 1104 | 1124 | rc = cxl_rr_ep_add(cxl_rr, cxled); |
| 1105 | 1125 | if (rc) { |
| 1106 | 1126 | dev_dbg(&cxlr->dev, |
| @@ -1210,6 +1230,50 @@ static int check_last_peer(struct cxl_endpoint_decoder *cxled, · 103 unmodified lines | ||
| 1210 | 1230 | return 0; |
| 1211 | 1231 | } |
| 1212 | 1232 | |
| 1233 | +static int check_interleave_cap(struct cxl_decoder *cxld, int iw, int ig) | |
| 1234 | +{ | |
| 1235 | + struct cxl_port *port = to_cxl_port(cxld->dev.parent); | |
| 1236 | + struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev); | |
| 1237 | + unsigned int interleave_mask; | |
| 1238 | + u8 eiw; | |
| 1239 | + u16 eig; | |
| 1240 | + int high_pos, low_pos; | |
| 1241 | + | |
| 1242 | + if (!test_bit(iw, &cxlhdm->iw_cap_mask)) | |
| 1243 | + return -ENXIO; | |
| 1244 | + /* | |
| 1245 | + * Per CXL specification r3.1(8.2.4.20.13 Decoder Protection), | |
| 1246 | + * if eiw < 8: | |
| 1247 | + * DPAOFFSET[51: eig + 8] = HPAOFFSET[51: eig + 8 + eiw] | |
| 1248 | + * DPAOFFSET[eig + 7: 0] = HPAOFFSET[eig + 7: 0] | |
| 1249 | + * | |
| 1250 | + * when the eiw is 0, all the bits of HPAOFFSET[51: 0] are used, the | |
| 1251 | + * interleave bits are none. | |
| 1252 | + * | |
| 1253 | + * if eiw >= 8: | |
| 1254 | + * DPAOFFSET[51: eig + 8] = HPAOFFSET[51: eig + eiw] / 3 | |
| 1255 | + * DPAOFFSET[eig + 7: 0] = HPAOFFSET[eig + 7: 0] | |
| 1256 | + * | |
| 1257 | + * when the eiw is 8, all the bits of HPAOFFSET[51: 0] are used, the | |
| 1258 | + * interleave bits are none. | |
| 1259 | + */ | |
| 1260 | + ways_to_eiw(iw, &eiw); | |
| 1261 | + if (eiw == 0 || eiw == 8) | |
| 1262 | + return 0; | |
| 1263 | + | |
| 1264 | + granularity_to_eig(ig, &eig); | |
| 1265 | + if (eiw > 8) | |
| 1266 | + high_pos = eiw + eig - 1; | |
| 1267 | + else | |
| 1268 | + high_pos = eiw + eig + 7; | |
| 1269 | + low_pos = eig + 8; | |
| 1270 | + interleave_mask = GENMASK(high_pos, low_pos); | |
| 1271 | + if (interleave_mask & ~cxlhdm->interleave_mask) | |
| 1272 | + return -ENXIO; | |
| 1273 | + | |
| 1274 | + return 0; | |
| 1275 | +} | |
| 1276 | + | |
| 1213 | 1277 | static int cxl_port_setup_targets(struct cxl_port *port, |
| 1214 | 1278 | struct cxl_region *cxlr, |
| 1215 | 1279 | struct cxl_endpoint_decoder *cxled) |
| @@ -1360,6 +1424,15 @@ static int cxl_port_setup_targets(struct cxl_port *port, · 144 unmodified lines | ||
| 1360 | 1424 | return -ENXIO; |
| 1361 | 1425 | } |
| 1362 | 1426 | } else { |
| 1427 | + rc = check_interleave_cap(cxld, iw, ig); | |
| 1428 | + if (rc) { | |
| 1429 | + dev_dbg(&cxlr->dev, | |
| 1430 | + "%s:%s iw: %d ig: %d is not supported\n", | |
| 1431 | + dev_name(port->uport_dev), | |
| 1432 | + dev_name(&port->dev), iw, ig); | |
| 1433 | + return rc; | |
| 1434 | + } | |
| 1435 | + | |
| 1363 | 1436 | cxld->interleave_ways = iw; |
| 1364 | 1437 | cxld->interleave_granularity = ig; |
| 1365 | 1438 | cxld->hpa_range = (struct range) { |
| @@ -1796,6 +1869,15 @@ static int cxl_region_attach(struct cxl_region *cxlr, · 430 unmodified lines | ||
| 1796 | 1869 | struct cxl_dport *dport; |
| 1797 | 1870 | int rc = -ENXIO; |
| 1798 | 1871 | |
| 1872 | + rc = check_interleave_cap(&cxled->cxld, p->interleave_ways, | |
| 1873 | + p->interleave_granularity); | |
| 1874 | + if (rc) { | |
| 1875 | + dev_dbg(&cxlr->dev, "%s iw: %d ig: %d is not supported\n", | |
| 1876 | + dev_name(&cxled->cxld.dev), p->interleave_ways, | |
| 1877 | + p->interleave_granularity); | |
| 1878 | + return rc; | |
| 1879 | + } | |
| 1880 | + | |
| 1799 | 1881 | if (cxled->mode != cxlr->mode) { |
| 1800 | 1882 | dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n", |
| 1801 | 1883 | dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode); |
| @@ -2688,22 +2770,33 @@ static int __cxl_dpa_to_region(struct device *dev, void *arg) · 886 unmodified lines | ||
| 2688 | 2770 | { |
| 2689 | 2771 | struct cxl_dpa_to_region_context *ctx = arg; |
| 2690 | 2772 | struct cxl_endpoint_decoder *cxled; |
| 2773 | + struct cxl_region *cxlr; | |
| 2691 | 2774 | u64 dpa = ctx->dpa; |
| 2692 | 2775 | |
| 2693 | 2776 | if (!is_endpoint_decoder(dev)) |
| 2694 | 2777 | return 0; |
| 2695 | 2778 | |
| 2696 | 2779 | cxled = to_cxl_endpoint_decoder(dev); |
| 2697 | − if (!cxled->dpa_res || !resource_size(cxled->dpa_res)) | |
| 2780 | + if (!cxled || !cxled->dpa_res || !resource_size(cxled->dpa_res)) | |
| 2698 | 2781 | return 0; |
| 2699 | 2782 | |
| 2700 | 2783 | if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start) |
| 2701 | 2784 | return 0; |
| 2702 | 2785 | |
| 2703 | − dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa, | |
| 2704 | − dev_name(&cxled->cxld.region->dev)); | |
| 2786 | + /* | |
| 2787 | + * Stop the region search (return 1) when an endpoint mapping is | |
| 2788 | + * found. The region may not be fully constructed so offering | |
| 2789 | + * the cxlr in the context structure is not guaranteed. | |
| 2790 | + */ | |
| 2791 | + cxlr = cxled->cxld.region; | |
| 2792 | + if (cxlr) | |
| 2793 | + dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa, | |
| 2794 | + dev_name(&cxlr->dev)); | |
| 2795 | + else | |
| 2796 | + dev_dbg(dev, "dpa:0x%llx mapped in endpoint:%s\n", dpa, | |
| 2797 | + dev_name(dev)); | |
| 2705 | 2798 | |
| 2706 | − ctx->cxlr = cxled->cxld.region; | |
| 2799 | + ctx->cxlr = cxlr; | |
| 2707 | 2800 | |
| 2708 | 2801 | return 1; |
| 2709 | 2802 | } |
| @@ -2847,7 +2940,7 @@ static int cxl_pmem_region_alloc(struct cxl_region *cxlr) · 137 unmodified lines | ||
| 2847 | 2940 | * bridge for one device is the same for all. |
| 2848 | 2941 | */ |
| 2849 | 2942 | if (i == 0) { |
| 2850 | − cxl_nvb = cxl_find_nvdimm_bridge(cxlmd); | |
| 2943 | + cxl_nvb = cxl_find_nvdimm_bridge(cxlmd->endpoint); | |
| 2851 | 2944 | if (!cxl_nvb) |
| 2852 | 2945 | return -ENODEV; |
| 2853 | 2946 | cxlr->cxl_nvb = cxl_nvb; |
| @@ -47,6 +47,8 @@ extern const struct nvdimm_security_ops *cxl_security_ops; · 46 unmodified lines | ||
| 47 | 47 | #define CXL_HDM_DECODER_TARGET_COUNT_MASK GENMASK(7, 4) |
| 48 | 48 | #define CXL_HDM_DECODER_INTERLEAVE_11_8 BIT(8) |
| 49 | 49 | #define CXL_HDM_DECODER_INTERLEAVE_14_12 BIT(9) |
| 50 | +#define CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY BIT(11) | |
| 51 | +#define CXL_HDM_DECODER_INTERLEAVE_16_WAY BIT(12) | |
| 50 | 52 | #define CXL_HDM_DECODER_CTRL_OFFSET 0x4 |
| 51 | 53 | #define CXL_HDM_DECODER_ENABLE BIT(1) |
| 52 | 54 | #define CXL_HDM_DECODER0_BASE_LOW_OFFSET(i) (0x20 * (i) + 0x10) |
| @@ -855,8 +857,8 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, · 802 unmodified lines | ||
| 855 | 857 | struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev); |
| 856 | 858 | bool is_cxl_nvdimm(struct device *dev); |
| 857 | 859 | bool is_cxl_nvdimm_bridge(struct device *dev); |
| 858 | −int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd); | |
| 859 | −struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd); | |
| 860 | +int devm_cxl_add_nvdimm(struct cxl_port *parent_port, struct cxl_memdev *cxlmd); | |
| 861 | +struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port); | |
| 860 | 862 | |
| 861 | 863 | #ifdef CONFIG_CXL_REGION |
| 862 | 864 | bool is_cxl_pmem_region(struct device *dev); |
| @@ -395,9 +395,9 @@ enum cxl_devtype { · 394 unmodified lines | ||
| 395 | 395 | |
| 396 | 396 | /** |
| 397 | 397 | * struct cxl_dpa_perf - DPA performance property entry |
| 398 | − * @dpa_range - range for DPA address | |
| 399 | − * @coord - QoS performance data (i.e. latency, bandwidth) | |
| 400 | − * @qos_class - QoS Class cookies | |
| 398 | + * @dpa_range: range for DPA address | |
| 399 | + * @coord: QoS performance data (i.e. latency, bandwidth) | |
| 400 | + * @qos_class: QoS Class cookies | |
| 401 | 401 | */ |
| 402 | 402 | struct cxl_dpa_perf { |
| 403 | 403 | struct range dpa_range; |
| @@ -464,13 +464,14 @@ struct cxl_dev_state { · 60 unmodified lines | ||
| 464 | 464 | * @active_persistent_bytes: sum of hard + soft persistent |
| 465 | 465 | * @next_volatile_bytes: volatile capacity change pending device reset |
| 466 | 466 | * @next_persistent_bytes: persistent capacity change pending device reset |
| 467 | + * @ram_perf: performance data entry matched to RAM partition | |
| 468 | + * @pmem_perf: performance data entry matched to PMEM partition | |
| 467 | 469 | * @event: event log driver state |
| 468 | 470 | * @poison: poison driver state info |
| 469 | 471 | * @security: security driver state info |
| 470 | 472 | * @fw: firmware upload / activation state |
| 473 | + * @mbox_wait: RCU wait for mbox send completely | |
| 471 | 474 | * @mbox_send: @dev specific transport for transmitting mailbox commands |
| 472 | − * @ram_perf: performance data entry matched to RAM partition | |
| 473 | − * @pmem_perf: performance data entry matched to PMEM partition | |
| 474 | 475 | * |
| 475 | 476 | * See CXL 3.0 8.2.9.8.2 Capacity Configuration and Label Storage for |
| 476 | 477 | * details on capacity parameters. |
| @@ -851,11 +852,21 @@ static inline void cxl_mem_active_dec(void) · 374 unmodified lines | ||
| 851 | 852 | |
| 852 | 853 | int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd); |
| 853 | 854 | |
| 855 | +/** | |
| 856 | + * struct cxl_hdm - HDM Decoder registers and cached / decoded capabilities | |
| 857 | + * @regs: mapped registers, see devm_cxl_setup_hdm() | |
| 858 | + * @decoder_count: number of decoders for this port | |
| 859 | + * @target_count: for switch decoders, max downstream port targets | |
| 860 | + * @interleave_mask: interleave granularity capability, see check_interleave_cap() | |
| 861 | + * @iw_cap_mask: bitmask of supported interleave ways, see check_interleave_cap() | |
| 862 | + * @port: mapped cxl_port, see devm_cxl_setup_hdm() | |
| 863 | + */ | |
| 854 | 864 | struct cxl_hdm { |
| 855 | 865 | struct cxl_component_regs regs; |
| 856 | 866 | unsigned int decoder_count; |
| 857 | 867 | unsigned int target_count; |
| 858 | 868 | unsigned int interleave_mask; |
| 869 | + unsigned long iw_cap_mask; | |
| 859 | 870 | struct cxl_port *port; |
| 860 | 871 | }; |
| 861 | 872 | |
| @@ -152,6 +152,15 @@ static int cxl_mem_probe(struct device *dev) · 151 unmodified lines | ||
| 152 | 152 | return -ENXIO; |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | + if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) { | |
| 156 | + rc = devm_cxl_add_nvdimm(parent_port, cxlmd); | |
| 157 | + if (rc) { | |
| 158 | + if (rc == -ENODEV) | |
| 159 | + dev_info(dev, "PMEM disabled by platform\n"); | |
| 160 | + return rc; | |
| 161 | + } | |
| 162 | + } | |
| 163 | + | |
| 155 | 164 | if (dport->rch) |
| 156 | 165 | endpoint_parent = parent_port->uport_dev; |
| 157 | 166 | else |
| @@ -174,14 +183,6 @@ unlock: · 16 unmodified lines | ||
| 174 | 183 | if (rc) |
| 175 | 184 | return rc; |
| 176 | 185 | |
| 177 | − if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) { | |
| 178 | − rc = devm_cxl_add_nvdimm(cxlmd); | |
| 179 | − if (rc == -ENODEV) | |
| 180 | − dev_info(dev, "PMEM disabled by platform\n"); | |
| 181 | − else | |
| 182 | − return rc; | |
| 183 | − } | |
| 184 | − | |
| 185 | 186 | /* |
| 186 | 187 | * The kernel may be operating out of CXL memory on this device, |
| 187 | 188 | * there is no spec defined way to determine whether this device |
| @@ -225,6 +225,11 @@ static int davinci_gpio_probe(struct platform_device *pdev) · 224 unmodified lines | ||
| 225 | 225 | else |
| 226 | 226 | nirq = DIV_ROUND_UP(ngpio, 16); |
| 227 | 227 | |
| 228 | + if (nirq > MAX_INT_PER_BANK) { | |
| 229 | + dev_err(dev, "Too many IRQs!\n"); | |
| 230 | + return -EINVAL; | |
| 231 | + } | |
| 232 | + | |
| 228 | 233 | chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL); |
| 229 | 234 | if (!chips) |
| 230 | 235 | return -ENOMEM; |
| @@ -296,6 +296,8 @@ static int gnr_gpio_probe(struct platform_device *pdev) · 295 unmodified lines | ||
| 296 | 296 | if (!priv) |
| 297 | 297 | return -ENOMEM; |
| 298 | 298 | |
| 299 | + raw_spin_lock_init(&priv->lock); | |
| 300 | + | |
| 299 | 301 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 300 | 302 | if (IS_ERR(regs)) |
| 301 | 303 | return PTR_ERR(regs); |
| @@ -758,6 +758,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) · 757 unmodified lines | ||
| 758 | 758 | int level; |
| 759 | 759 | |
| 760 | 760 | if (chip->driver_data & PCA_PCAL) { |
| 761 | + guard(mutex)(&chip->i2c_lock); | |
| 762 | + | |
| 761 | 763 | /* Enable latch on interrupt-enabled inputs */ |
| 762 | 764 | pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask); |
| 763 | 765 | |
| @@ -89,6 +89,10 @@ struct linehandle_state { · 88 unmodified lines | ||
| 89 | 89 | GPIOHANDLE_REQUEST_OPEN_DRAIN | \ |
| 90 | 90 | GPIOHANDLE_REQUEST_OPEN_SOURCE) |
| 91 | 91 | |
| 92 | +#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS \ | |
| 93 | + (GPIOHANDLE_REQUEST_INPUT | \ | |
| 94 | + GPIOHANDLE_REQUEST_OUTPUT) | |
| 95 | + | |
| 92 | 96 | static int linehandle_validate_flags(u32 flags) |
| 93 | 97 | { |
| 94 | 98 | /* Return an error if an unknown flag is set */ |
| @@ -169,21 +173,21 @@ static long linehandle_set_config(struct linehandle_state *lh, · 74 unmodified lines | ||
| 169 | 173 | if (ret) |
| 170 | 174 | return ret; |
| 171 | 175 | |
| 176 | + /* Lines must be reconfigured explicitly as input or output. */ | |
| 177 | + if (!(lflags & GPIOHANDLE_REQUEST_DIRECTION_FLAGS)) | |
| 178 | + return -EINVAL; | |
| 179 | + | |
| 172 | 180 | for (i = 0; i < lh->num_descs; i++) { |
| 173 | 181 | desc = lh->descs[i]; |
| 174 | − linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags); | |
| 182 | + linehandle_flags_to_desc_flags(lflags, &desc->flags); | |
| 175 | 183 | |
| 176 | − /* | |
| 177 | − * Lines have to be requested explicitly for input | |
| 178 | − * or output, else the line will be treated "as is". | |
| 179 | − */ | |
| 180 | 184 | if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { |
| 181 | 185 | int val = !!gcnf.default_values[i]; |
| 182 | 186 | |
| 183 | 187 | ret = gpiod_direction_output(desc, val); |
| 184 | 188 | if (ret) |
| 185 | 189 | return ret; |
| 186 | − } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { | |
| 190 | + } else { | |
| 187 | 191 | ret = gpiod_direction_input(desc); |
| 188 | 192 | if (ret) |
| 189 | 193 | return ret; |
| @@ -1530,12 +1534,14 @@ static long linereq_set_config(struct linereq *lr, void __user *ip) · 1340 unmodified lines | ||
| 1530 | 1534 | line = &lr->lines[i]; |
| 1531 | 1535 | desc = lr->lines[i].desc; |
| 1532 | 1536 | flags = gpio_v2_line_config_flags(&lc, i); |
| 1533 | − gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); | |
| 1534 | − edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS; | |
| 1535 | 1537 | /* |
| 1536 | − * Lines have to be requested explicitly for input | |
| 1537 | − * or output, else the line will be treated "as is". | |
| 1538 | + * Lines not explicitly reconfigured as input or output | |
| 1539 | + * are left unchanged. | |
| 1538 | 1540 | */ |
| 1541 | + if (!(flags & GPIO_V2_LINE_DIRECTION_FLAGS)) | |
| 1542 | + continue; | |
| 1543 | + gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); | |
| 1544 | + edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS; | |
| 1539 | 1545 | if (flags & GPIO_V2_LINE_FLAG_OUTPUT) { |
| 1540 | 1546 | int val = gpio_v2_line_config_output_value(&lc, i); |
| 1541 | 1547 | |
| @@ -1543,7 +1549,7 @@ static long linereq_set_config(struct linereq *lr, void __user *ip) · 1 unmodified line | ||
| 1543 | 1549 | ret = gpiod_direction_output(desc, val); |
| 1544 | 1550 | if (ret) |
| 1545 | 1551 | return ret; |
| 1546 | − } else if (flags & GPIO_V2_LINE_FLAG_INPUT) { | |
| 1552 | + } else { | |
| 1547 | 1553 | ret = gpiod_direction_input(desc); |
| 1548 | 1554 | if (ret) |
| 1549 | 1555 | return ret; |
| @@ -400,7 +400,7 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, · 399 unmodified lines | ||
| 400 | 400 | mem_channel_number = vram_info->v30.channel_num; |
| 401 | 401 | mem_channel_width = vram_info->v30.channel_width; |
| 402 | 402 | if (vram_width) |
| 403 | − *vram_width = mem_channel_number * (1 << mem_channel_width); | |
| 403 | + *vram_width = mem_channel_number * 16; | |
| 404 | 404 | break; |
| 405 | 405 | default: |
| 406 | 406 | return -EINVAL; |
| @@ -5220,11 +5220,14 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev) · 5219 unmodified lines | ||
| 5220 | 5220 | |
| 5221 | 5221 | dev_info(adev->dev, "GPU mode1 reset\n"); |
| 5222 | 5222 | |
| 5223 | + /* Cache the state before bus master disable. The saved config space | |
| 5224 | + * values are used in other cases like restore after mode-2 reset. | |
| 5225 | + */ | |
| 5226 | + amdgpu_device_cache_pci_state(adev->pdev); | |
| 5227 | + | |
| 5223 | 5228 | /* disable BM */ |
| 5224 | 5229 | pci_clear_master(adev->pdev); |
| 5225 | 5230 | |
| 5226 | − amdgpu_device_cache_pci_state(adev->pdev); | |
| 5227 | − | |
| 5228 | 5231 | if (amdgpu_dpm_is_mode1_reset_supported(adev)) { |
| 5229 | 5232 | dev_info(adev->dev, "GPU smu mode1 reset\n"); |
| 5230 | 5233 | ret = amdgpu_dpm_mode1_reset(adev); |
| @@ -640,6 +640,20 @@ static const char *psp_gfx_cmd_name(enum psp_gfx_cmd_id cmd_id) · 639 unmodified lines | ||
| 640 | 640 | } |
| 641 | 641 | } |
| 642 | 642 | |
| 643 | +static bool psp_err_warn(struct psp_context *psp) | |
| 644 | +{ | |
| 645 | + struct psp_gfx_cmd_resp *cmd = psp->cmd_buf_mem; | |
| 646 | + | |
| 647 | + /* This response indicates reg list is already loaded */ | |
| 648 | + if (amdgpu_ip_version(psp->adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 2) && | |
| 649 | + cmd->cmd_id == GFX_CMD_ID_LOAD_IP_FW && | |
| 650 | + cmd->cmd.cmd_load_ip_fw.fw_type == GFX_FW_TYPE_REG_LIST && | |
| 651 | + cmd->resp.status == TEE_ERROR_CANCEL) | |
| 652 | + return false; | |
| 653 | + | |
| 654 | + return true; | |
| 655 | +} | |
| 656 | + | |
| 643 | 657 | static int |
| 644 | 658 | psp_cmd_submit_buf(struct psp_context *psp, |
| 645 | 659 | struct amdgpu_firmware_info *ucode, |
| @@ -699,10 +713,13 @@ psp_cmd_submit_buf(struct psp_context *psp, · 53 unmodified lines | ||
| 699 | 713 | dev_warn(psp->adev->dev, |
| 700 | 714 | "failed to load ucode %s(0x%X) ", |
| 701 | 715 | amdgpu_ucode_name(ucode->ucode_id), ucode->ucode_id); |
| 702 | − dev_warn(psp->adev->dev, | |
| 703 | − "psp gfx command %s(0x%X) failed and response status is (0x%X)\n", | |
| 704 | − psp_gfx_cmd_name(psp->cmd_buf_mem->cmd_id), psp->cmd_buf_mem->cmd_id, | |
| 705 | − psp->cmd_buf_mem->resp.status); | |
| 716 | + if (psp_err_warn(psp)) | |
| 717 | + dev_warn( | |
| 718 | + psp->adev->dev, | |
| 719 | + "psp gfx command %s(0x%X) failed and response status is (0x%X)\n", | |
| 720 | + psp_gfx_cmd_name(psp->cmd_buf_mem->cmd_id), | |
| 721 | + psp->cmd_buf_mem->cmd_id, | |
| 722 | + psp->cmd_buf_mem->resp.status); | |
| 706 | 723 | /* If any firmware (including CAP) load fails under SRIOV, it should |
| 707 | 724 | * return failure to stop the VF from initializing. |
| 708 | 725 | * Also return failure in case of timeout |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <drm/drm_atomic_helper.h> |
| 4 | 4 | #include <drm/drm_edid.h> |
| 5 | 5 | #include <drm/drm_simple_kms_helper.h> |
| 6 | +#include <drm/drm_gem_framebuffer_helper.h> | |
| 6 | 7 | #include <drm/drm_vblank.h> |
| 7 | 8 | |
| 8 | 9 | #include "amdgpu.h" |
| @@ -314,7 +315,13 @@ static int amdgpu_vkms_prepare_fb(struct drm_plane *plane, · 305 unmodified lines | ||
| 314 | 315 | return 0; |
| 315 | 316 | } |
| 316 | 317 | afb = to_amdgpu_framebuffer(new_state->fb); |
| 317 | − obj = new_state->fb->obj[0]; | |
| 318 | + | |
| 319 | + obj = drm_gem_fb_get_obj(new_state->fb, 0); | |
| 320 | + if (!obj) { | |
| 321 | + DRM_ERROR("Failed to get obj from framebuffer\n"); | |
| 322 | + return -EINVAL; | |
| 323 | + } | |
| 324 | + | |
| 318 | 325 | rbo = gem_to_amdgpu_bo(obj); |
| 319 | 326 | adev = amdgpu_ttm_adev(rbo->tbo.bdev); |
| 320 | 327 | |
| @@ -368,12 +375,19 @@ static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane, · 47 unmodified lines | ||
| 368 | 375 | struct drm_plane_state *old_state) |
| 369 | 376 | { |
| 370 | 377 | struct amdgpu_bo *rbo; |
| 378 | + struct drm_gem_object *obj; | |
| 371 | 379 | int r; |
| 372 | 380 | |
| 373 | 381 | if (!old_state->fb) |
| 374 | 382 | return; |
| 375 | 383 | |
| 376 | − rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]); | |
| 384 | + obj = drm_gem_fb_get_obj(old_state->fb, 0); | |
| 385 | + if (!obj) { | |
| 386 | + DRM_ERROR("Failed to get obj from framebuffer\n"); | |
| 387 | + return; | |
| 388 | + } | |
| 389 | + | |
| 390 | + rbo = gem_to_amdgpu_bo(obj); | |
| 377 | 391 | r = amdgpu_bo_reserve(rbo, false); |
| 378 | 392 | if (unlikely(r)) { |
| 379 | 393 | DRM_ERROR("failed to reserve rbo before unpin\n"); |
| @@ -464,8 +464,9 @@ struct psp_gfx_rb_frame · 463 unmodified lines | ||
| 464 | 464 | #define PSP_ERR_UNKNOWN_COMMAND 0x00000100 |
| 465 | 465 | |
| 466 | 466 | enum tee_error_code { |
| 467 | − TEE_SUCCESS = 0x00000000, | |
| 468 | − TEE_ERROR_NOT_SUPPORTED = 0xFFFF000A, | |
| 467 | + TEE_SUCCESS = 0x00000000, | |
| 468 | + TEE_ERROR_CANCEL = 0xFFFF0002, | |
| 469 | + TEE_ERROR_NOT_SUPPORTED = 0xFFFF000A, | |
| 469 | 470 | }; |
| 470 | 471 | |
| 471 | 472 | #endif /* _PSP_TEE_GFX_IF_H_ */ |
| @@ -1590,9 +1590,17 @@ static bool retrieve_link_cap(struct dc_link *link) · 1589 unmodified lines | ||
| 1590 | 1590 | return false; |
| 1591 | 1591 | } |
| 1592 | 1592 | |
| 1593 | − if (dp_is_lttpr_present(link)) | |
| 1593 | + if (dp_is_lttpr_present(link)) { | |
| 1594 | 1594 | configure_lttpr_mode_transparent(link); |
| 1595 | 1595 | |
| 1596 | + // Echo TOTAL_LTTPR_CNT back downstream | |
| 1597 | + core_link_write_dpcd( | |
| 1598 | + link, | |
| 1599 | + DP_TOTAL_LTTPR_CNT, | |
| 1600 | + &link->dpcd_caps.lttpr_caps.phy_repeater_cnt, | |
| 1601 | + sizeof(link->dpcd_caps.lttpr_caps.phy_repeater_cnt)); | |
| 1602 | + } | |
| 1603 | + | |
| 1596 | 1604 | /* Read DP tunneling information. */ |
| 1597 | 1605 | status = dpcd_get_tunneling_device_data(link); |
| 1598 | 1606 | |
| @@ -177,4 +177,9 @@ enum dpcd_psr_sink_states { · 176 unmodified lines | ||
| 177 | 177 | #define DP_SINK_PR_PIXEL_DEVIATION_PER_LINE 0x379 |
| 178 | 178 | #define DP_SINK_PR_MAX_NUMBER_OF_DEVIATION_LINE 0x37A |
| 179 | 179 | |
| 180 | +/* Remove once drm_dp_helper.h is updated upstream */ | |
| 181 | +#ifndef DP_TOTAL_LTTPR_CNT | |
| 182 | +#define DP_TOTAL_LTTPR_CNT 0xF000A /* 2.1 */ | |
| 183 | +#endif | |
| 184 | + | |
| 180 | 185 | #endif /* __DAL_DPCD_DEFS_H__ */ |
| @@ -324,6 +324,18 @@ static int smu_dpm_set_umsch_mm_enable(struct smu_context *smu, · 323 unmodified lines | ||
| 324 | 324 | return ret; |
| 325 | 325 | } |
| 326 | 326 | |
| 327 | +static int smu_set_mall_enable(struct smu_context *smu) | |
| 328 | +{ | |
| 329 | + int ret = 0; | |
| 330 | + | |
| 331 | + if (!smu->ppt_funcs->set_mall_enable) | |
| 332 | + return 0; | |
| 333 | + | |
| 334 | + ret = smu->ppt_funcs->set_mall_enable(smu); | |
| 335 | + | |
| 336 | + return ret; | |
| 337 | +} | |
| 338 | + | |
| 327 | 339 | /** |
| 328 | 340 | * smu_dpm_set_power_gate - power gate/ungate the specific IP block |
| 329 | 341 | * |
| @@ -1791,6 +1803,7 @@ static int smu_hw_init(void *handle) · 1461 unmodified lines | ||
| 1791 | 1803 | smu_dpm_set_jpeg_enable(smu, true); |
| 1792 | 1804 | smu_dpm_set_vpe_enable(smu, true); |
| 1793 | 1805 | smu_dpm_set_umsch_mm_enable(smu, true); |
| 1806 | + smu_set_mall_enable(smu); | |
| 1794 | 1807 | smu_set_gfx_cgpg(smu, true); |
| 1795 | 1808 | } |
| 1796 | 1809 | |
| @@ -1394,6 +1394,11 @@ struct pptable_funcs { · 1393 unmodified lines | ||
| 1394 | 1394 | */ |
| 1395 | 1395 | int (*dpm_set_umsch_mm_enable)(struct smu_context *smu, bool enable); |
| 1396 | 1396 | |
| 1397 | + /** | |
| 1398 | + * @set_mall_enable: Init MALL power gating control. | |
| 1399 | + */ | |
| 1400 | + int (*set_mall_enable)(struct smu_context *smu); | |
| 1401 | + | |
| 1397 | 1402 | /** |
| 1398 | 1403 | * @notify_rlc_state: Notify RLC power state to SMU. |
| 1399 | 1404 | */ |
| @@ -106,8 +106,8 @@ · 105 unmodified lines | ||
| 106 | 106 | #define PPSMC_MSG_DisableLSdma 0x35 ///< Disable LSDMA |
| 107 | 107 | #define PPSMC_MSG_SetSoftMaxVpe 0x36 ///< |
| 108 | 108 | #define PPSMC_MSG_SetSoftMinVpe 0x37 ///< |
| 109 | −#define PPSMC_MSG_AllocMALLCache 0x38 ///< Allocating MALL Cache | |
| 110 | −#define PPSMC_MSG_ReleaseMALLCache 0x39 ///< Releasing MALL Cache | |
| 109 | +#define PPSMC_MSG_MALLPowerController 0x38 ///< Set MALL control | |
| 110 | +#define PPSMC_MSG_MALLPowerState 0x39 ///< Enter/Exit MALL PG | |
| 111 | 111 | #define PPSMC_Message_Count 0x3A ///< Total number of PPSMC messages |
| 112 | 112 | /** @}*/ |
| 113 | 113 | |
| @@ -272,7 +272,9 @@ · 271 unmodified lines | ||
| 272 | 272 | __SMU_DUMMY_MAP(SetSoftMinVpe), \ |
| 273 | 273 | __SMU_DUMMY_MAP(GetMetricsVersion), \ |
| 274 | 274 | __SMU_DUMMY_MAP(EnableUCLKShadow), \ |
| 275 | − __SMU_DUMMY_MAP(RmaDueToBadPageThreshold), | |
| 275 | + __SMU_DUMMY_MAP(RmaDueToBadPageThreshold), \ | |
| 276 | + __SMU_DUMMY_MAP(MALLPowerController), \ | |
| 277 | + __SMU_DUMMY_MAP(MALLPowerState), | |
| 276 | 278 | |
| 277 | 279 | #undef __SMU_DUMMY_MAP |
| 278 | 280 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type |
| @@ -52,6 +52,19 @@ · 51 unmodified lines | ||
| 52 | 52 | #define mmMP1_SMN_C2PMSG_90 0x029a |
| 53 | 53 | #define mmMP1_SMN_C2PMSG_90_BASE_IDX 0 |
| 54 | 54 | |
| 55 | +/* MALLPowerController message arguments (Defines for the Cache mode control) */ | |
| 56 | +#define SMU_MALL_PMFW_CONTROL 0 | |
| 57 | +#define SMU_MALL_DRIVER_CONTROL 1 | |
| 58 | + | |
| 59 | +/* | |
| 60 | + * MALLPowerState message arguments | |
| 61 | + * (Defines for the Allocate/Release Cache mode if in driver mode) | |
| 62 | + */ | |
| 63 | +#define SMU_MALL_EXIT_PG 0 | |
| 64 | +#define SMU_MALL_ENTER_PG 1 | |
| 65 | + | |
| 66 | +#define SMU_MALL_PG_CONFIG_DEFAULT SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON | |
| 67 | + | |
| 55 | 68 | #define FEATURE_MASK(feature) (1ULL << feature) |
| 56 | 69 | #define SMC_DPM_FEATURE ( \ |
| 57 | 70 | FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ |
| @@ -66,6 +79,12 @@ · 8 unmodified lines | ||
| 66 | 79 | FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ |
| 67 | 80 | FEATURE_MASK(FEATURE_VPE_DPM_BIT)) |
| 68 | 81 | |
| 82 | +enum smu_mall_pg_config { | |
| 83 | + SMU_MALL_PG_CONFIG_PMFW_CONTROL = 0, | |
| 84 | + SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON = 1, | |
| 85 | + SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_OFF = 2, | |
| 86 | +}; | |
| 87 | + | |
| 69 | 88 | static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = { |
| 70 | 89 | MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), |
| 71 | 90 | MSG_MAP(GetSmuVersion, PPSMC_MSG_GetPmfwVersion, 1), |
| @@ -113,6 +132,8 @@ static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = · 41 unmodified lines | ||
| 113 | 132 | MSG_MAP(PowerDownUmsch, PPSMC_MSG_PowerDownUmsch, 1), |
| 114 | 133 | MSG_MAP(SetSoftMaxVpe, PPSMC_MSG_SetSoftMaxVpe, 1), |
| 115 | 134 | MSG_MAP(SetSoftMinVpe, PPSMC_MSG_SetSoftMinVpe, 1), |
| 135 | + MSG_MAP(MALLPowerController, PPSMC_MSG_MALLPowerController, 1), | |
| 136 | + MSG_MAP(MALLPowerState, PPSMC_MSG_MALLPowerState, 1), | |
| 116 | 137 | }; |
| 117 | 138 | |
| 118 | 139 | static struct cmn2asic_mapping smu_v14_0_0_feature_mask_map[SMU_FEATURE_COUNT] = { |
| @@ -1423,6 +1444,57 @@ static int smu_v14_0_common_get_dpm_table(struct smu_context *smu, struct dpm_cl · 1304 unmodified lines | ||
| 1423 | 1444 | return 0; |
| 1424 | 1445 | } |
| 1425 | 1446 | |
| 1447 | +static int smu_v14_0_1_init_mall_power_gating(struct smu_context *smu, enum smu_mall_pg_config pg_config) | |
| 1448 | +{ | |
| 1449 | + struct amdgpu_device *adev = smu->adev; | |
| 1450 | + int ret = 0; | |
| 1451 | + | |
| 1452 | + if (pg_config == SMU_MALL_PG_CONFIG_PMFW_CONTROL) { | |
| 1453 | + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerController, | |
| 1454 | + SMU_MALL_PMFW_CONTROL, NULL); | |
| 1455 | + if (ret) { | |
| 1456 | + dev_err(adev->dev, "Init MALL PMFW CONTROL Failure\n"); | |
| 1457 | + return ret; | |
| 1458 | + } | |
| 1459 | + } else { | |
| 1460 | + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerController, | |
| 1461 | + SMU_MALL_DRIVER_CONTROL, NULL); | |
| 1462 | + if (ret) { | |
| 1463 | + dev_err(adev->dev, "Init MALL Driver CONTROL Failure\n"); | |
| 1464 | + return ret; | |
| 1465 | + } | |
| 1466 | + | |
| 1467 | + if (pg_config == SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON) { | |
| 1468 | + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerState, | |
| 1469 | + SMU_MALL_EXIT_PG, NULL); | |
| 1470 | + if (ret) { | |
| 1471 | + dev_err(adev->dev, "EXIT MALL PG Failure\n"); | |
| 1472 | + return ret; | |
| 1473 | + } | |
| 1474 | + } else if (pg_config == SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_OFF) { | |
| 1475 | + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerState, | |
| 1476 | + SMU_MALL_ENTER_PG, NULL); | |
| 1477 | + if (ret) { | |
| 1478 | + dev_err(adev->dev, "Enter MALL PG Failure\n"); | |
| 1479 | + return ret; | |
| 1480 | + } | |
| 1481 | + } | |
| 1482 | + } | |
| 1483 | + | |
| 1484 | + return ret; | |
| 1485 | +} | |
| 1486 | + | |
| 1487 | +static int smu_v14_0_common_set_mall_enable(struct smu_context *smu) | |
| 1488 | +{ | |
| 1489 | + enum smu_mall_pg_config pg_config = SMU_MALL_PG_CONFIG_DEFAULT; | |
| 1490 | + int ret = 0; | |
| 1491 | + | |
| 1492 | + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) | |
| 1493 | + ret = smu_v14_0_1_init_mall_power_gating(smu, pg_config); | |
| 1494 | + | |
| 1495 | + return ret; | |
| 1496 | +} | |
| 1497 | + | |
| 1426 | 1498 | static const struct pptable_funcs smu_v14_0_0_ppt_funcs = { |
| 1427 | 1499 | .check_fw_status = smu_v14_0_check_fw_status, |
| 1428 | 1500 | .check_fw_version = smu_v14_0_check_fw_version, |
| @@ -1454,6 +1526,7 @@ static const struct pptable_funcs smu_v14_0_0_ppt_funcs = { · 25 unmodified lines | ||
| 1454 | 1526 | .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable, |
| 1455 | 1527 | .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable, |
| 1456 | 1528 | .get_dpm_clock_table = smu_v14_0_common_get_dpm_table, |
| 1529 | + .set_mall_enable = smu_v14_0_common_set_mall_enable, | |
| 1457 | 1530 | }; |
| 1458 | 1531 | |
| 1459 | 1532 | static void smu_v14_0_0_set_smu_mailbox_registers(struct smu_context *smu) |
| @@ -524,6 +524,9 @@ struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) · 523 unmodified lines | ||
| 524 | 524 | if (!info) |
| 525 | 525 | return ERR_PTR(-ENOMEM); |
| 526 | 526 | |
| 527 | + if (!drm_leak_fbdev_smem) | |
| 528 | + info->flags |= FBINFO_HIDE_SMEM_START; | |
| 529 | + | |
| 527 | 530 | ret = fb_alloc_cmap(&info->cmap, 256, 0); |
| 528 | 531 | if (ret) |
| 529 | 532 | goto err_release; |
| @@ -1860,9 +1863,6 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper) · 1330 unmodified lines | ||
| 1860 | 1863 | info = fb_helper->info; |
| 1861 | 1864 | info->var.pixclock = 0; |
| 1862 | 1865 | |
| 1863 | − if (!drm_leak_fbdev_smem) | |
| 1864 | − info->flags |= FBINFO_HIDE_SMEM_START; | |
| 1865 | − | |
| 1866 | 1866 | /* Need to drop locks to avoid recursive deadlock in |
| 1867 | 1867 | * register_framebuffer. This is ok because the only thing left to do is |
| 1868 | 1868 | * register the fbdev emulation instance in kernel_fb_helper_list. */ |
| @@ -130,7 +130,10 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, · 129 unmodified lines | ||
| 130 | 130 | info->flags |= FBINFO_READS_FAST; /* signal caching */ |
| 131 | 131 | info->screen_size = sizes->surface_height * fb->pitches[0]; |
| 132 | 132 | info->screen_buffer = map.vaddr; |
| 133 | − info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); | |
| 133 | + if (!(info->flags & FBINFO_HIDE_SMEM_START)) { | |
| 134 | + if (!drm_WARN_ON(dev, is_vmalloc_addr(info->screen_buffer))) | |
| 135 | + info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); | |
| 136 | + } | |
| 134 | 137 | info->fix.smem_len = info->screen_size; |
| 135 | 138 | |
| 136 | 139 | return 0; |
| @@ -469,14 +469,12 @@ void drm_file_update_pid(struct drm_file *filp) · 468 unmodified lines | ||
| 469 | 469 | |
| 470 | 470 | dev = filp->minor->dev; |
| 471 | 471 | mutex_lock(&dev->filelist_mutex); |
| 472 | + get_pid(pid); | |
| 472 | 473 | old = rcu_replace_pointer(filp->pid, pid, 1); |
| 473 | 474 | mutex_unlock(&dev->filelist_mutex); |
| 474 | 475 | |
| 475 | − if (pid != old) { | |
| 476 | − get_pid(pid); | |
| 477 | − synchronize_rcu(); | |
| 478 | − put_pid(old); | |
| 479 | − } | |
| 476 | + synchronize_rcu(); | |
| 477 | + put_pid(old); | |
| 480 | 478 | } |
| 481 | 479 | |
| 482 | 480 | /** |
| @@ -298,6 +298,7 @@ void i915_vma_revoke_fence(struct i915_vma *vma) · 297 unmodified lines | ||
| 298 | 298 | return; |
| 299 | 299 | |
| 300 | 300 | GEM_BUG_ON(fence->vma != vma); |
| 301 | + i915_active_wait(&fence->active); | |
| 301 | 302 | GEM_BUG_ON(!i915_active_is_idle(&fence->active)); |
| 302 | 303 | GEM_BUG_ON(atomic_read(&fence->pin_count)); |
| 303 | 304 | |
| @@ -209,6 +209,8 @@ static int nv17_tv_get_ld_modes(struct drm_encoder *encoder, · 208 unmodified lines | ||
| 209 | 209 | struct drm_display_mode *mode; |
| 210 | 210 | |
| 211 | 211 | mode = drm_mode_duplicate(encoder->dev, tv_mode); |
| 212 | + if (!mode) | |
| 213 | + continue; | |
| 212 | 214 | |
| 213 | 215 | mode->clock = tv_norm->tv_enc_mode.vrefresh * |
| 214 | 216 | mode->htotal / 1000 * |
| @@ -258,6 +260,8 @@ static int nv17_tv_get_hd_modes(struct drm_encoder *encoder, · 43 unmodified lines | ||
| 258 | 260 | if (modes[i].hdisplay == output_mode->hdisplay && |
| 259 | 261 | modes[i].vdisplay == output_mode->vdisplay) { |
| 260 | 262 | mode = drm_mode_duplicate(encoder->dev, output_mode); |
| 263 | + if (!mode) | |
| 264 | + continue; | |
| 261 | 265 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
| 262 | 266 | |
| 263 | 267 | } else { |
| @@ -265,6 +269,8 @@ static int nv17_tv_get_hd_modes(struct drm_encoder *encoder, · 1 unmodified line | ||
| 265 | 269 | modes[i].vdisplay, 60, false, |
| 266 | 270 | (output_mode->flags & |
| 267 | 271 | DRM_MODE_FLAG_INTERLACE), false); |
| 272 | + if (!mode) | |
| 273 | + continue; | |
| 268 | 274 | } |
| 269 | 275 | |
| 270 | 276 | /* CVT modes are sometimes unsuitable... */ |
| @@ -2752,6 +2752,7 @@ static const struct display_timing koe_tx26d202vm0bwa_timing = { · 2751 unmodified lines | ||
| 2752 | 2752 | .vfront_porch = { 3, 5, 10 }, |
| 2753 | 2753 | .vback_porch = { 2, 5, 10 }, |
| 2754 | 2754 | .vsync_len = { 5, 5, 5 }, |
| 2755 | + .flags = DISPLAY_FLAGS_DE_HIGH, | |
| 2755 | 2756 | }; |
| 2756 | 2757 | |
| 2757 | 2758 | static const struct panel_desc koe_tx26d202vm0bwa = { |
| @@ -29,8 +29,7 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o · 28 unmodified lines | ||
| 29 | 29 | obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o |
| 30 | 30 | obj-$(CONFIG_I2C_VIA) += i2c-via.o |
| 31 | 31 | obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o |
| 32 | −i2c-zhaoxin-objs := i2c-viai2c-zhaoxin.o i2c-viai2c-common.o | |
| 33 | −obj-$(CONFIG_I2C_ZHAOXIN) += i2c-zhaoxin.o | |
| 32 | +obj-$(CONFIG_I2C_ZHAOXIN) += i2c-viai2c-zhaoxin.o i2c-viai2c-common.o | |
| 34 | 33 | |
| 35 | 34 | # Mac SMBus host controller drivers |
| 36 | 35 | obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o |
| @@ -120,8 +119,7 @@ obj-$(CONFIG_I2C_TEGRA_BPMP) += i2c-tegra-bpmp.o · 83 unmodified lines | ||
| 120 | 119 | obj-$(CONFIG_I2C_UNIPHIER) += i2c-uniphier.o |
| 121 | 120 | obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-uniphier-f.o |
| 122 | 121 | obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o |
| 123 | −i2c-wmt-objs := i2c-viai2c-wmt.o i2c-viai2c-common.o | |
| 124 | −obj-$(CONFIG_I2C_WMT) += i2c-wmt.o | |
| 122 | +obj-$(CONFIG_I2C_WMT) += i2c-viai2c-wmt.o i2c-viai2c-common.o | |
| 125 | 123 | i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o |
| 126 | 124 | obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o |
| 127 | 125 | i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o |
| @@ -17,6 +17,7 @@ int viai2c_wait_bus_not_busy(struct viai2c *i2c) · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | return 0; |
| 19 | 19 | } |
| 20 | +EXPORT_SYMBOL_GPL(viai2c_wait_bus_not_busy); | |
| 20 | 21 | |
| 21 | 22 | static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, int last) |
| 22 | 23 | { |
| @@ -121,6 +122,7 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) · 98 unmodified lines | ||
| 121 | 122 | |
| 122 | 123 | return (ret < 0) ? ret : i; |
| 123 | 124 | } |
| 125 | +EXPORT_SYMBOL_GPL(viai2c_xfer); | |
| 124 | 126 | |
| 125 | 127 | /* |
| 126 | 128 | * Main process of the byte mode xfer |
| @@ -130,7 +132,7 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) · 3 unmodified lines | ||
| 130 | 132 | * 0: there is still data that needs to be transferred |
| 131 | 133 | * -EIO: error occurred |
| 132 | 134 | */ |
| 133 | −static int viai2c_irq_xfer(struct viai2c *i2c) | |
| 135 | +int viai2c_irq_xfer(struct viai2c *i2c) | |
| 134 | 136 | { |
| 135 | 137 | u16 val; |
| 136 | 138 | struct i2c_msg *msg = i2c->msg; |
| @@ -171,51 +173,11 @@ static int viai2c_irq_xfer(struct viai2c *i2c) · 34 unmodified lines | ||
| 171 | 173 | |
| 172 | 174 | return i2c->xfered_len == msg->len; |
| 173 | 175 | } |
| 174 | − | |
| 175 | −int __weak viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq) | |
| 176 | −{ | |
| 177 | − return 0; | |
| 178 | −} | |
| 179 | − | |
| 180 | −static irqreturn_t viai2c_isr(int irq, void *data) | |
| 181 | −{ | |
| 182 | − struct viai2c *i2c = data; | |
| 183 | − u8 status; | |
| 184 | − | |
| 185 | − /* save the status and write-clear it */ | |
| 186 | − status = readw(i2c->base + VIAI2C_REG_ISR); | |
| 187 | − if (!status && i2c->platform == VIAI2C_PLAT_ZHAOXIN) | |
| 188 | − return IRQ_NONE; | |
| 189 | − | |
| 190 | − writew(status, i2c->base + VIAI2C_REG_ISR); | |
| 191 | − | |
| 192 | − i2c->ret = 0; | |
| 193 | − if (status & VIAI2C_ISR_NACK_ADDR) | |
| 194 | − i2c->ret = -EIO; | |
| 195 | − | |
| 196 | − if (i2c->platform == VIAI2C_PLAT_WMT && (status & VIAI2C_ISR_SCL_TIMEOUT)) | |
| 197 | − i2c->ret = -ETIMEDOUT; | |
| 198 | − | |
| 199 | − if (!i2c->ret) { | |
| 200 | − if (i2c->mode == VIAI2C_BYTE_MODE) | |
| 201 | − i2c->ret = viai2c_irq_xfer(i2c); | |
| 202 | − else | |
| 203 | − i2c->ret = viai2c_fifo_irq_xfer(i2c, true); | |
| 204 | − } | |
| 205 | − | |
| 206 | − /* All the data has been successfully transferred or error occurred */ | |
| 207 | − if (i2c->ret) | |
| 208 | − complete(&i2c->complete); | |
| 209 | − | |
| 210 | − return IRQ_HANDLED; | |
| 211 | −} | |
| 176 | +EXPORT_SYMBOL_GPL(viai2c_irq_xfer); | |
| 212 | 177 | |
| 213 | 178 | int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat) |
| 214 | 179 | { |
| 215 | − int err; | |
| 216 | − int irq_flags; | |
| 217 | 180 | struct viai2c *i2c; |
| 218 | − struct device_node *np = pdev->dev.of_node; | |
| 219 | 181 | |
| 220 | 182 | i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); |
| 221 | 183 | if (!i2c) |
| @@ -225,28 +187,8 @@ int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat) · 3 unmodified lines | ||
| 225 | 187 | if (IS_ERR(i2c->base)) |
| 226 | 188 | return PTR_ERR(i2c->base); |
| 227 | 189 | |
| 228 | − if (plat == VIAI2C_PLAT_WMT) { | |
| 229 | − irq_flags = 0; | |
| 230 | − i2c->irq = irq_of_parse_and_map(np, 0); | |
| 231 | − if (!i2c->irq) | |
| 232 | − return -EINVAL; | |
| 233 | − } else if (plat == VIAI2C_PLAT_ZHAOXIN) { | |
| 234 | − irq_flags = IRQF_SHARED; | |
| 235 | − i2c->irq = platform_get_irq(pdev, 0); | |
| 236 | − if (i2c->irq < 0) | |
| 237 | − return i2c->irq; | |
| 238 | − } else { | |
| 239 | − return dev_err_probe(&pdev->dev, -EINVAL, "wrong platform type\n"); | |
| 240 | − } | |
| 241 | − | |
| 242 | 190 | i2c->platform = plat; |
| 243 | 191 | |
| 244 | − err = devm_request_irq(&pdev->dev, i2c->irq, viai2c_isr, | |
| 245 | − irq_flags, pdev->name, i2c); | |
| 246 | − if (err) | |
| 247 | − return dev_err_probe(&pdev->dev, err, | |
| 248 | − "failed to request irq %i\n", i2c->irq); | |
| 249 | − | |
| 250 | 192 | i2c->dev = &pdev->dev; |
| 251 | 193 | init_completion(&i2c->complete); |
| 252 | 194 | platform_set_drvdata(pdev, i2c); |
| @@ -254,3 +196,8 @@ int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat) · 1 unmodified line | ||
| 254 | 196 | *pi2c = i2c; |
| 255 | 197 | return 0; |
| 256 | 198 | } |
| 199 | +EXPORT_SYMBOL_GPL(viai2c_init); | |
| 200 | + | |
| 201 | +MODULE_DESCRIPTION("Via/Wondermedia/Zhaoxin I2C master-mode bus adapter"); | |
| 202 | +MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); | |
| 203 | +MODULE_LICENSE("GPL"); | |
| @@ -80,6 +80,6 @@ struct viai2c { · 79 unmodified lines | ||
| 80 | 80 | int viai2c_wait_bus_not_busy(struct viai2c *i2c); |
| 81 | 81 | int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num); |
| 82 | 82 | int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat); |
| 83 | −int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq); | |
| 83 | +int viai2c_irq_xfer(struct viai2c *i2c); | |
| 84 | 84 | |
| 85 | 85 | #endif |
| @@ -72,6 +72,32 @@ static int wmt_i2c_reset_hardware(struct viai2c *i2c) · 71 unmodified lines | ||
| 72 | 72 | return 0; |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | +static irqreturn_t wmt_i2c_isr(int irq, void *data) | |
| 76 | +{ | |
| 77 | + struct viai2c *i2c = data; | |
| 78 | + u8 status; | |
| 79 | + | |
| 80 | + /* save the status and write-clear it */ | |
| 81 | + status = readw(i2c->base + VIAI2C_REG_ISR); | |
| 82 | + writew(status, i2c->base + VIAI2C_REG_ISR); | |
| 83 | + | |
| 84 | + i2c->ret = 0; | |
| 85 | + if (status & VIAI2C_ISR_NACK_ADDR) | |
| 86 | + i2c->ret = -EIO; | |
| 87 | + | |
| 88 | + if (status & VIAI2C_ISR_SCL_TIMEOUT) | |
| 89 | + i2c->ret = -ETIMEDOUT; | |
| 90 | + | |
| 91 | + if (!i2c->ret) | |
| 92 | + i2c->ret = viai2c_irq_xfer(i2c); | |
| 93 | + | |
| 94 | + /* All the data has been successfully transferred or error occurred */ | |
| 95 | + if (i2c->ret) | |
| 96 | + complete(&i2c->complete); | |
| 97 | + | |
| 98 | + return IRQ_HANDLED; | |
| 99 | +} | |
| 100 | + | |
| 75 | 101 | static int wmt_i2c_probe(struct platform_device *pdev) |
| 76 | 102 | { |
| 77 | 103 | struct device_node *np = pdev->dev.of_node; |
| @@ -84,6 +110,16 @@ static int wmt_i2c_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 84 | 110 | if (err) |
| 85 | 111 | return err; |
| 86 | 112 | |
| 113 | + i2c->irq = platform_get_irq(pdev, 0); | |
| 114 | + if (i2c->irq < 0) | |
| 115 | + return i2c->irq; | |
| 116 | + | |
| 117 | + err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr, | |
| 118 | + 0, pdev->name, i2c); | |
| 119 | + if (err) | |
| 120 | + return dev_err_probe(&pdev->dev, err, | |
| 121 | + "failed to request irq %i\n", i2c->irq); | |
| 122 | + | |
| 87 | 123 | i2c->clk = of_clk_get(np, 0); |
| 88 | 124 | if (IS_ERR(i2c->clk)) { |
| 89 | 125 | dev_err(&pdev->dev, "unable to request clock\n"); |
| @@ -49,8 +49,7 @@ struct viai2c_zhaoxin { · 48 unmodified lines | ||
| 49 | 49 | u16 xfer_len; |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | −/* 'irq == true' means in interrupt context */ | |
| 53 | −int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq) | |
| 52 | +static int viai2c_fifo_xfer(struct viai2c *i2c) | |
| 54 | 53 | { |
| 55 | 54 | u16 i; |
| 56 | 55 | u8 tmp; |
| @@ -59,17 +58,6 @@ int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq) · 2 unmodified lines | ||
| 59 | 58 | bool read = !!(msg->flags & I2C_M_RD); |
| 60 | 59 | struct viai2c_zhaoxin *priv = i2c->pltfm_priv; |
| 61 | 60 | |
| 62 | − if (irq) { | |
| 63 | − /* get the received data */ | |
| 64 | − if (read) | |
| 65 | − for (i = 0; i < priv->xfer_len; i++) | |
| 66 | − msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR); | |
| 67 | − | |
| 68 | − i2c->xfered_len += priv->xfer_len; | |
| 69 | − if (i2c->xfered_len == msg->len) | |
| 70 | − return 1; | |
| 71 | − } | |
| 72 | − | |
| 73 | 61 | /* reset fifo buffer */ |
| 74 | 62 | tmp = ioread8(base + ZXI2C_REG_HCR); |
| 75 | 63 | iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR); |
| @@ -92,18 +80,59 @@ int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq) · 16 unmodified lines | ||
| 92 | 80 | iowrite8(tmp, base + VIAI2C_REG_CR); |
| 93 | 81 | } |
| 94 | 82 | |
| 95 | − if (irq) { | |
| 96 | − /* continue transmission */ | |
| 97 | − tmp = ioread8(base + VIAI2C_REG_CR); | |
| 98 | − iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR); | |
| 83 | + u16 tcr_val = i2c->tcr; | |
| 84 | + | |
| 85 | + /* start transmission */ | |
| 86 | + tcr_val |= read ? VIAI2C_TCR_READ : 0; | |
| 87 | + writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR); | |
| 88 | + | |
| 89 | + return 0; | |
| 90 | +} | |
| 91 | + | |
| 92 | +static int viai2c_fifo_irq_xfer(struct viai2c *i2c) | |
| 93 | +{ | |
| 94 | + u16 i; | |
| 95 | + u8 tmp; | |
| 96 | + struct i2c_msg *msg = i2c->msg; | |
| 97 | + void __iomem *base = i2c->base; | |
| 98 | + bool read = !!(msg->flags & I2C_M_RD); | |
| 99 | + struct viai2c_zhaoxin *priv = i2c->pltfm_priv; | |
| 100 | + | |
| 101 | + /* get the received data */ | |
| 102 | + if (read) | |
| 103 | + for (i = 0; i < priv->xfer_len; i++) | |
| 104 | + msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR); | |
| 105 | + | |
| 106 | + i2c->xfered_len += priv->xfer_len; | |
| 107 | + if (i2c->xfered_len == msg->len) | |
| 108 | + return 1; | |
| 109 | + | |
| 110 | + /* reset fifo buffer */ | |
| 111 | + tmp = ioread8(base + ZXI2C_REG_HCR); | |
| 112 | + iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR); | |
| 113 | + | |
| 114 | + /* set xfer len */ | |
| 115 | + priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE); | |
| 116 | + if (read) { | |
| 117 | + iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR); | |
| 99 | 118 | } else { |
| 100 | − u16 tcr_val = i2c->tcr; | |
| 119 | + iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR); | |
| 120 | + /* set write data */ | |
| 121 | + for (i = 0; i < priv->xfer_len; i++) | |
| 122 | + iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR); | |
| 123 | + } | |
| 101 | 124 | |
| 102 | − /* start transmission */ | |
| 103 | − tcr_val |= read ? VIAI2C_TCR_READ : 0; | |
| 104 | − writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR); | |
| 125 | + /* prepare to stop transmission */ | |
| 126 | + if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) { | |
| 127 | + tmp = ioread8(base + VIAI2C_REG_CR); | |
| 128 | + tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END; | |
| 129 | + iowrite8(tmp, base + VIAI2C_REG_CR); | |
| 105 | 130 | } |
| 106 | 131 | |
| 132 | + /* continue transmission */ | |
| 133 | + tmp = ioread8(base + VIAI2C_REG_CR); | |
| 134 | + iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR); | |
| 135 | + | |
| 107 | 136 | return 0; |
| 108 | 137 | } |
| 109 | 138 | |
| @@ -135,7 +164,7 @@ static int zxi2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int · 25 unmodified lines | ||
| 135 | 164 | priv->xfer_len = 0; |
| 136 | 165 | i2c->xfered_len = 0; |
| 137 | 166 | |
| 138 | − viai2c_fifo_irq_xfer(i2c, 0); | |
| 167 | + viai2c_fifo_xfer(i2c); | |
| 139 | 168 | |
| 140 | 169 | if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT)) |
| 141 | 170 | return -ETIMEDOUT; |
| @@ -228,6 +257,36 @@ static void zxi2c_get_bus_speed(struct viai2c *i2c) · 86 unmodified lines | ||
| 228 | 257 | dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0])); |
| 229 | 258 | } |
| 230 | 259 | |
| 260 | +static irqreturn_t zxi2c_isr(int irq, void *data) | |
| 261 | +{ | |
| 262 | + struct viai2c *i2c = data; | |
| 263 | + u8 status; | |
| 264 | + | |
| 265 | + /* save the status and write-clear it */ | |
| 266 | + status = readw(i2c->base + VIAI2C_REG_ISR); | |
| 267 | + if (!status) | |
| 268 | + return IRQ_NONE; | |
| 269 | + | |
| 270 | + writew(status, i2c->base + VIAI2C_REG_ISR); | |
| 271 | + | |
| 272 | + i2c->ret = 0; | |
| 273 | + if (status & VIAI2C_ISR_NACK_ADDR) | |
| 274 | + i2c->ret = -EIO; | |
| 275 | + | |
| 276 | + if (!i2c->ret) { | |
| 277 | + if (i2c->mode == VIAI2C_BYTE_MODE) | |
| 278 | + i2c->ret = viai2c_irq_xfer(i2c); | |
| 279 | + else | |
| 280 | + i2c->ret = viai2c_fifo_irq_xfer(i2c); | |
| 281 | + } | |
| 282 | + | |
| 283 | + /* All the data has been successfully transferred or error occurred */ | |
| 284 | + if (i2c->ret) | |
| 285 | + complete(&i2c->complete); | |
| 286 | + | |
| 287 | + return IRQ_HANDLED; | |
| 288 | +} | |
| 289 | + | |
| 231 | 290 | static int zxi2c_probe(struct platform_device *pdev) |
| 232 | 291 | { |
| 233 | 292 | int error; |
| @@ -239,6 +298,16 @@ static int zxi2c_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 239 | 298 | if (error) |
| 240 | 299 | return error; |
| 241 | 300 | |
| 301 | + i2c->irq = platform_get_irq(pdev, 0); | |
| 302 | + if (i2c->irq < 0) | |
| 303 | + return i2c->irq; | |
| 304 | + | |
| 305 | + error = devm_request_irq(&pdev->dev, i2c->irq, zxi2c_isr, | |
| 306 | + IRQF_SHARED, pdev->name, i2c); | |
| 307 | + if (error) | |
| 308 | + return dev_err_probe(&pdev->dev, error, | |
| 309 | + "failed to request irq %i\n", i2c->irq); | |
| 310 | + | |
| 242 | 311 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 243 | 312 | if (!priv) |
| 244 | 313 | return -ENOMEM; |
| @@ -118,9 +118,12 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, · 117 unmodified lines | ||
| 118 | 118 | queue_delayed_work(system_long_wq, &tu->worker, |
| 119 | 119 | msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY])); |
| 120 | 120 | } |
| 121 | − fallthrough; | |
| 121 | + break; | |
| 122 | 122 | |
| 123 | 123 | case I2C_SLAVE_WRITE_REQUESTED: |
| 124 | + if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags)) | |
| 125 | + return -EBUSY; | |
| 126 | + | |
| 124 | 127 | memset(tu->regs, 0, TU_NUM_REGS); |
| 125 | 128 | tu->reg_idx = 0; |
| 126 | 129 | break; |
| @@ -330,6 +330,8 @@ config DMARD10 · 329 unmodified lines | ||
| 330 | 330 | config FXLS8962AF |
| 331 | 331 | tristate |
| 332 | 332 | depends on I2C || !I2C # cannot be built-in for modular I2C |
| 333 | + select IIO_BUFFER | |
| 334 | + select IIO_KFIFO_BUF | |
| 333 | 335 | |
| 334 | 336 | config FXLS8962AF_I2C |
| 335 | 337 | tristate "NXP FXLS8962AF/FXLS8964AF Accelerometer I2C Driver" |
| @@ -157,6 +157,8 @@ static int ad7266_read_raw(struct iio_dev *indio_dev, · 156 unmodified lines | ||
| 157 | 157 | ret = ad7266_read_single(st, val, chan->address); |
| 158 | 158 | iio_device_release_direct_mode(indio_dev); |
| 159 | 159 | |
| 160 | + if (ret < 0) | |
| 161 | + return ret; | |
| 160 | 162 | *val = (*val >> 2) & 0xfff; |
| 161 | 163 | if (chan->scan_type.sign == 's') |
| 162 | 164 | *val = sign_extend32(*val, |
| @@ -414,8 +414,12 @@ static void ams_enable_channel_sequence(struct iio_dev *indio_dev) · 413 unmodified lines | ||
| 414 | 414 | |
| 415 | 415 | /* Run calibration of PS & PL as part of the sequence */ |
| 416 | 416 | scan_mask = BIT(0) | BIT(AMS_PS_SEQ_MAX); |
| 417 | − for (i = 0; i < indio_dev->num_channels; i++) | |
| 418 | − scan_mask |= BIT_ULL(indio_dev->channels[i].scan_index); | |
| 417 | + for (i = 0; i < indio_dev->num_channels; i++) { | |
| 418 | + const struct iio_chan_spec *chan = &indio_dev->channels[i]; | |
| 419 | + | |
| 420 | + if (chan->scan_index < AMS_CTRL_SEQ_BASE) | |
| 421 | + scan_mask |= BIT_ULL(chan->scan_index); | |
| 422 | + } | |
| 419 | 423 | |
| 420 | 424 | if (ams->ps_base) { |
| 421 | 425 | /* put sysmon in a soft reset to change the sequence */ |
| @@ -54,7 +54,9 @@ · 53 unmodified lines | ||
| 54 | 54 | #define BME680_NB_CONV_MASK GENMASK(3, 0) |
| 55 | 55 | |
| 56 | 56 | #define BME680_REG_MEAS_STAT_0 0x1D |
| 57 | +#define BME680_NEW_DATA_BIT BIT(7) | |
| 57 | 58 | #define BME680_GAS_MEAS_BIT BIT(6) |
| 59 | +#define BME680_MEAS_BIT BIT(5) | |
| 58 | 60 | |
| 59 | 61 | /* Calibration Parameters */ |
| 60 | 62 | #define BME680_T2_LSB_REG 0x8A |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | */ |
| 11 | 11 | #include <linux/acpi.h> |
| 12 | 12 | #include <linux/bitfield.h> |
| 13 | +#include <linux/delay.h> | |
| 13 | 14 | #include <linux/device.h> |
| 14 | 15 | #include <linux/module.h> |
| 15 | 16 | #include <linux/log2.h> |
| @@ -38,7 +39,7 @@ struct bme680_calib { · 22 unmodified lines | ||
| 38 | 39 | s8 par_h3; |
| 39 | 40 | s8 par_h4; |
| 40 | 41 | s8 par_h5; |
| 41 | − s8 par_h6; | |
| 42 | + u8 par_h6; | |
| 42 | 43 | s8 par_h7; |
| 43 | 44 | s8 par_gh1; |
| 44 | 45 | s16 par_gh2; |
| @@ -342,10 +343,10 @@ static s16 bme680_compensate_temp(struct bme680_data *data, · 297 unmodified lines | ||
| 342 | 343 | if (!calib->par_t2) |
| 343 | 344 | bme680_read_calib(data, calib); |
| 344 | 345 | |
| 345 | − var1 = (adc_temp >> 3) - (calib->par_t1 << 1); | |
| 346 | + var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1); | |
| 346 | 347 | var2 = (var1 * calib->par_t2) >> 11; |
| 347 | 348 | var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; |
| 348 | − var3 = (var3 * (calib->par_t3 << 4)) >> 14; | |
| 349 | + var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14; | |
| 349 | 350 | data->t_fine = var2 + var3; |
| 350 | 351 | calc_temp = (data->t_fine * 5 + 128) >> 8; |
| 351 | 352 | |
| @@ -368,9 +369,9 @@ static u32 bme680_compensate_press(struct bme680_data *data, · 16 unmodified lines | ||
| 368 | 369 | var1 = (data->t_fine >> 1) - 64000; |
| 369 | 370 | var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2; |
| 370 | 371 | var2 = var2 + (var1 * calib->par_p5 << 1); |
| 371 | − var2 = (var2 >> 2) + (calib->par_p4 << 16); | |
| 372 | + var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16); | |
| 372 | 373 | var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * |
| 373 | − (calib->par_p3 << 5)) >> 3) + | |
| 374 | + ((s32)calib->par_p3 << 5)) >> 3) + | |
| 374 | 375 | ((calib->par_p2 * var1) >> 1); |
| 375 | 376 | var1 = var1 >> 18; |
| 376 | 377 | var1 = ((32768 + var1) * calib->par_p1) >> 15; |
| @@ -388,7 +389,7 @@ static u32 bme680_compensate_press(struct bme680_data *data, · 11 unmodified lines | ||
| 388 | 389 | var3 = ((press_comp >> 8) * (press_comp >> 8) * |
| 389 | 390 | (press_comp >> 8) * calib->par_p10) >> 17; |
| 390 | 391 | |
| 391 | − press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4; | |
| 392 | + press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4; | |
| 392 | 393 | |
| 393 | 394 | return press_comp; |
| 394 | 395 | } |
| @@ -414,7 +415,7 @@ static u32 bme680_compensate_humid(struct bme680_data *data, · 19 unmodified lines | ||
| 414 | 415 | (((temp_scaled * ((temp_scaled * calib->par_h5) / 100)) |
| 415 | 416 | >> 6) / 100) + (1 << 14))) >> 10; |
| 416 | 417 | var3 = var1 * var2; |
| 417 | − var4 = calib->par_h6 << 7; | |
| 418 | + var4 = (s32)calib->par_h6 << 7; | |
| 418 | 419 | var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4; |
| 419 | 420 | var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; |
| 420 | 421 | var6 = (var4 * var5) >> 1; |
| @@ -532,6 +533,43 @@ static u8 bme680_oversampling_to_reg(u8 val) · 111 unmodified lines | ||
| 532 | 533 | return ilog2(val) + 1; |
| 533 | 534 | } |
| 534 | 535 | |
| 536 | +/* | |
| 537 | + * Taken from Bosch BME680 API: | |
| 538 | + * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 | |
| 539 | + */ | |
| 540 | +static int bme680_wait_for_eoc(struct bme680_data *data) | |
| 541 | +{ | |
| 542 | + struct device *dev = regmap_get_device(data->regmap); | |
| 543 | + unsigned int check; | |
| 544 | + int ret; | |
| 545 | + /* | |
| 546 | + * (Sum of oversampling ratios * time per oversampling) + | |
| 547 | + * TPH measurement + gas measurement + wait transition from forced mode | |
| 548 | + * + heater duration | |
| 549 | + */ | |
| 550 | + int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press + | |
| 551 | + data->oversampling_humid) * 1936) + (477 * 4) + | |
| 552 | + (477 * 5) + 1000 + (data->heater_dur * 1000); | |
| 553 | + | |
| 554 | + usleep_range(wait_eoc_us, wait_eoc_us + 100); | |
| 555 | + | |
| 556 | + ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); | |
| 557 | + if (ret) { | |
| 558 | + dev_err(dev, "failed to read measurement status register.\n"); | |
| 559 | + return ret; | |
| 560 | + } | |
| 561 | + if (check & BME680_MEAS_BIT) { | |
| 562 | + dev_err(dev, "Device measurement cycle incomplete.\n"); | |
| 563 | + return -EBUSY; | |
| 564 | + } | |
| 565 | + if (!(check & BME680_NEW_DATA_BIT)) { | |
| 566 | + dev_err(dev, "No new data available from the device.\n"); | |
| 567 | + return -ENODATA; | |
| 568 | + } | |
| 569 | + | |
| 570 | + return 0; | |
| 571 | +} | |
| 572 | + | |
| 535 | 573 | static int bme680_chip_config(struct bme680_data *data) |
| 536 | 574 | { |
| 537 | 575 | struct device *dev = regmap_get_device(data->regmap); |
| @@ -622,6 +660,10 @@ static int bme680_read_temp(struct bme680_data *data, int *val) · 84 unmodified lines | ||
| 622 | 660 | if (ret < 0) |
| 623 | 661 | return ret; |
| 624 | 662 | |
| 663 | + ret = bme680_wait_for_eoc(data); | |
| 664 | + if (ret) | |
| 665 | + return ret; | |
| 666 | + | |
| 625 | 667 | ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB, |
| 626 | 668 | &tmp, 3); |
| 627 | 669 | if (ret < 0) { |
| @@ -678,7 +720,7 @@ static int bme680_read_press(struct bme680_data *data, · 50 unmodified lines | ||
| 678 | 720 | } |
| 679 | 721 | |
| 680 | 722 | *val = bme680_compensate_press(data, adc_press); |
| 681 | − *val2 = 100; | |
| 723 | + *val2 = 1000; | |
| 682 | 724 | return IIO_VAL_FRACTIONAL; |
| 683 | 725 | } |
| 684 | 726 | |
| @@ -738,6 +780,10 @@ static int bme680_read_gas(struct bme680_data *data, · 53 unmodified lines | ||
| 738 | 780 | if (ret < 0) |
| 739 | 781 | return ret; |
| 740 | 782 | |
| 783 | + ret = bme680_wait_for_eoc(data); | |
| 784 | + if (ret) | |
| 785 | + return ret; | |
| 786 | + | |
| 741 | 787 | ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); |
| 742 | 788 | if (check & BME680_GAS_MEAS_BIT) { |
| 743 | 789 | dev_err(dev, "gas measurement incomplete\n"); |
| @@ -133,7 +133,7 @@ config AD5624R_SPI · 132 unmodified lines | ||
| 133 | 133 | |
| 134 | 134 | config AD9739A |
| 135 | 135 | tristate "Analog Devices AD9739A RF DAC spi driver" |
| 136 | − depends on SPI || COMPILE_TEST | |
| 136 | + depends on SPI | |
| 137 | 137 | select REGMAP_SPI |
| 138 | 138 | select IIO_BACKEND |
| 139 | 139 | help |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/i2c.h> |
| 20 | 20 | #include <linux/init.h> |
| 21 | 21 | #include <linux/interrupt.h> |
| 22 | +#include <linux/math64.h> | |
| 22 | 23 | #include <linux/module.h> |
| 23 | 24 | #include <linux/mutex.h> |
| 24 | 25 | #include <linux/pm.h> |
| @@ -66,8 +67,10 @@ · 41 unmodified lines | ||
| 66 | 67 | |
| 67 | 68 | #define HDC3020_CRC8_POLYNOMIAL 0x31 |
| 68 | 69 | |
| 69 | −#define HDC3020_MIN_TEMP -40 | |
| 70 | −#define HDC3020_MAX_TEMP 125 | |
| 70 | +#define HDC3020_MIN_TEMP_MICRO -39872968 | |
| 71 | +#define HDC3020_MAX_TEMP_MICRO 124875639 | |
| 72 | +#define HDC3020_MAX_TEMP_HYST_MICRO 164748607 | |
| 73 | +#define HDC3020_MAX_HUM_MICRO 99220264 | |
| 71 | 74 | |
| 72 | 75 | struct hdc3020_data { |
| 73 | 76 | struct i2c_client *client; |
| @@ -368,6 +371,105 @@ static int hdc3020_write_raw(struct iio_dev *indio_dev, · 294 unmodified lines | ||
| 368 | 371 | return -EINVAL; |
| 369 | 372 | } |
| 370 | 373 | |
| 374 | +static int hdc3020_thresh_get_temp(u16 thresh) | |
| 375 | +{ | |
| 376 | + int temp; | |
| 377 | + | |
| 378 | + /* | |
| 379 | + * Get the temperature threshold from 9 LSBs, shift them to get | |
| 380 | + * the truncated temperature threshold representation and | |
| 381 | + * calculate the threshold according to the formula in the | |
| 382 | + * datasheet. Result is degree celsius scaled by 65535. | |
| 383 | + */ | |
| 384 | + temp = FIELD_GET(HDC3020_THRESH_TEMP_MASK, thresh) << | |
| 385 | + HDC3020_THRESH_TEMP_TRUNC_SHIFT; | |
| 386 | + | |
| 387 | + return -2949075 + (175 * temp); | |
| 388 | +} | |
| 389 | + | |
| 390 | +static int hdc3020_thresh_get_hum(u16 thresh) | |
| 391 | +{ | |
| 392 | + int hum; | |
| 393 | + | |
| 394 | + /* | |
| 395 | + * Get the humidity threshold from 7 MSBs, shift them to get the | |
| 396 | + * truncated humidity threshold representation and calculate the | |
| 397 | + * threshold according to the formula in the datasheet. Result is | |
| 398 | + * percent scaled by 65535. | |
| 399 | + */ | |
| 400 | + hum = FIELD_GET(HDC3020_THRESH_HUM_MASK, thresh) << | |
| 401 | + HDC3020_THRESH_HUM_TRUNC_SHIFT; | |
| 402 | + | |
| 403 | + return hum * 100; | |
| 404 | +} | |
| 405 | + | |
| 406 | +static u16 hdc3020_thresh_set_temp(int s_temp, u16 curr_thresh) | |
| 407 | +{ | |
| 408 | + u64 temp; | |
| 409 | + u16 thresh; | |
| 410 | + | |
| 411 | + /* | |
| 412 | + * Calculate temperature threshold, shift it down to get the | |
| 413 | + * truncated threshold representation in the 9LSBs while keeping | |
| 414 | + * the current humidity threshold in the 7 MSBs. | |
| 415 | + */ | |
| 416 | + temp = (u64)(s_temp + 45000000) * 65535ULL; | |
| 417 | + temp = div_u64(temp, 1000000 * 175) >> HDC3020_THRESH_TEMP_TRUNC_SHIFT; | |
| 418 | + thresh = FIELD_PREP(HDC3020_THRESH_TEMP_MASK, temp); | |
| 419 | + thresh |= (FIELD_GET(HDC3020_THRESH_HUM_MASK, curr_thresh) << | |
| 420 | + HDC3020_THRESH_HUM_TRUNC_SHIFT); | |
| 421 | + | |
| 422 | + return thresh; | |
| 423 | +} | |
| 424 | + | |
| 425 | +static u16 hdc3020_thresh_set_hum(int s_hum, u16 curr_thresh) | |
| 426 | +{ | |
| 427 | + u64 hum; | |
| 428 | + u16 thresh; | |
| 429 | + | |
| 430 | + /* | |
| 431 | + * Calculate humidity threshold, shift it down and up to get the | |
| 432 | + * truncated threshold representation in the 7MSBs while keeping | |
| 433 | + * the current temperature threshold in the 9 LSBs. | |
| 434 | + */ | |
| 435 | + hum = (u64)(s_hum) * 65535ULL; | |
| 436 | + hum = div_u64(hum, 1000000 * 100) >> HDC3020_THRESH_HUM_TRUNC_SHIFT; | |
| 437 | + thresh = FIELD_PREP(HDC3020_THRESH_HUM_MASK, hum); | |
| 438 | + thresh |= FIELD_GET(HDC3020_THRESH_TEMP_MASK, curr_thresh); | |
| 439 | + | |
| 440 | + return thresh; | |
| 441 | +} | |
| 442 | + | |
| 443 | +static | |
| 444 | +int hdc3020_thresh_clr(s64 s_thresh, s64 s_hyst, enum iio_event_direction dir) | |
| 445 | +{ | |
| 446 | + s64 s_clr; | |
| 447 | + | |
| 448 | + /* | |
| 449 | + * Include directions when calculation the clear value, | |
| 450 | + * since hysteresis is unsigned by definition and the | |
| 451 | + * clear value is an absolute value which is signed. | |
| 452 | + */ | |
| 453 | + if (dir == IIO_EV_DIR_RISING) | |
| 454 | + s_clr = s_thresh - s_hyst; | |
| 455 | + else | |
| 456 | + s_clr = s_thresh + s_hyst; | |
| 457 | + | |
| 458 | + /* Divide by 65535 to get units of micro */ | |
| 459 | + return div_s64(s_clr, 65535); | |
| 460 | +} | |
| 461 | + | |
| 462 | +static int _hdc3020_write_thresh(struct hdc3020_data *data, u16 reg, u16 val) | |
| 463 | +{ | |
| 464 | + u8 buf[5]; | |
| 465 | + | |
| 466 | + put_unaligned_be16(reg, buf); | |
| 467 | + put_unaligned_be16(val, buf + 2); | |
| 468 | + buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); | |
| 469 | + | |
| 470 | + return hdc3020_write_bytes(data, buf, 5); | |
| 471 | +} | |
| 472 | + | |
| 371 | 473 | static int hdc3020_write_thresh(struct iio_dev *indio_dev, |
| 372 | 474 | const struct iio_chan_spec *chan, |
| 373 | 475 | enum iio_event_type type, |
| @@ -376,67 +478,126 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev, · 2 unmodified lines | ||
| 376 | 478 | int val, int val2) |
| 377 | 479 | { |
| 378 | 480 | struct hdc3020_data *data = iio_priv(indio_dev); |
| 379 | − u8 buf[5]; | |
| 380 | − u64 tmp; | |
| 381 | − u16 reg; | |
| 382 | − int ret; | |
| 383 | − | |
| 384 | − /* Supported temperature range is from –40 to 125 degree celsius */ | |
| 385 | − if (val < HDC3020_MIN_TEMP || val > HDC3020_MAX_TEMP) | |
| 386 | − return -EINVAL; | |
| 387 | − | |
| 388 | − /* Select threshold register */ | |
| 389 | − if (info == IIO_EV_INFO_VALUE) { | |
| 390 | − if (dir == IIO_EV_DIR_RISING) | |
| 391 | − reg = HDC3020_S_T_RH_THRESH_HIGH; | |
| 392 | − else | |
| 393 | − reg = HDC3020_S_T_RH_THRESH_LOW; | |
| 481 | + u16 reg, reg_val, reg_thresh_rd, reg_clr_rd, reg_thresh_wr, reg_clr_wr; | |
| 482 | + s64 s_thresh, s_hyst, s_clr; | |
| 483 | + int s_val, thresh, clr, ret; | |
| 484 | + | |
| 485 | + /* Select threshold registers */ | |
| 486 | + if (dir == IIO_EV_DIR_RISING) { | |
| 487 | + reg_thresh_rd = HDC3020_R_T_RH_THRESH_HIGH; | |
| 488 | + reg_thresh_wr = HDC3020_S_T_RH_THRESH_HIGH; | |
| 489 | + reg_clr_rd = HDC3020_R_T_RH_THRESH_HIGH_CLR; | |
| 490 | + reg_clr_wr = HDC3020_S_T_RH_THRESH_HIGH_CLR; | |
| 394 | 491 | } else { |
| 395 | − if (dir == IIO_EV_DIR_RISING) | |
| 396 | − reg = HDC3020_S_T_RH_THRESH_HIGH_CLR; | |
| 397 | − else | |
| 398 | − reg = HDC3020_S_T_RH_THRESH_LOW_CLR; | |
| 492 | + reg_thresh_rd = HDC3020_R_T_RH_THRESH_LOW; | |
| 493 | + reg_thresh_wr = HDC3020_S_T_RH_THRESH_LOW; | |
| 494 | + reg_clr_rd = HDC3020_R_T_RH_THRESH_LOW_CLR; | |
| 495 | + reg_clr_wr = HDC3020_S_T_RH_THRESH_LOW_CLR; | |
| 399 | 496 | } |
| 400 | 497 | |
| 401 | 498 | guard(mutex)(&data->lock); |
| 402 | − ret = hdc3020_read_be16(data, reg); | |
| 499 | + ret = hdc3020_read_be16(data, reg_thresh_rd); | |
| 500 | + if (ret < 0) | |
| 501 | + return ret; | |
| 502 | + | |
| 503 | + thresh = ret; | |
| 504 | + ret = hdc3020_read_be16(data, reg_clr_rd); | |
| 403 | 505 | if (ret < 0) |
| 404 | 506 | return ret; |
| 405 | 507 | |
| 508 | + clr = ret; | |
| 509 | + /* Scale value to include decimal part into calculations */ | |
| 510 | + s_val = (val < 0) ? (val * 1000000 - val2) : (val * 1000000 + val2); | |
| 406 | 511 | switch (chan->type) { |
| 407 | 512 | case IIO_TEMP: |
| 408 | − /* | |
| 409 | − * Calculate temperature threshold, shift it down to get the | |
| 410 | − * truncated threshold representation in the 9LSBs while keeping | |
| 411 | − * the current humidity threshold in the 7 MSBs. | |
| 412 | − */ | |
| 413 | − tmp = ((u64)(((val + 45) * MICRO) + val2)) * 65535ULL; | |
| 414 | − tmp = div_u64(tmp, MICRO * 175); | |
| 415 | − val = tmp >> HDC3020_THRESH_TEMP_TRUNC_SHIFT; | |
| 416 | − val = FIELD_PREP(HDC3020_THRESH_TEMP_MASK, val); | |
| 417 | − val |= (FIELD_GET(HDC3020_THRESH_HUM_MASK, ret) << | |
| 418 | − HDC3020_THRESH_HUM_TRUNC_SHIFT); | |
| 513 | + switch (info) { | |
| 514 | + case IIO_EV_INFO_VALUE: | |
| 515 | + s_val = max(s_val, HDC3020_MIN_TEMP_MICRO); | |
| 516 | + s_val = min(s_val, HDC3020_MAX_TEMP_MICRO); | |
| 517 | + reg = reg_thresh_wr; | |
| 518 | + reg_val = hdc3020_thresh_set_temp(s_val, thresh); | |
| 519 | + ret = _hdc3020_write_thresh(data, reg, reg_val); | |
| 520 | + if (ret < 0) | |
| 521 | + return ret; | |
| 522 | + | |
| 523 | + /* Calculate old hysteresis */ | |
| 524 | + s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000; | |
| 525 | + s_clr = (s64)hdc3020_thresh_get_temp(clr) * 1000000; | |
| 526 | + s_hyst = div_s64(abs(s_thresh - s_clr), 65535); | |
| 527 | + /* Set new threshold */ | |
| 528 | + thresh = reg_val; | |
| 529 | + /* Set old hysteresis */ | |
| 530 | + s_val = s_hyst; | |
| 531 | + fallthrough; | |
| 532 | + case IIO_EV_INFO_HYSTERESIS: | |
| 533 | + /* | |
| 534 | + * Function hdc3020_thresh_get_temp returns temperature | |
| 535 | + * in degree celsius scaled by 65535. Scale by 1000000 | |
| 536 | + * to be able to subtract scaled hysteresis value. | |
| 537 | + */ | |
| 538 | + s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000; | |
| 539 | + /* | |
| 540 | + * Units of s_val are in micro degree celsius, scale by | |
| 541 | + * 65535 to get same units as s_thresh. | |
| 542 | + */ | |
| 543 | + s_val = min(abs(s_val), HDC3020_MAX_TEMP_HYST_MICRO); | |
| 544 | + s_hyst = (s64)s_val * 65535; | |
| 545 | + s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir); | |
| 546 | + s_clr = max(s_clr, HDC3020_MIN_TEMP_MICRO); | |
| 547 | + s_clr = min(s_clr, HDC3020_MAX_TEMP_MICRO); | |
| 548 | + reg = reg_clr_wr; | |
| 549 | + reg_val = hdc3020_thresh_set_temp(s_clr, clr); | |
| 550 | + break; | |
| 551 | + default: | |
| 552 | + return -EOPNOTSUPP; | |
| 553 | + } | |
| 419 | 554 | break; |
| 420 | 555 | case IIO_HUMIDITYRELATIVE: |
| 421 | − /* | |
| 422 | − * Calculate humidity threshold, shift it down and up to get the | |
| 423 | − * truncated threshold representation in the 7MSBs while keeping | |
| 424 | − * the current temperature threshold in the 9 LSBs. | |
| 425 | − */ | |
| 426 | − tmp = ((u64)((val * MICRO) + val2)) * 65535ULL; | |
| 427 | − tmp = div_u64(tmp, MICRO * 100); | |
| 428 | − val = tmp >> HDC3020_THRESH_HUM_TRUNC_SHIFT; | |
| 429 | − val = FIELD_PREP(HDC3020_THRESH_HUM_MASK, val); | |
| 430 | − val |= FIELD_GET(HDC3020_THRESH_TEMP_MASK, ret); | |
| 556 | + s_val = (s_val < 0) ? 0 : min(s_val, HDC3020_MAX_HUM_MICRO); | |
| 557 | + switch (info) { | |
| 558 | + case IIO_EV_INFO_VALUE: | |
| 559 | + reg = reg_thresh_wr; | |
| 560 | + reg_val = hdc3020_thresh_set_hum(s_val, thresh); | |
| 561 | + ret = _hdc3020_write_thresh(data, reg, reg_val); | |
| 562 | + if (ret < 0) | |
| 563 | + return ret; | |
| 564 | + | |
| 565 | + /* Calculate old hysteresis */ | |
| 566 | + s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000; | |
| 567 | + s_clr = (s64)hdc3020_thresh_get_hum(clr) * 1000000; | |
| 568 | + s_hyst = div_s64(abs(s_thresh - s_clr), 65535); | |
| 569 | + /* Set new threshold */ | |
| 570 | + thresh = reg_val; | |
| 571 | + /* Try to set old hysteresis */ | |
| 572 | + s_val = min(abs(s_hyst), HDC3020_MAX_HUM_MICRO); | |
| 573 | + fallthrough; | |
| 574 | + case IIO_EV_INFO_HYSTERESIS: | |
| 575 | + /* | |
| 576 | + * Function hdc3020_thresh_get_hum returns relative | |
| 577 | + * humidity in percent scaled by 65535. Scale by 1000000 | |
| 578 | + * to be able to subtract scaled hysteresis value. | |
| 579 | + */ | |
| 580 | + s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000; | |
| 581 | + /* | |
| 582 | + * Units of s_val are in micro percent, scale by 65535 | |
| 583 | + * to get same units as s_thresh. | |
| 584 | + */ | |
| 585 | + s_hyst = (s64)s_val * 65535; | |
| 586 | + s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir); | |
| 587 | + s_clr = max(s_clr, 0); | |
| 588 | + s_clr = min(s_clr, HDC3020_MAX_HUM_MICRO); | |
| 589 | + reg = reg_clr_wr; | |
| 590 | + reg_val = hdc3020_thresh_set_hum(s_clr, clr); | |
| 591 | + break; | |
| 592 | + default: | |
| 593 | + return -EOPNOTSUPP; | |
| 594 | + } | |
| 431 | 595 | break; |
| 432 | 596 | default: |
| 433 | 597 | return -EOPNOTSUPP; |
| 434 | 598 | } |
| 435 | 599 | |
| 436 | − put_unaligned_be16(reg, buf); | |
| 437 | − put_unaligned_be16(val, buf + 2); | |
| 438 | − buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); | |
| 439 | − return hdc3020_write_bytes(data, buf, 5); | |
| 600 | + return _hdc3020_write_thresh(data, reg, reg_val); | |
| 440 | 601 | } |
| 441 | 602 | |
| 442 | 603 | static int hdc3020_read_thresh(struct iio_dev *indio_dev, |
| @@ -447,48 +608,60 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev, · 4 unmodified lines | ||
| 447 | 608 | int *val, int *val2) |
| 448 | 609 | { |
| 449 | 610 | struct hdc3020_data *data = iio_priv(indio_dev); |
| 450 | − u16 reg; | |
| 451 | − int ret; | |
| 611 | + u16 reg_thresh, reg_clr; | |
| 612 | + int thresh, clr, ret; | |
| 452 | 613 | |
| 453 | − /* Select threshold register */ | |
| 454 | − if (info == IIO_EV_INFO_VALUE) { | |
| 455 | − if (dir == IIO_EV_DIR_RISING) | |
| 456 | − reg = HDC3020_R_T_RH_THRESH_HIGH; | |
| 457 | − else | |
| 458 | − reg = HDC3020_R_T_RH_THRESH_LOW; | |
| 614 | + /* Select threshold registers */ | |
| 615 | + if (dir == IIO_EV_DIR_RISING) { | |
| 616 | + reg_thresh = HDC3020_R_T_RH_THRESH_HIGH; | |
| 617 | + reg_clr = HDC3020_R_T_RH_THRESH_HIGH_CLR; | |
| 459 | 618 | } else { |
| 460 | − if (dir == IIO_EV_DIR_RISING) | |
| 461 | − reg = HDC3020_R_T_RH_THRESH_HIGH_CLR; | |
| 462 | − else | |
| 463 | − reg = HDC3020_R_T_RH_THRESH_LOW_CLR; | |
| 619 | + reg_thresh = HDC3020_R_T_RH_THRESH_LOW; | |
| 620 | + reg_clr = HDC3020_R_T_RH_THRESH_LOW_CLR; | |
| 464 | 621 | } |
| 465 | 622 | |
| 466 | 623 | guard(mutex)(&data->lock); |
| 467 | − ret = hdc3020_read_be16(data, reg); | |
| 624 | + ret = hdc3020_read_be16(data, reg_thresh); | |
| 468 | 625 | if (ret < 0) |
| 469 | 626 | return ret; |
| 470 | 627 | |
| 471 | 628 | switch (chan->type) { |
| 472 | 629 | case IIO_TEMP: |
| 473 | − /* | |
| 474 | − * Get the temperature threshold from 9 LSBs, shift them to get | |
| 475 | − * the truncated temperature threshold representation and | |
| 476 | − * calculate the threshold according to the formula in the | |
| 477 | − * datasheet. | |
| 478 | − */ | |
| 479 | − *val = FIELD_GET(HDC3020_THRESH_TEMP_MASK, ret); | |
| 480 | − *val = *val << HDC3020_THRESH_TEMP_TRUNC_SHIFT; | |
| 481 | − *val = -2949075 + (175 * (*val)); | |
| 630 | + thresh = hdc3020_thresh_get_temp(ret); | |
| 631 | + switch (info) { | |
| 632 | + case IIO_EV_INFO_VALUE: | |
| 633 | + *val = thresh; | |
| 634 | + break; | |
| 635 | + case IIO_EV_INFO_HYSTERESIS: | |
| 636 | + ret = hdc3020_read_be16(data, reg_clr); | |
| 637 | + if (ret < 0) | |
| 638 | + return ret; | |
| 639 | + | |
| 640 | + clr = hdc3020_thresh_get_temp(ret); | |
| 641 | + *val = abs(thresh - clr); | |
| 642 | + break; | |
| 643 | + default: | |
| 644 | + return -EOPNOTSUPP; | |
| 645 | + } | |
| 482 | 646 | *val2 = 65535; |
| 483 | 647 | return IIO_VAL_FRACTIONAL; |
| 484 | 648 | case IIO_HUMIDITYRELATIVE: |
| 485 | − /* | |
| 486 | − * Get the humidity threshold from 7 MSBs, shift them to get the | |
| 487 | − * truncated humidity threshold representation and calculate the | |
| 488 | − * threshold according to the formula in the datasheet. | |
| 489 | − */ | |
| 490 | − *val = FIELD_GET(HDC3020_THRESH_HUM_MASK, ret); | |
| 491 | − *val = (*val << HDC3020_THRESH_HUM_TRUNC_SHIFT) * 100; | |
| 649 | + thresh = hdc3020_thresh_get_hum(ret); | |
| 650 | + switch (info) { | |
| 651 | + case IIO_EV_INFO_VALUE: | |
| 652 | + *val = thresh; | |
| 653 | + break; | |
| 654 | + case IIO_EV_INFO_HYSTERESIS: | |
| 655 | + ret = hdc3020_read_be16(data, reg_clr); | |
| 656 | + if (ret < 0) | |
| 657 | + return ret; | |
| 658 | + | |
| 659 | + clr = hdc3020_thresh_get_hum(ret); | |
| 660 | + *val = abs(thresh - clr); | |
| 661 | + break; | |
| 662 | + default: | |
| 663 | + return -EOPNOTSUPP; | |
| 664 | + } | |
| 492 | 665 | *val2 = 65535; |
| 493 | 666 | return IIO_VAL_FRACTIONAL; |
| 494 | 667 | default: |
| @@ -2743,6 +2743,7 @@ static void early_enable_iommu(struct amd_iommu *iommu) · 2742 unmodified lines | ||
| 2743 | 2743 | iommu_enable_command_buffer(iommu); |
| 2744 | 2744 | iommu_enable_event_buffer(iommu); |
| 2745 | 2745 | iommu_set_exclusion_range(iommu); |
| 2746 | + iommu_enable_gt(iommu); | |
| 2746 | 2747 | iommu_enable_ga(iommu); |
| 2747 | 2748 | iommu_enable_xt(iommu); |
| 2748 | 2749 | iommu_enable_irtcachedis(iommu); |
| @@ -2061,6 +2061,12 @@ static void do_detach(struct iommu_dev_data *dev_data) · 2060 unmodified lines | ||
| 2061 | 2061 | struct protection_domain *domain = dev_data->domain; |
| 2062 | 2062 | struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data); |
| 2063 | 2063 | |
| 2064 | + /* Clear DTE and flush the entry */ | |
| 2065 | + amd_iommu_dev_update_dte(dev_data, false); | |
| 2066 | + | |
| 2067 | + /* Flush IOTLB and wait for the flushes to finish */ | |
| 2068 | + amd_iommu_domain_flush_all(domain); | |
| 2069 | + | |
| 2064 | 2070 | /* Clear GCR3 table */ |
| 2065 | 2071 | if (pdom_is_sva_capable(domain)) |
| 2066 | 2072 | destroy_gcr3_table(dev_data, domain); |
| @@ -2069,12 +2075,6 @@ static void do_detach(struct iommu_dev_data *dev_data) · 2 unmodified lines | ||
| 2069 | 2075 | dev_data->domain = NULL; |
| 2070 | 2076 | list_del(&dev_data->list); |
| 2071 | 2077 | |
| 2072 | − /* Clear DTE and flush the entry */ | |
| 2073 | − amd_iommu_dev_update_dte(dev_data, false); | |
| 2074 | − | |
| 2075 | − /* Flush IOTLB and wait for the flushes to finish */ | |
| 2076 | − amd_iommu_domain_flush_all(domain); | |
| 2077 | − | |
| 2078 | 2078 | /* decrease reference counters - needs to happen after the flushes */ |
| 2079 | 2079 | domain->dev_iommu[iommu->index] -= 1; |
| 2080 | 2080 | domain->dev_cnt -= 1; |
| @@ -2114,12 +2114,6 @@ static int dmar_domain_attach_device(struct dmar_domain *domain, · 2113 unmodified lines | ||
| 2114 | 2114 | if (ret) |
| 2115 | 2115 | return ret; |
| 2116 | 2116 | |
| 2117 | − ret = cache_tag_assign_domain(domain, dev, IOMMU_NO_PASID); | |
| 2118 | − if (ret) { | |
| 2119 | − domain_detach_iommu(domain, iommu); | |
| 2120 | − return ret; | |
| 2121 | − } | |
| 2122 | − | |
| 2123 | 2117 | info->domain = domain; |
| 2124 | 2118 | spin_lock_irqsave(&domain->lock, flags); |
| 2125 | 2119 | list_add(&info->link, &domain->devices); |
| @@ -2137,15 +2131,21 @@ static int dmar_domain_attach_device(struct dmar_domain *domain, · 11 unmodified lines | ||
| 2137 | 2131 | else |
| 2138 | 2132 | ret = intel_pasid_setup_second_level(iommu, domain, dev, IOMMU_NO_PASID); |
| 2139 | 2133 | |
| 2140 | − if (ret) { | |
| 2141 | − device_block_translation(dev); | |
| 2142 | − return ret; | |
| 2143 | − } | |
| 2134 | + if (ret) | |
| 2135 | + goto out_block_translation; | |
| 2144 | 2136 | |
| 2145 | 2137 | if (sm_supported(info->iommu) || !domain_type_is_si(info->domain)) |
| 2146 | 2138 | iommu_enable_pci_caps(info); |
| 2147 | 2139 | |
| 2140 | + ret = cache_tag_assign_domain(domain, dev, IOMMU_NO_PASID); | |
| 2141 | + if (ret) | |
| 2142 | + goto out_block_translation; | |
| 2143 | + | |
| 2148 | 2144 | return 0; |
| 2145 | + | |
| 2146 | +out_block_translation: | |
| 2147 | + device_block_translation(dev); | |
| 2148 | + return ret; | |
| 2149 | 2149 | } |
| 2150 | 2150 | |
| 2151 | 2151 | /** |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/irqchip/chained_irq.h> |
| 16 | 16 | #include <linux/kernel.h> |
| 17 | 17 | #include <linux/syscore_ops.h> |
| 18 | +#include <asm/numa.h> | |
| 18 | 19 | |
| 19 | 20 | #define EIOINTC_REG_NODEMAP 0x14a0 |
| 20 | 21 | #define EIOINTC_REG_IPMAP 0x14c0 |
| @@ -339,7 +340,7 @@ static int __init pch_msi_parse_madt(union acpi_subtable_headers *header, · 318 unmodified lines | ||
| 339 | 340 | int node; |
| 340 | 341 | |
| 341 | 342 | if (cpu_has_flatmode) |
| 342 | − node = cpu_to_node(eiointc_priv[nr_pics - 1]->node * CORES_PER_EIO_NODE); | |
| 343 | + node = early_cpu_to_node(eiointc_priv[nr_pics - 1]->node * CORES_PER_EIO_NODE); | |
| 343 | 344 | else |
| 344 | 345 | node = eiointc_priv[nr_pics - 1]->node; |
| 345 | 346 | |
| @@ -431,7 +432,7 @@ int __init eiointc_acpi_init(struct irq_domain *parent, · 85 unmodified lines | ||
| 431 | 432 | goto out_free_handle; |
| 432 | 433 | |
| 433 | 434 | if (cpu_has_flatmode) |
| 434 | − node = cpu_to_node(acpi_eiointc->node * CORES_PER_EIO_NODE); | |
| 435 | + node = early_cpu_to_node(acpi_eiointc->node * CORES_PER_EIO_NODE); | |
| 435 | 436 | else |
| 436 | 437 | node = acpi_eiointc->node; |
| 437 | 438 | acpi_set_vec_parent(node, priv->eiointc_domain, pch_group); |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #define LIOINTC_INTC_CHIP_START 0x20 |
| 30 | 30 | |
| 31 | −#define LIOINTC_REG_INTC_STATUS (LIOINTC_INTC_CHIP_START + 0x20) | |
| 31 | +#define LIOINTC_REG_INTC_STATUS(core) (LIOINTC_INTC_CHIP_START + 0x20 + (core) * 8) | |
| 32 | 32 | #define LIOINTC_REG_INTC_EN_STATUS (LIOINTC_INTC_CHIP_START + 0x04) |
| 33 | 33 | #define LIOINTC_REG_INTC_ENABLE (LIOINTC_INTC_CHIP_START + 0x08) |
| 34 | 34 | #define LIOINTC_REG_INTC_DISABLE (LIOINTC_INTC_CHIP_START + 0x0c) |
| @@ -217,7 +217,7 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision, · 182 unmodified lines | ||
| 217 | 217 | goto out_free_priv; |
| 218 | 218 | |
| 219 | 219 | for (i = 0; i < LIOINTC_NUM_CORES; i++) |
| 220 | − priv->core_isr[i] = base + LIOINTC_REG_INTC_STATUS; | |
| 220 | + priv->core_isr[i] = base + LIOINTC_REG_INTC_STATUS(i); | |
| 221 | 221 | |
| 222 | 222 | for (i = 0; i < LIOINTC_NUM_PARENT; i++) |
| 223 | 223 | priv->handler[i].parent_int_map = parent_int_map[i]; |
| @@ -943,7 +943,7 @@ ipu6_isys_query_stream_by_source(struct ipu6_isys *isys, int source, u8 vc) · 942 unmodified lines | ||
| 943 | 943 | return NULL; |
| 944 | 944 | |
| 945 | 945 | if (source < 0) { |
| 946 | − dev_err(&stream->isys->adev->auxdev.dev, | |
| 946 | + dev_err(&isys->adev->auxdev.dev, | |
| 947 | 947 | "query stream with invalid port number\n"); |
| 948 | 948 | return NULL; |
| 949 | 949 | } |
| @@ -799,7 +799,7 @@ static int isys_register_devices(struct ipu6_isys *isys) · 798 unmodified lines | ||
| 799 | 799 | isys->v4l2_dev.mdev = &isys->media_dev; |
| 800 | 800 | isys->v4l2_dev.ctrl_handler = NULL; |
| 801 | 801 | |
| 802 | − ret = v4l2_device_register(&pdev->dev, &isys->v4l2_dev); | |
| 802 | + ret = v4l2_device_register(dev, &isys->v4l2_dev); | |
| 803 | 803 | if (ret < 0) |
| 804 | 804 | goto out_media_device_unregister; |
| 805 | 805 | |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | config INTEL_VSC |
| 5 | 5 | tristate "Intel Visual Sensing Controller" |
| 6 | 6 | depends on INTEL_MEI && ACPI && VIDEO_DEV |
| 7 | + depends on IPU_BRIDGE || !IPU_BRIDGE | |
| 7 | 8 | select MEDIA_CONTROLLER |
| 8 | 9 | select VIDEO_V4L2_SUBDEV_API |
| 9 | 10 | select V4L2_FWNODE |
| @@ -131,10 +131,12 @@ struct moxart_host { · 130 unmodified lines | ||
| 131 | 131 | struct dma_async_tx_descriptor *tx_desc; |
| 132 | 132 | struct mmc_host *mmc; |
| 133 | 133 | struct mmc_request *mrq; |
| 134 | + struct scatterlist *cur_sg; | |
| 134 | 135 | struct completion dma_complete; |
| 135 | 136 | struct completion pio_complete; |
| 136 | 137 | |
| 137 | − struct sg_mapping_iter sg_miter; | |
| 138 | + u32 num_sg; | |
| 139 | + u32 data_remain; | |
| 138 | 140 | u32 data_len; |
| 139 | 141 | u32 fifo_width; |
| 140 | 142 | u32 timeout; |
| @@ -146,6 +148,35 @@ struct moxart_host { · 5 unmodified lines | ||
| 146 | 148 | bool is_removed; |
| 147 | 149 | }; |
| 148 | 150 | |
| 151 | +static inline void moxart_init_sg(struct moxart_host *host, | |
| 152 | + struct mmc_data *data) | |
| 153 | +{ | |
| 154 | + host->cur_sg = data->sg; | |
| 155 | + host->num_sg = data->sg_len; | |
| 156 | + host->data_remain = host->cur_sg->length; | |
| 157 | + | |
| 158 | + if (host->data_remain > host->data_len) | |
| 159 | + host->data_remain = host->data_len; | |
| 160 | +} | |
| 161 | + | |
| 162 | +static inline int moxart_next_sg(struct moxart_host *host) | |
| 163 | +{ | |
| 164 | + int remain; | |
| 165 | + struct mmc_data *data = host->mrq->cmd->data; | |
| 166 | + | |
| 167 | + host->cur_sg++; | |
| 168 | + host->num_sg--; | |
| 169 | + | |
| 170 | + if (host->num_sg > 0) { | |
| 171 | + host->data_remain = host->cur_sg->length; | |
| 172 | + remain = host->data_len - data->bytes_xfered; | |
| 173 | + if (remain > 0 && remain < host->data_remain) | |
| 174 | + host->data_remain = remain; | |
| 175 | + } | |
| 176 | + | |
| 177 | + return host->num_sg; | |
| 178 | +} | |
| 179 | + | |
| 149 | 180 | static int moxart_wait_for_status(struct moxart_host *host, |
| 150 | 181 | u32 mask, u32 *status) |
| 151 | 182 | { |
| @@ -278,29 +309,14 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host) · 126 unmodified lines | ||
| 278 | 309 | |
| 279 | 310 | static void moxart_transfer_pio(struct moxart_host *host) |
| 280 | 311 | { |
| 281 | − struct sg_mapping_iter *sgm = &host->sg_miter; | |
| 282 | 312 | struct mmc_data *data = host->mrq->cmd->data; |
| 283 | 313 | u32 *sgp, len = 0, remain, status; |
| 284 | 314 | |
| 285 | 315 | if (host->data_len == data->bytes_xfered) |
| 286 | 316 | return; |
| 287 | 317 | |
| 288 | − /* | |
| 289 | − * By updating sgm->consumes this will get a proper pointer into the | |
| 290 | − * buffer at any time. | |
| 291 | − */ | |
| 292 | − if (!sg_miter_next(sgm)) { | |
| 293 | − /* This shold not happen */ | |
| 294 | − dev_err(mmc_dev(host->mmc), "ran out of scatterlist prematurely\n"); | |
| 295 | − data->error = -EINVAL; | |
| 296 | − complete(&host->pio_complete); | |
| 297 | − return; | |
| 298 | − } | |
| 299 | − sgp = sgm->addr; | |
| 300 | − remain = sgm->length; | |
| 301 | − if (remain > host->data_len) | |
| 302 | − remain = host->data_len; | |
| 303 | − sgm->consumed = 0; | |
| 318 | + sgp = sg_virt(host->cur_sg); | |
| 319 | + remain = host->data_remain; | |
| 304 | 320 | |
| 305 | 321 | if (data->flags & MMC_DATA_WRITE) { |
| 306 | 322 | while (remain > 0) { |
| @@ -315,7 +331,6 @@ static void moxart_transfer_pio(struct moxart_host *host) · 8 unmodified lines | ||
| 315 | 331 | sgp++; |
| 316 | 332 | len += 4; |
| 317 | 333 | } |
| 318 | − sgm->consumed += len; | |
| 319 | 334 | remain -= len; |
| 320 | 335 | } |
| 321 | 336 | |
| @@ -332,22 +347,22 @@ static void moxart_transfer_pio(struct moxart_host *host) · 10 unmodified lines | ||
| 332 | 347 | sgp++; |
| 333 | 348 | len += 4; |
| 334 | 349 | } |
| 335 | − sgm->consumed += len; | |
| 336 | 350 | remain -= len; |
| 337 | 351 | } |
| 338 | 352 | } |
| 339 | 353 | |
| 340 | − data->bytes_xfered += sgm->consumed; | |
| 341 | − if (host->data_len == data->bytes_xfered) { | |
| 354 | + data->bytes_xfered += host->data_remain - remain; | |
| 355 | + host->data_remain = remain; | |
| 356 | + | |
| 357 | + if (host->data_len != data->bytes_xfered) | |
| 358 | + moxart_next_sg(host); | |
| 359 | + else | |
| 342 | 360 | complete(&host->pio_complete); |
| 343 | − return; | |
| 344 | − } | |
| 345 | 361 | } |
| 346 | 362 | |
| 347 | 363 | static void moxart_prepare_data(struct moxart_host *host) |
| 348 | 364 | { |
| 349 | 365 | struct mmc_data *data = host->mrq->cmd->data; |
| 350 | − unsigned int flags = SG_MITER_ATOMIC; /* Used from IRQ */ | |
| 351 | 366 | u32 datactrl; |
| 352 | 367 | int blksz_bits; |
| 353 | 368 | |
| @@ -358,19 +373,15 @@ static void moxart_prepare_data(struct moxart_host *host) · 4 unmodified lines | ||
| 358 | 373 | blksz_bits = ffs(data->blksz) - 1; |
| 359 | 374 | BUG_ON(1 << blksz_bits != data->blksz); |
| 360 | 375 | |
| 376 | + moxart_init_sg(host, data); | |
| 377 | + | |
| 361 | 378 | datactrl = DCR_DATA_EN | (blksz_bits & DCR_BLK_SIZE); |
| 362 | 379 | |
| 363 | − if (data->flags & MMC_DATA_WRITE) { | |
| 364 | − flags |= SG_MITER_FROM_SG; | |
| 380 | + if (data->flags & MMC_DATA_WRITE) | |
| 365 | 381 | datactrl |= DCR_DATA_WRITE; |
| 366 | − } else { | |
| 367 | − flags |= SG_MITER_TO_SG; | |
| 368 | − } | |
| 369 | 382 | |
| 370 | 383 | if (moxart_use_dma(host)) |
| 371 | 384 | datactrl |= DCR_DMA_EN; |
| 372 | − else | |
| 373 | − sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); | |
| 374 | 385 | |
| 375 | 386 | writel(DCR_DATA_FIFO_RESET, host->base + REG_DATA_CONTROL); |
| 376 | 387 | writel(MASK_DATA | FIFO_URUN | FIFO_ORUN, host->base + REG_CLEAR); |
| @@ -443,9 +454,6 @@ static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq) · 66 unmodified lines | ||
| 443 | 454 | } |
| 444 | 455 | |
| 445 | 456 | request_done: |
| 446 | − if (!moxart_use_dma(host)) | |
| 447 | − sg_miter_stop(&host->sg_miter); | |
| 448 | − | |
| 449 | 457 | spin_unlock_irqrestore(&host->lock, flags); |
| 450 | 458 | mmc_request_done(host->mmc, mrq); |
| 451 | 459 | } |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #define BRCMSTB_MATCH_FLAGS_NO_64BIT BIT(0) |
| 25 | 25 | #define BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT BIT(1) |
| 26 | 26 | #define BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE BIT(2) |
| 27 | +#define BRCMSTB_MATCH_FLAGS_USE_CARD_BUSY BIT(4) | |
| 27 | 28 | |
| 28 | 29 | #define BRCMSTB_PRIV_FLAGS_HAS_CQE BIT(0) |
| 29 | 30 | #define BRCMSTB_PRIV_FLAGS_GATE_CLOCK BIT(1) |
| @@ -384,6 +385,9 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) · 354 unmodified lines | ||
| 384 | 385 | if (match_priv->flags & BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT) |
| 385 | 386 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; |
| 386 | 387 | |
| 388 | + if (!(match_priv->flags & BRCMSTB_MATCH_FLAGS_USE_CARD_BUSY)) | |
| 389 | + host->mmc_host_ops.card_busy = NULL; | |
| 390 | + | |
| 387 | 391 | /* Change the base clock frequency if the DT property exists */ |
| 388 | 392 | if (device_property_read_u32(&pdev->dev, "clock-frequency", |
| 389 | 393 | &priv->base_freq_hz) != 0) |
| @@ -1326,7 +1326,7 @@ static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) · 1325 unmodified lines | ||
| 1326 | 1326 | |
| 1327 | 1327 | ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); |
| 1328 | 1328 | if (ret) |
| 1329 | − return ret; | |
| 1329 | + goto fail; | |
| 1330 | 1330 | |
| 1331 | 1331 | /* |
| 1332 | 1332 | * Turn PMOS on [bit 0], set over current detection to 2.4 V |
| @@ -1337,7 +1337,10 @@ static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) · 4 unmodified lines | ||
| 1337 | 1337 | else |
| 1338 | 1338 | scratch &= ~0x47; |
| 1339 | 1339 | |
| 1340 | − return pci_write_config_byte(chip->pdev, 0xAE, scratch); | |
| 1340 | + ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); | |
| 1341 | + | |
| 1342 | +fail: | |
| 1343 | + return pcibios_err_to_errno(ret); | |
| 1341 | 1344 | } |
| 1342 | 1345 | |
| 1343 | 1346 | static int jmicron_probe(struct sdhci_pci_chip *chip) |
| @@ -2202,7 +2205,7 @@ static int sdhci_pci_probe(struct pci_dev *pdev, · 858 unmodified lines | ||
| 2202 | 2205 | |
| 2203 | 2206 | ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); |
| 2204 | 2207 | if (ret) |
| 2205 | − return ret; | |
| 2208 | + return pcibios_err_to_errno(ret); | |
| 2206 | 2209 | |
| 2207 | 2210 | slots = PCI_SLOT_INFO_SLOTS(slots) + 1; |
| 2208 | 2211 | dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); |
| @@ -2211,7 +2214,7 @@ static int sdhci_pci_probe(struct pci_dev *pdev, · 2 unmodified lines | ||
| 2211 | 2214 | |
| 2212 | 2215 | ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); |
| 2213 | 2216 | if (ret) |
| 2214 | − return ret; | |
| 2217 | + return pcibios_err_to_errno(ret); | |
| 2215 | 2218 | |
| 2216 | 2219 | first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; |
| 2217 | 2220 | |
| @@ -823,7 +823,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 822 unmodified lines | ||
| 823 | 823 | ret = pci_read_config_byte(chip->pdev, |
| 824 | 824 | O2_SD_LOCK_WP, &scratch); |
| 825 | 825 | if (ret) |
| 826 | − return ret; | |
| 826 | + goto read_fail; | |
| 827 | 827 | scratch &= 0x7f; |
| 828 | 828 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| 829 | 829 | |
| @@ -834,7 +834,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 4 unmodified lines | ||
| 834 | 834 | ret = pci_read_config_byte(chip->pdev, |
| 835 | 835 | O2_SD_CLKREQ, &scratch); |
| 836 | 836 | if (ret) |
| 837 | − return ret; | |
| 837 | + goto read_fail; | |
| 838 | 838 | scratch |= 0x20; |
| 839 | 839 | pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch); |
| 840 | 840 | |
| @@ -843,7 +843,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 2 unmodified lines | ||
| 843 | 843 | */ |
| 844 | 844 | ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch); |
| 845 | 845 | if (ret) |
| 846 | − return ret; | |
| 846 | + goto read_fail; | |
| 847 | 847 | scratch |= 0x01; |
| 848 | 848 | pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch); |
| 849 | 849 | pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73); |
| @@ -856,7 +856,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 6 unmodified lines | ||
| 856 | 856 | ret = pci_read_config_byte(chip->pdev, |
| 857 | 857 | O2_SD_INF_MOD, &scratch); |
| 858 | 858 | if (ret) |
| 859 | − return ret; | |
| 859 | + goto read_fail; | |
| 860 | 860 | scratch |= 0x08; |
| 861 | 861 | pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch); |
| 862 | 862 | |
| @@ -864,7 +864,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 1 unmodified line | ||
| 864 | 864 | ret = pci_read_config_byte(chip->pdev, |
| 865 | 865 | O2_SD_LOCK_WP, &scratch); |
| 866 | 866 | if (ret) |
| 867 | − return ret; | |
| 867 | + goto read_fail; | |
| 868 | 868 | scratch |= 0x80; |
| 869 | 869 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| 870 | 870 | break; |
| @@ -875,7 +875,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 4 unmodified lines | ||
| 875 | 875 | ret = pci_read_config_byte(chip->pdev, |
| 876 | 876 | O2_SD_LOCK_WP, &scratch); |
| 877 | 877 | if (ret) |
| 878 | − return ret; | |
| 878 | + goto read_fail; | |
| 879 | 879 | |
| 880 | 880 | scratch &= 0x7f; |
| 881 | 881 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| @@ -886,7 +886,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 4 unmodified lines | ||
| 886 | 886 | O2_SD_FUNC_REG0, |
| 887 | 887 | &scratch_32); |
| 888 | 888 | if (ret) |
| 889 | − return ret; | |
| 889 | + goto read_fail; | |
| 890 | 890 | scratch_32 = ((scratch_32 & 0xFF000000) >> 24); |
| 891 | 891 | |
| 892 | 892 | /* Check Whether subId is 0x11 or 0x12 */ |
| @@ -898,7 +898,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 5 unmodified lines | ||
| 898 | 898 | O2_SD_FUNC_REG4, |
| 899 | 899 | &scratch_32); |
| 900 | 900 | if (ret) |
| 901 | − return ret; | |
| 901 | + goto read_fail; | |
| 902 | 902 | |
| 903 | 903 | /* Enable Base Clk setting change */ |
| 904 | 904 | scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET; |
| @@ -921,7 +921,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 16 unmodified lines | ||
| 921 | 921 | ret = pci_read_config_dword(chip->pdev, |
| 922 | 922 | O2_SD_CLK_SETTING, &scratch_32); |
| 923 | 923 | if (ret) |
| 924 | − return ret; | |
| 924 | + goto read_fail; | |
| 925 | 925 | |
| 926 | 926 | scratch_32 &= ~(0xFF00); |
| 927 | 927 | scratch_32 |= 0x07E0C800; |
| @@ -931,14 +931,14 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 3 unmodified lines | ||
| 931 | 931 | ret = pci_read_config_dword(chip->pdev, |
| 932 | 932 | O2_SD_CLKREQ, &scratch_32); |
| 933 | 933 | if (ret) |
| 934 | − return ret; | |
| 934 | + goto read_fail; | |
| 935 | 935 | scratch_32 |= 0x3; |
| 936 | 936 | pci_write_config_dword(chip->pdev, O2_SD_CLKREQ, scratch_32); |
| 937 | 937 | |
| 938 | 938 | ret = pci_read_config_dword(chip->pdev, |
| 939 | 939 | O2_SD_PLL_SETTING, &scratch_32); |
| 940 | 940 | if (ret) |
| 941 | − return ret; | |
| 941 | + goto read_fail; | |
| 942 | 942 | |
| 943 | 943 | scratch_32 &= ~(0x1F3F070E); |
| 944 | 944 | scratch_32 |= 0x18270106; |
| @@ -949,7 +949,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 4 unmodified lines | ||
| 949 | 949 | ret = pci_read_config_dword(chip->pdev, |
| 950 | 950 | O2_SD_CAP_REG2, &scratch_32); |
| 951 | 951 | if (ret) |
| 952 | − return ret; | |
| 952 | + goto read_fail; | |
| 953 | 953 | scratch_32 &= ~(0xE0); |
| 954 | 954 | pci_write_config_dword(chip->pdev, |
| 955 | 955 | O2_SD_CAP_REG2, scratch_32); |
| @@ -961,7 +961,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 5 unmodified lines | ||
| 961 | 961 | ret = pci_read_config_byte(chip->pdev, |
| 962 | 962 | O2_SD_LOCK_WP, &scratch); |
| 963 | 963 | if (ret) |
| 964 | − return ret; | |
| 964 | + goto read_fail; | |
| 965 | 965 | scratch |= 0x80; |
| 966 | 966 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| 967 | 967 | break; |
| @@ -971,7 +971,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 3 unmodified lines | ||
| 971 | 971 | ret = pci_read_config_byte(chip->pdev, |
| 972 | 972 | O2_SD_LOCK_WP, &scratch); |
| 973 | 973 | if (ret) |
| 974 | − return ret; | |
| 974 | + goto read_fail; | |
| 975 | 975 | |
| 976 | 976 | scratch &= 0x7f; |
| 977 | 977 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| @@ -979,7 +979,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 1 unmodified line | ||
| 979 | 979 | ret = pci_read_config_dword(chip->pdev, |
| 980 | 980 | O2_SD_PLL_SETTING, &scratch_32); |
| 981 | 981 | if (ret) |
| 982 | − return ret; | |
| 982 | + goto read_fail; | |
| 983 | 983 | |
| 984 | 984 | if ((scratch_32 & 0xff000000) == 0x01000000) { |
| 985 | 985 | scratch_32 &= 0x0000FFFF; |
| @@ -998,7 +998,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 12 unmodified lines | ||
| 998 | 998 | O2_SD_FUNC_REG4, |
| 999 | 999 | &scratch_32); |
| 1000 | 1000 | if (ret) |
| 1001 | − return ret; | |
| 1001 | + goto read_fail; | |
| 1002 | 1002 | scratch_32 |= (1 << 22); |
| 1003 | 1003 | pci_write_config_dword(chip->pdev, |
| 1004 | 1004 | O2_SD_FUNC_REG4, scratch_32); |
| @@ -1017,7 +1017,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 12 unmodified lines | ||
| 1017 | 1017 | ret = pci_read_config_byte(chip->pdev, |
| 1018 | 1018 | O2_SD_LOCK_WP, &scratch); |
| 1019 | 1019 | if (ret) |
| 1020 | − return ret; | |
| 1020 | + goto read_fail; | |
| 1021 | 1021 | scratch |= 0x80; |
| 1022 | 1022 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| 1023 | 1023 | break; |
| @@ -1028,7 +1028,7 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 4 unmodified lines | ||
| 1028 | 1028 | /* UnLock WP */ |
| 1029 | 1029 | ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); |
| 1030 | 1030 | if (ret) |
| 1031 | − return ret; | |
| 1031 | + goto read_fail; | |
| 1032 | 1032 | scratch &= 0x7f; |
| 1033 | 1033 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| 1034 | 1034 | |
| @@ -1057,13 +1057,16 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 22 unmodified lines | ||
| 1057 | 1057 | /* Lock WP */ |
| 1058 | 1058 | ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); |
| 1059 | 1059 | if (ret) |
| 1060 | − return ret; | |
| 1060 | + goto read_fail; | |
| 1061 | 1061 | scratch |= 0x80; |
| 1062 | 1062 | pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); |
| 1063 | 1063 | break; |
| 1064 | 1064 | } |
| 1065 | 1065 | |
| 1066 | 1066 | return 0; |
| 1067 | + | |
| 1068 | +read_fail: | |
| 1069 | + return pcibios_err_to_errno(ret); | |
| 1067 | 1070 | } |
| 1068 | 1071 | |
| 1069 | 1072 | #ifdef CONFIG_PM_SLEEP |
| @@ -2515,26 +2515,29 @@ EXPORT_SYMBOL_GPL(sdhci_get_cd_nogpio); · 2514 unmodified lines | ||
| 2515 | 2515 | |
| 2516 | 2516 | static int sdhci_check_ro(struct sdhci_host *host) |
| 2517 | 2517 | { |
| 2518 | − unsigned long flags; | |
| 2518 | + bool allow_invert = false; | |
| 2519 | 2519 | int is_readonly; |
| 2520 | 2520 | |
| 2521 | − spin_lock_irqsave(&host->lock, flags); | |
| 2522 | − | |
| 2523 | − if (host->flags & SDHCI_DEVICE_DEAD) | |
| 2521 | + if (host->flags & SDHCI_DEVICE_DEAD) { | |
| 2524 | 2522 | is_readonly = 0; |
| 2525 | − else if (host->ops->get_ro) | |
| 2523 | + } else if (host->ops->get_ro) { | |
| 2526 | 2524 | is_readonly = host->ops->get_ro(host); |
| 2527 | − else if (mmc_can_gpio_ro(host->mmc)) | |
| 2525 | + } else if (mmc_can_gpio_ro(host->mmc)) { | |
| 2528 | 2526 | is_readonly = mmc_gpio_get_ro(host->mmc); |
| 2529 | − else | |
| 2527 | + /* Do not invert twice */ | |
| 2528 | + allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); | |
| 2529 | + } else { | |
| 2530 | 2530 | is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) |
| 2531 | 2531 | & SDHCI_WRITE_PROTECT); |
| 2532 | + allow_invert = true; | |
| 2533 | + } | |
| 2532 | 2534 | |
| 2533 | − spin_unlock_irqrestore(&host->lock, flags); | |
| 2535 | + if (is_readonly >= 0 && | |
| 2536 | + allow_invert && | |
| 2537 | + (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) | |
| 2538 | + is_readonly = !is_readonly; | |
| 2534 | 2539 | |
| 2535 | − /* This quirk needs to be replaced by a callback-function later */ | |
| 2536 | − return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? | |
| 2537 | − !is_readonly : is_readonly; | |
| 2540 | + return is_readonly; | |
| 2538 | 2541 | } |
| 2539 | 2542 | |
| 2540 | 2543 | #define SAMPLE_COUNT 5 |
| @@ -1093,28 +1093,32 @@ static int nand_fill_column_cycles(struct nand_chip *chip, u8 *addrs, · 1092 unmodified lines | ||
| 1093 | 1093 | unsigned int offset_in_page) |
| 1094 | 1094 | { |
| 1095 | 1095 | struct mtd_info *mtd = nand_to_mtd(chip); |
| 1096 | + bool ident_stage = !mtd->writesize; | |
| 1096 | 1097 | |
| 1097 | − /* Make sure the offset is less than the actual page size. */ | |
| 1098 | − if (offset_in_page > mtd->writesize + mtd->oobsize) | |
| 1099 | − return -EINVAL; | |
| 1098 | + /* Bypass all checks during NAND identification */ | |
| 1099 | + if (likely(!ident_stage)) { | |
| 1100 | + /* Make sure the offset is less than the actual page size. */ | |
| 1101 | + if (offset_in_page > mtd->writesize + mtd->oobsize) | |
| 1102 | + return -EINVAL; | |
| 1100 | 1103 | |
| 1101 | − /* | |
| 1102 | − * On small page NANDs, there's a dedicated command to access the OOB | |
| 1103 | − * area, and the column address is relative to the start of the OOB | |
| 1104 | − * area, not the start of the page. Asjust the address accordingly. | |
| 1105 | − */ | |
| 1106 | − if (mtd->writesize <= 512 && offset_in_page >= mtd->writesize) | |
| 1107 | − offset_in_page -= mtd->writesize; | |
| 1104 | + /* | |
| 1105 | + * On small page NANDs, there's a dedicated command to access the OOB | |
| 1106 | + * area, and the column address is relative to the start of the OOB | |
| 1107 | + * area, not the start of the page. Asjust the address accordingly. | |
| 1108 | + */ | |
| 1109 | + if (mtd->writesize <= 512 && offset_in_page >= mtd->writesize) | |
| 1110 | + offset_in_page -= mtd->writesize; | |
| 1108 | 1111 | |
| 1109 | − /* | |
| 1110 | − * The offset in page is expressed in bytes, if the NAND bus is 16-bit | |
| 1111 | − * wide, then it must be divided by 2. | |
| 1112 | − */ | |
| 1113 | − if (chip->options & NAND_BUSWIDTH_16) { | |
| 1114 | − if (WARN_ON(offset_in_page % 2)) | |
| 1115 | − return -EINVAL; | |
| 1112 | + /* | |
| 1113 | + * The offset in page is expressed in bytes, if the NAND bus is 16-bit | |
| 1114 | + * wide, then it must be divided by 2. | |
| 1115 | + */ | |
| 1116 | + if (chip->options & NAND_BUSWIDTH_16) { | |
| 1117 | + if (WARN_ON(offset_in_page % 2)) | |
| 1118 | + return -EINVAL; | |
| 1116 | 1119 | |
| 1117 | − offset_in_page /= 2; | |
| 1120 | + offset_in_page /= 2; | |
| 1121 | + } | |
| 1118 | 1122 | } |
| 1119 | 1123 | |
| 1120 | 1124 | addrs[0] = offset_in_page; |
| @@ -1123,7 +1127,7 @@ static int nand_fill_column_cycles(struct nand_chip *chip, u8 *addrs, · 2 unmodified lines | ||
| 1123 | 1127 | * Small page NANDs use 1 cycle for the columns, while large page NANDs |
| 1124 | 1128 | * need 2 |
| 1125 | 1129 | */ |
| 1126 | − if (mtd->writesize <= 512) | |
| 1130 | + if (!ident_stage && mtd->writesize <= 512) | |
| 1127 | 1131 | return 1; |
| 1128 | 1132 | |
| 1129 | 1133 | addrs[1] = offset_in_page >> 8; |
| @@ -1436,16 +1440,19 @@ int nand_change_read_column_op(struct nand_chip *chip, · 306 unmodified lines | ||
| 1436 | 1440 | unsigned int len, bool force_8bit) |
| 1437 | 1441 | { |
| 1438 | 1442 | struct mtd_info *mtd = nand_to_mtd(chip); |
| 1443 | + bool ident_stage = !mtd->writesize; | |
| 1439 | 1444 | |
| 1440 | 1445 | if (len && !buf) |
| 1441 | 1446 | return -EINVAL; |
| 1442 | 1447 | |
| 1443 | − if (offset_in_page + len > mtd->writesize + mtd->oobsize) | |
| 1444 | − return -EINVAL; | |
| 1448 | + if (!ident_stage) { | |
| 1449 | + if (offset_in_page + len > mtd->writesize + mtd->oobsize) | |
| 1450 | + return -EINVAL; | |
| 1445 | 1451 | |
| 1446 | − /* Small page NANDs do not support column change. */ | |
| 1447 | − if (mtd->writesize <= 512) | |
| 1448 | − return -ENOTSUPP; | |
| 1452 | + /* Small page NANDs do not support column change. */ | |
| 1453 | + if (mtd->writesize <= 512) | |
| 1454 | + return -ENOTSUPP; | |
| 1455 | + } | |
| 1449 | 1456 | |
| 1450 | 1457 | if (nand_has_exec_op(chip)) { |
| 1451 | 1458 | const struct nand_interface_config *conf = |
| @@ -2173,7 +2180,7 @@ EXPORT_SYMBOL_GPL(nand_reset_op); · 721 unmodified lines | ||
| 2173 | 2180 | int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, |
| 2174 | 2181 | bool force_8bit, bool check_only) |
| 2175 | 2182 | { |
| 2176 | − if (!len || !buf) | |
| 2183 | + if (!len || (!check_only && !buf)) | |
| 2177 | 2184 | return -EINVAL; |
| 2178 | 2185 | |
| 2179 | 2186 | if (nand_has_exec_op(chip)) { |
| @@ -6301,6 +6308,7 @@ static const struct nand_ops rawnand_ops = { · 4121 unmodified lines | ||
| 6301 | 6308 | static int nand_scan_tail(struct nand_chip *chip) |
| 6302 | 6309 | { |
| 6303 | 6310 | struct mtd_info *mtd = nand_to_mtd(chip); |
| 6311 | + struct nand_device *base = &chip->base; | |
| 6304 | 6312 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
| 6305 | 6313 | int ret, i; |
| 6306 | 6314 | |
| @@ -6445,9 +6453,13 @@ static int nand_scan_tail(struct nand_chip *chip) · 138 unmodified lines | ||
| 6445 | 6453 | if (!ecc->write_oob_raw) |
| 6446 | 6454 | ecc->write_oob_raw = ecc->write_oob; |
| 6447 | 6455 | |
| 6448 | − /* propagate ecc info to mtd_info */ | |
| 6456 | + /* Propagate ECC info to the generic NAND and MTD layers */ | |
| 6449 | 6457 | mtd->ecc_strength = ecc->strength; |
| 6458 | + if (!base->ecc.ctx.conf.strength) | |
| 6459 | + base->ecc.ctx.conf.strength = ecc->strength; | |
| 6450 | 6460 | mtd->ecc_step_size = ecc->size; |
| 6461 | + if (!base->ecc.ctx.conf.step_size) | |
| 6462 | + base->ecc.ctx.conf.step_size = ecc->size; | |
| 6451 | 6463 | |
| 6452 | 6464 | /* |
| 6453 | 6465 | * Set the number of read / write steps for one page depending on ECC |
| @@ -6455,6 +6467,8 @@ static int nand_scan_tail(struct nand_chip *chip) · 1 unmodified line | ||
| 6455 | 6467 | */ |
| 6456 | 6468 | if (!ecc->steps) |
| 6457 | 6469 | ecc->steps = mtd->writesize / ecc->size; |
| 6470 | + if (!base->ecc.ctx.nsteps) | |
| 6471 | + base->ecc.ctx.nsteps = ecc->steps; | |
| 6458 | 6472 | if (ecc->steps * ecc->size != mtd->writesize) { |
| 6459 | 6473 | WARN(1, "Invalid ECC parameters\n"); |
| 6460 | 6474 | ret = -EINVAL; |
| @@ -420,13 +420,13 @@ static int rk_nfc_setup_interface(struct nand_chip *chip, int target, · 419 unmodified lines | ||
| 420 | 420 | u32 rate, tc2rw, trwpw, trw2c; |
| 421 | 421 | u32 temp; |
| 422 | 422 | |
| 423 | − if (target < 0) | |
| 424 | − return 0; | |
| 425 | − | |
| 426 | 423 | timings = nand_get_sdr_timings(conf); |
| 427 | 424 | if (IS_ERR(timings)) |
| 428 | 425 | return -EOPNOTSUPP; |
| 429 | 426 | |
| 427 | + if (target < 0) | |
| 428 | + return 0; | |
| 429 | + | |
| 430 | 430 | if (IS_ERR(nfc->nfc_clk)) |
| 431 | 431 | rate = clk_get_rate(nfc->ahb_clk); |
| 432 | 432 | else |
| @@ -1214,9 +1214,9 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond, · 1213 unmodified lines | ||
| 1214 | 1214 | __be32 target; |
| 1215 | 1215 | |
| 1216 | 1216 | if (newval->string) { |
| 1217 | − if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) { | |
| 1218 | − netdev_err(bond->dev, "invalid ARP target %pI4 specified\n", | |
| 1219 | − &target); | |
| 1217 | + if (strlen(newval->string) < 1 || | |
| 1218 | + !in4_pton(newval->string + 1, -1, (u8 *)&target, -1, NULL)) { | |
| 1219 | + netdev_err(bond->dev, "invalid ARP target specified\n"); | |
| 1220 | 1220 | return ret; |
| 1221 | 1221 | } |
| 1222 | 1222 | if (newval->string[0] == '+') |
| @@ -128,6 +128,7 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_liste · 127 unmodified lines | ||
| 128 | 128 | |
| 129 | 129 | static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = { |
| 130 | 130 | .quirks = 0, |
| 131 | + .family = KVASER_LEAF, | |
| 131 | 132 | .ops = &kvaser_usb_leaf_dev_ops, |
| 132 | 133 | }; |
| 133 | 134 | |
| @@ -1262,7 +1262,7 @@ enum { · 1261 unmodified lines | ||
| 1262 | 1262 | |
| 1263 | 1263 | struct bnx2x_fw_stats_req { |
| 1264 | 1264 | struct stats_query_header hdr; |
| 1265 | − struct stats_query_entry query[FP_SB_MAX_E1x+ | |
| 1265 | + struct stats_query_entry query[FP_SB_MAX_E2 + | |
| 1266 | 1266 | BNX2X_FIRST_QUEUE_QUERY_IDX]; |
| 1267 | 1267 | }; |
| 1268 | 1268 | |
| @@ -12851,7 +12851,11 @@ bool bnxt_rfs_capable(struct bnxt *bp, bool new_rss_ctx) · 12850 unmodified lines | ||
| 12851 | 12851 | if (!BNXT_NEW_RM(bp)) |
| 12852 | 12852 | return true; |
| 12853 | 12853 | |
| 12854 | − if (hwr.vnic == bp->hw_resc.resv_vnics && | |
| 12854 | + /* Do not reduce VNIC and RSS ctx reservations. There is a FW | |
| 12855 | + * issue that will mess up the default VNIC if we reduce the | |
| 12856 | + * reservations. | |
| 12857 | + */ | |
| 12858 | + if (hwr.vnic <= bp->hw_resc.resv_vnics && | |
| 12855 | 12859 | hwr.rss_ctx <= bp->hw_resc.resv_rsscos_ctxs) |
| 12856 | 12860 | return true; |
| 12857 | 12861 | |
| @@ -6363,49 +6363,49 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter) · 6362 unmodified lines | ||
| 6363 | 6363 | mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; |
| 6364 | 6364 | ew32(EXTCNF_CTRL, mac_data); |
| 6365 | 6365 | |
| 6366 | − /* Enable the Dynamic Power Gating in the MAC */ | |
| 6367 | − mac_data = er32(FEXTNVM7); | |
| 6368 | − mac_data |= BIT(22); | |
| 6369 | − ew32(FEXTNVM7, mac_data); | |
| 6370 | − | |
| 6371 | 6366 | /* Disable disconnected cable conditioning for Power Gating */ |
| 6372 | 6367 | mac_data = er32(DPGFR); |
| 6373 | 6368 | mac_data |= BIT(2); |
| 6374 | 6369 | ew32(DPGFR, mac_data); |
| 6375 | 6370 | |
| 6376 | − /* Don't wake from dynamic Power Gating with clock request */ | |
| 6377 | − mac_data = er32(FEXTNVM12); | |
| 6378 | − mac_data |= BIT(12); | |
| 6379 | − ew32(FEXTNVM12, mac_data); | |
| 6380 | − | |
| 6381 | − /* Ungate PGCB clock */ | |
| 6382 | − mac_data = er32(FEXTNVM9); | |
| 6383 | − mac_data &= ~BIT(28); | |
| 6384 | − ew32(FEXTNVM9, mac_data); | |
| 6385 | − | |
| 6386 | − /* Enable K1 off to enable mPHY Power Gating */ | |
| 6387 | − mac_data = er32(FEXTNVM6); | |
| 6388 | − mac_data |= BIT(31); | |
| 6389 | − ew32(FEXTNVM6, mac_data); | |
| 6390 | − | |
| 6391 | − /* Enable mPHY power gating for any link and speed */ | |
| 6392 | − mac_data = er32(FEXTNVM8); | |
| 6393 | − mac_data |= BIT(9); | |
| 6394 | − ew32(FEXTNVM8, mac_data); | |
| 6395 | − | |
| 6396 | 6371 | /* Enable the Dynamic Clock Gating in the DMA and MAC */ |
| 6397 | 6372 | mac_data = er32(CTRL_EXT); |
| 6398 | 6373 | mac_data |= E1000_CTRL_EXT_DMA_DYN_CLK_EN; |
| 6399 | 6374 | ew32(CTRL_EXT, mac_data); |
| 6400 | − | |
| 6401 | − /* No MAC DPG gating SLP_S0 in modern standby | |
| 6402 | − * Switch the logic of the lanphypc to use PMC counter | |
| 6403 | − */ | |
| 6404 | − mac_data = er32(FEXTNVM5); | |
| 6405 | − mac_data |= BIT(7); | |
| 6406 | − ew32(FEXTNVM5, mac_data); | |
| 6407 | 6375 | } |
| 6408 | 6376 | |
| 6377 | + /* Enable the Dynamic Power Gating in the MAC */ | |
| 6378 | + mac_data = er32(FEXTNVM7); | |
| 6379 | + mac_data |= BIT(22); | |
| 6380 | + ew32(FEXTNVM7, mac_data); | |
| 6381 | + | |
| 6382 | + /* Don't wake from dynamic Power Gating with clock request */ | |
| 6383 | + mac_data = er32(FEXTNVM12); | |
| 6384 | + mac_data |= BIT(12); | |
| 6385 | + ew32(FEXTNVM12, mac_data); | |
| 6386 | + | |
| 6387 | + /* Ungate PGCB clock */ | |
| 6388 | + mac_data = er32(FEXTNVM9); | |
| 6389 | + mac_data &= ~BIT(28); | |
| 6390 | + ew32(FEXTNVM9, mac_data); | |
| 6391 | + | |
| 6392 | + /* Enable K1 off to enable mPHY Power Gating */ | |
| 6393 | + mac_data = er32(FEXTNVM6); | |
| 6394 | + mac_data |= BIT(31); | |
| 6395 | + ew32(FEXTNVM6, mac_data); | |
| 6396 | + | |
| 6397 | + /* Enable mPHY power gating for any link and speed */ | |
| 6398 | + mac_data = er32(FEXTNVM8); | |
| 6399 | + mac_data |= BIT(9); | |
| 6400 | + ew32(FEXTNVM8, mac_data); | |
| 6401 | + | |
| 6402 | + /* No MAC DPG gating SLP_S0 in modern standby | |
| 6403 | + * Switch the logic of the lanphypc to use PMC counter | |
| 6404 | + */ | |
| 6405 | + mac_data = er32(FEXTNVM5); | |
| 6406 | + mac_data |= BIT(7); | |
| 6407 | + ew32(FEXTNVM5, mac_data); | |
| 6408 | + | |
| 6409 | 6409 | /* Disable the time synchronization clock */ |
| 6410 | 6410 | mac_data = er32(FEXTNVM7); |
| 6411 | 6411 | mac_data |= BIT(31); |
| @@ -6498,33 +6498,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter) · 86 unmodified lines | ||
| 6498 | 6498 | } else { |
| 6499 | 6499 | /* Request driver unconfigure the device from S0ix */ |
| 6500 | 6500 | |
| 6501 | − /* Disable the Dynamic Power Gating in the MAC */ | |
| 6502 | − mac_data = er32(FEXTNVM7); | |
| 6503 | − mac_data &= 0xFFBFFFFF; | |
| 6504 | − ew32(FEXTNVM7, mac_data); | |
| 6505 | − | |
| 6506 | − /* Disable mPHY power gating for any link and speed */ | |
| 6507 | − mac_data = er32(FEXTNVM8); | |
| 6508 | − mac_data &= ~BIT(9); | |
| 6509 | − ew32(FEXTNVM8, mac_data); | |
| 6510 | − | |
| 6511 | − /* Disable K1 off */ | |
| 6512 | − mac_data = er32(FEXTNVM6); | |
| 6513 | − mac_data &= ~BIT(31); | |
| 6514 | − ew32(FEXTNVM6, mac_data); | |
| 6515 | − | |
| 6516 | − /* Disable Ungate PGCB clock */ | |
| 6517 | − mac_data = er32(FEXTNVM9); | |
| 6518 | − mac_data |= BIT(28); | |
| 6519 | − ew32(FEXTNVM9, mac_data); | |
| 6520 | − | |
| 6521 | − /* Cancel not waking from dynamic | |
| 6522 | − * Power Gating with clock request | |
| 6523 | − */ | |
| 6524 | − mac_data = er32(FEXTNVM12); | |
| 6525 | − mac_data &= ~BIT(12); | |
| 6526 | − ew32(FEXTNVM12, mac_data); | |
| 6527 | − | |
| 6528 | 6501 | /* Cancel disable disconnected cable conditioning |
| 6529 | 6502 | * for Power Gating |
| 6530 | 6503 | */ |
| @@ -6537,13 +6510,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter) · 6 unmodified lines | ||
| 6537 | 6510 | mac_data &= 0xFFF7FFFF; |
| 6538 | 6511 | ew32(CTRL_EXT, mac_data); |
| 6539 | 6512 | |
| 6540 | − /* Revert the lanphypc logic to use the internal Gbe counter | |
| 6541 | − * and not the PMC counter | |
| 6542 | − */ | |
| 6543 | − mac_data = er32(FEXTNVM5); | |
| 6544 | − mac_data &= 0xFFFFFF7F; | |
| 6545 | − ew32(FEXTNVM5, mac_data); | |
| 6546 | − | |
| 6547 | 6513 | /* Enable the periodic inband message, |
| 6548 | 6514 | * Request PCIe clock in K1 page770_17[10:9] =01b |
| 6549 | 6515 | */ |
| @@ -6581,6 +6547,40 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter) · 31 unmodified lines | ||
| 6581 | 6547 | mac_data &= ~BIT(31); |
| 6582 | 6548 | mac_data |= BIT(0); |
| 6583 | 6549 | ew32(FEXTNVM7, mac_data); |
| 6550 | + | |
| 6551 | + /* Disable the Dynamic Power Gating in the MAC */ | |
| 6552 | + mac_data = er32(FEXTNVM7); | |
| 6553 | + mac_data &= 0xFFBFFFFF; | |
| 6554 | + ew32(FEXTNVM7, mac_data); | |
| 6555 | + | |
| 6556 | + /* Disable mPHY power gating for any link and speed */ | |
| 6557 | + mac_data = er32(FEXTNVM8); | |
| 6558 | + mac_data &= ~BIT(9); | |
| 6559 | + ew32(FEXTNVM8, mac_data); | |
| 6560 | + | |
| 6561 | + /* Disable K1 off */ | |
| 6562 | + mac_data = er32(FEXTNVM6); | |
| 6563 | + mac_data &= ~BIT(31); | |
| 6564 | + ew32(FEXTNVM6, mac_data); | |
| 6565 | + | |
| 6566 | + /* Disable Ungate PGCB clock */ | |
| 6567 | + mac_data = er32(FEXTNVM9); | |
| 6568 | + mac_data |= BIT(28); | |
| 6569 | + ew32(FEXTNVM9, mac_data); | |
| 6570 | + | |
| 6571 | + /* Cancel not waking from dynamic | |
| 6572 | + * Power Gating with clock request | |
| 6573 | + */ | |
| 6574 | + mac_data = er32(FEXTNVM12); | |
| 6575 | + mac_data &= ~BIT(12); | |
| 6576 | + ew32(FEXTNVM12, mac_data); | |
| 6577 | + | |
| 6578 | + /* Revert the lanphypc logic to use the internal Gbe counter | |
| 6579 | + * and not the PMC counter | |
| 6580 | + */ | |
| 6581 | + mac_data = er32(FEXTNVM5); | |
| 6582 | + mac_data &= 0xFFFFFF7F; | |
| 6583 | + ew32(FEXTNVM5, mac_data); | |
| 6584 | 6584 | } |
| 6585 | 6585 | |
| 6586 | 6586 | static int e1000e_pm_freeze(struct device *dev) |
| @@ -96,7 +96,7 @@ static bool ice_is_internal_reading_supported(struct ice_pf *pf) · 95 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | unsigned long sensors = pf->hw.dev_caps.supported_sensors; |
| 98 | 98 | |
| 99 | − return _test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors); | |
| 99 | + return test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors); | |
| 100 | 100 | }; |
| 101 | 101 | |
| 102 | 102 | void ice_hwmon_init(struct ice_pf *pf) |
| @@ -1618,6 +1618,10 @@ void ice_ptp_extts_event(struct ice_pf *pf) · 1617 unmodified lines | ||
| 1618 | 1618 | u8 chan, tmr_idx; |
| 1619 | 1619 | u32 hi, lo; |
| 1620 | 1620 | |
| 1621 | + /* Don't process timestamp events if PTP is not ready */ | |
| 1622 | + if (pf->ptp.state != ICE_PTP_READY) | |
| 1623 | + return; | |
| 1624 | + | |
| 1621 | 1625 | tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; |
| 1622 | 1626 | /* Event time is captured by one of the two matched registers |
| 1623 | 1627 | * GLTSYN_EVNT_L: 32 LSB of sampled time event |
| @@ -1643,27 +1647,33 @@ void ice_ptp_extts_event(struct ice_pf *pf) · 19 unmodified lines | ||
| 1643 | 1647 | /** |
| 1644 | 1648 | * ice_ptp_cfg_extts - Configure EXTTS pin and channel |
| 1645 | 1649 | * @pf: Board private structure |
| 1646 | − * @ena: true to enable; false to disable | |
| 1647 | 1650 | * @chan: GPIO channel (0-3) |
| 1648 | − * @gpio_pin: GPIO pin | |
| 1649 | − * @extts_flags: request flags from the ptp_extts_request.flags | |
| 1651 | + * @config: desired EXTTS configuration. | |
| 1652 | + * @store: If set to true, the values will be stored | |
| 1653 | + * | |
| 1654 | + * Configure an external timestamp event on the requested channel. | |
| 1655 | + * | |
| 1656 | + * Return: 0 on success, -EOPNOTUSPP on unsupported flags | |
| 1650 | 1657 | */ |
| 1651 | −static int | |
| 1652 | −ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin, | |
| 1653 | − unsigned int extts_flags) | |
| 1658 | +static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan, | |
| 1659 | + struct ice_extts_channel *config, bool store) | |
| 1654 | 1660 | { |
| 1655 | 1661 | u32 func, aux_reg, gpio_reg, irq_reg; |
| 1656 | 1662 | struct ice_hw *hw = &pf->hw; |
| 1657 | 1663 | u8 tmr_idx; |
| 1658 | 1664 | |
| 1659 | − if (chan > (unsigned int)pf->ptp.info.n_ext_ts) | |
| 1660 | − return -EINVAL; | |
| 1665 | + /* Reject requests with unsupported flags */ | |
| 1666 | + if (config->flags & ~(PTP_ENABLE_FEATURE | | |
| 1667 | + PTP_RISING_EDGE | | |
| 1668 | + PTP_FALLING_EDGE | | |
| 1669 | + PTP_STRICT_FLAGS)) | |
| 1670 | + return -EOPNOTSUPP; | |
| 1661 | 1671 | |
| 1662 | 1672 | tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; |
| 1663 | 1673 | |
| 1664 | 1674 | irq_reg = rd32(hw, PFINT_OICR_ENA); |
| 1665 | 1675 | |
| 1666 | − if (ena) { | |
| 1676 | + if (config->ena) { | |
| 1667 | 1677 | /* Enable the interrupt */ |
| 1668 | 1678 | irq_reg |= PFINT_OICR_TSYN_EVNT_M; |
| 1669 | 1679 | aux_reg = GLTSYN_AUX_IN_0_INT_ENA_M; |
| @@ -1672,9 +1682,9 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin, · 2 unmodified lines | ||
| 1672 | 1682 | #define GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE BIT(1) |
| 1673 | 1683 | |
| 1674 | 1684 | /* set event level to requested edge */ |
| 1675 | − if (extts_flags & PTP_FALLING_EDGE) | |
| 1685 | + if (config->flags & PTP_FALLING_EDGE) | |
| 1676 | 1686 | aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE; |
| 1677 | − if (extts_flags & PTP_RISING_EDGE) | |
| 1687 | + if (config->flags & PTP_RISING_EDGE) | |
| 1678 | 1688 | aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_RISING_EDGE; |
| 1679 | 1689 | |
| 1680 | 1690 | /* Write GPIO CTL reg. |
| @@ -1695,11 +1705,51 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin, · 14 unmodified lines | ||
| 1695 | 1705 | |
| 1696 | 1706 | wr32(hw, PFINT_OICR_ENA, irq_reg); |
| 1697 | 1707 | wr32(hw, GLTSYN_AUX_IN(chan, tmr_idx), aux_reg); |
| 1698 | − wr32(hw, GLGEN_GPIO_CTL(gpio_pin), gpio_reg); | |
| 1708 | + wr32(hw, GLGEN_GPIO_CTL(config->gpio_pin), gpio_reg); | |
| 1709 | + | |
| 1710 | + if (store) | |
| 1711 | + memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config)); | |
| 1699 | 1712 | |
| 1700 | 1713 | return 0; |
| 1701 | 1714 | } |
| 1702 | 1715 | |
| 1716 | +/** | |
| 1717 | + * ice_ptp_disable_all_extts - Disable all EXTTS channels | |
| 1718 | + * @pf: Board private structure | |
| 1719 | + */ | |
| 1720 | +static void ice_ptp_disable_all_extts(struct ice_pf *pf) | |
| 1721 | +{ | |
| 1722 | + struct ice_extts_channel extts_cfg = {}; | |
| 1723 | + int i; | |
| 1724 | + | |
| 1725 | + for (i = 0; i < pf->ptp.info.n_ext_ts; i++) { | |
| 1726 | + if (pf->ptp.extts_channels[i].ena) { | |
| 1727 | + extts_cfg.gpio_pin = pf->ptp.extts_channels[i].gpio_pin; | |
| 1728 | + extts_cfg.ena = false; | |
| 1729 | + ice_ptp_cfg_extts(pf, i, &extts_cfg, false); | |
| 1730 | + } | |
| 1731 | + } | |
| 1732 | + | |
| 1733 | + synchronize_irq(pf->oicr_irq.virq); | |
| 1734 | +} | |
| 1735 | + | |
| 1736 | +/** | |
| 1737 | + * ice_ptp_enable_all_extts - Enable all EXTTS channels | |
| 1738 | + * @pf: Board private structure | |
| 1739 | + * | |
| 1740 | + * Called during reset to restore user configuration. | |
| 1741 | + */ | |
| 1742 | +static void ice_ptp_enable_all_extts(struct ice_pf *pf) | |
| 1743 | +{ | |
| 1744 | + int i; | |
| 1745 | + | |
| 1746 | + for (i = 0; i < pf->ptp.info.n_ext_ts; i++) { | |
| 1747 | + if (pf->ptp.extts_channels[i].ena) | |
| 1748 | + ice_ptp_cfg_extts(pf, i, &pf->ptp.extts_channels[i], | |
| 1749 | + false); | |
| 1750 | + } | |
| 1751 | +} | |
| 1752 | + | |
| 1703 | 1753 | /** |
| 1704 | 1754 | * ice_ptp_cfg_clkout - Configure clock to generate periodic wave |
| 1705 | 1755 | * @pf: Board private structure |
| @@ -1718,6 +1768,9 @@ static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan, · 12 unmodified lines | ||
| 1718 | 1768 | u32 func, val, gpio_pin; |
| 1719 | 1769 | u8 tmr_idx; |
| 1720 | 1770 | |
| 1771 | + if (config && config->flags & ~PTP_PEROUT_PHASE) | |
| 1772 | + return -EOPNOTSUPP; | |
| 1773 | + | |
| 1721 | 1774 | tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; |
| 1722 | 1775 | |
| 1723 | 1776 | /* 0. Reset mode & out_en in AUX_OUT */ |
| @@ -1853,17 +1906,18 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, · 129 unmodified lines | ||
| 1853 | 1906 | struct ptp_clock_request *rq, int on) |
| 1854 | 1907 | { |
| 1855 | 1908 | struct ice_pf *pf = ptp_info_to_pf(info); |
| 1856 | − struct ice_perout_channel clk_cfg = {0}; | |
| 1857 | 1909 | bool sma_pres = false; |
| 1858 | 1910 | unsigned int chan; |
| 1859 | 1911 | u32 gpio_pin; |
| 1860 | − int err; | |
| 1861 | 1912 | |
| 1862 | 1913 | if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) |
| 1863 | 1914 | sma_pres = true; |
| 1864 | 1915 | |
| 1865 | 1916 | switch (rq->type) { |
| 1866 | 1917 | case PTP_CLK_REQ_PEROUT: |
| 1918 | + { | |
| 1919 | + struct ice_perout_channel clk_cfg = {}; | |
| 1920 | + | |
| 1867 | 1921 | chan = rq->perout.index; |
| 1868 | 1922 | if (sma_pres) { |
| 1869 | 1923 | if (chan == ice_pin_desc_e810t[SMA1].chan) |
| @@ -1883,15 +1937,19 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, · 13 unmodified lines | ||
| 1883 | 1937 | clk_cfg.gpio_pin = chan; |
| 1884 | 1938 | } |
| 1885 | 1939 | |
| 1940 | + clk_cfg.flags = rq->perout.flags; | |
| 1886 | 1941 | clk_cfg.period = ((rq->perout.period.sec * NSEC_PER_SEC) + |
| 1887 | 1942 | rq->perout.period.nsec); |
| 1888 | 1943 | clk_cfg.start_time = ((rq->perout.start.sec * NSEC_PER_SEC) + |
| 1889 | 1944 | rq->perout.start.nsec); |
| 1890 | 1945 | clk_cfg.ena = !!on; |
| 1891 | 1946 | |
| 1892 | − err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true); | |
| 1893 | − break; | |
| 1947 | + return ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true); | |
| 1948 | + } | |
| 1894 | 1949 | case PTP_CLK_REQ_EXTTS: |
| 1950 | + { | |
| 1951 | + struct ice_extts_channel extts_cfg = {}; | |
| 1952 | + | |
| 1895 | 1953 | chan = rq->extts.index; |
| 1896 | 1954 | if (sma_pres) { |
| 1897 | 1955 | if (chan < ice_pin_desc_e810t[SMA2].chan) |
| @@ -1907,14 +1965,15 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, · 9 unmodified lines | ||
| 1907 | 1965 | gpio_pin = chan; |
| 1908 | 1966 | } |
| 1909 | 1967 | |
| 1910 | − err = ice_ptp_cfg_extts(pf, !!on, chan, gpio_pin, | |
| 1911 | − rq->extts.flags); | |
| 1912 | − break; | |
| 1968 | + extts_cfg.flags = rq->extts.flags; | |
| 1969 | + extts_cfg.gpio_pin = gpio_pin; | |
| 1970 | + extts_cfg.ena = !!on; | |
| 1971 | + | |
| 1972 | + return ice_ptp_cfg_extts(pf, chan, &extts_cfg, true); | |
| 1973 | + } | |
| 1913 | 1974 | default: |
| 1914 | 1975 | return -EOPNOTSUPP; |
| 1915 | 1976 | } |
| 1916 | − | |
| 1917 | − return err; | |
| 1918 | 1977 | } |
| 1919 | 1978 | |
| 1920 | 1979 | /** |
| @@ -1927,26 +1986,32 @@ static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info, · 6 unmodified lines | ||
| 1927 | 1986 | struct ptp_clock_request *rq, int on) |
| 1928 | 1987 | { |
| 1929 | 1988 | struct ice_pf *pf = ptp_info_to_pf(info); |
| 1930 | − struct ice_perout_channel clk_cfg = {0}; | |
| 1931 | − int err; | |
| 1932 | 1989 | |
| 1933 | 1990 | switch (rq->type) { |
| 1934 | 1991 | case PTP_CLK_REQ_PPS: |
| 1992 | + { | |
| 1993 | + struct ice_perout_channel clk_cfg = {}; | |
| 1994 | + | |
| 1995 | + clk_cfg.flags = rq->perout.flags; | |
| 1935 | 1996 | clk_cfg.gpio_pin = PPS_PIN_INDEX; |
| 1936 | 1997 | clk_cfg.period = NSEC_PER_SEC; |
| 1937 | 1998 | clk_cfg.ena = !!on; |
| 1938 | 1999 | |
| 1939 | − err = ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true); | |
| 1940 | − break; | |
| 2000 | + return ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true); | |
| 2001 | + } | |
| 1941 | 2002 | case PTP_CLK_REQ_EXTTS: |
| 1942 | − err = ice_ptp_cfg_extts(pf, !!on, rq->extts.index, | |
| 1943 | − TIME_SYNC_PIN_INDEX, rq->extts.flags); | |
| 1944 | − break; | |
| 2003 | + { | |
| 2004 | + struct ice_extts_channel extts_cfg = {}; | |
| 2005 | + | |
| 2006 | + extts_cfg.flags = rq->extts.flags; | |
| 2007 | + extts_cfg.gpio_pin = TIME_SYNC_PIN_INDEX; | |
| 2008 | + extts_cfg.ena = !!on; | |
| 2009 | + | |
| 2010 | + return ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true); | |
| 2011 | + } | |
| 1945 | 2012 | default: |
| 1946 | 2013 | return -EOPNOTSUPP; |
| 1947 | 2014 | } |
| 1948 | − | |
| 1949 | − return err; | |
| 1950 | 2015 | } |
| 1951 | 2016 | |
| 1952 | 2017 | /** |
| @@ -2781,6 +2846,10 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf) · 828 unmodified lines | ||
| 2781 | 2846 | ice_ptp_restart_all_phy(pf); |
| 2782 | 2847 | } |
| 2783 | 2848 | |
| 2849 | + /* Re-enable all periodic outputs and external timestamp events */ | |
| 2850 | + ice_ptp_enable_all_clkout(pf); | |
| 2851 | + ice_ptp_enable_all_extts(pf); | |
| 2852 | + | |
| 2784 | 2853 | return 0; |
| 2785 | 2854 | } |
| 2786 | 2855 | |
| @@ -3340,6 +3409,8 @@ void ice_ptp_release(struct ice_pf *pf) · 553 unmodified lines | ||
| 3340 | 3409 | |
| 3341 | 3410 | ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx); |
| 3342 | 3411 | |
| 3412 | + ice_ptp_disable_all_extts(pf); | |
| 3413 | + | |
| 3343 | 3414 | kthread_cancel_delayed_work_sync(&pf->ptp.work); |
| 3344 | 3415 | |
| 3345 | 3416 | ice_ptp_port_phy_stop(&pf->ptp.port); |
| @@ -29,10 +29,17 @@ enum ice_ptp_pin_e810t { · 28 unmodified lines | ||
| 29 | 29 | struct ice_perout_channel { |
| 30 | 30 | bool ena; |
| 31 | 31 | u32 gpio_pin; |
| 32 | + u32 flags; | |
| 32 | 33 | u64 period; |
| 33 | 34 | u64 start_time; |
| 34 | 35 | }; |
| 35 | 36 | |
| 37 | +struct ice_extts_channel { | |
| 38 | + bool ena; | |
| 39 | + u32 gpio_pin; | |
| 40 | + u32 flags; | |
| 41 | +}; | |
| 42 | + | |
| 36 | 43 | /* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp |
| 37 | 44 | * is stored in a buffer of registers. Depending on the specific hardware, |
| 38 | 45 | * this buffer might be shared across multiple PHY ports. |
| @@ -227,6 +234,7 @@ enum ice_ptp_state { · 188 unmodified lines | ||
| 227 | 234 | * @ext_ts_irq: the external timestamp IRQ in use |
| 228 | 235 | * @kworker: kwork thread for handling periodic work |
| 229 | 236 | * @perout_channels: periodic output data |
| 237 | + * @extts_channels: channels for external timestamps | |
| 230 | 238 | * @info: structure defining PTP hardware capabilities |
| 231 | 239 | * @clock: pointer to registered PTP clock device |
| 232 | 240 | * @tstamp_config: hardware timestamping configuration |
| @@ -250,6 +258,7 @@ struct ice_ptp { · 17 unmodified lines | ||
| 250 | 258 | u8 ext_ts_irq; |
| 251 | 259 | struct kthread_worker *kworker; |
| 252 | 260 | struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX]; |
| 261 | + struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX]; | |
| 253 | 262 | struct ptp_clock_info info; |
| 254 | 263 | struct ptp_clock *clock; |
| 255 | 264 | struct hwtstamp_config tstamp_config; |
| @@ -989,7 +989,12 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x) · 988 unmodified lines | ||
| 989 | 989 | struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); |
| 990 | 990 | struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule; |
| 991 | 991 | struct net *net = dev_net(x->xso.dev); |
| 992 | + u64 trailer_packets = 0, trailer_bytes = 0; | |
| 993 | + u64 replay_packets = 0, replay_bytes = 0; | |
| 994 | + u64 auth_packets = 0, auth_bytes = 0; | |
| 995 | + u64 success_packets, success_bytes; | |
| 992 | 996 | u64 packets, bytes, lastuse; |
| 997 | + size_t headers; | |
| 993 | 998 | |
| 994 | 999 | lockdep_assert(lockdep_is_held(&x->lock) || |
| 995 | 1000 | lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex) || |
| @@ -999,26 +1004,43 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x) · 3 unmodified lines | ||
| 999 | 1004 | return; |
| 1000 | 1005 | |
| 1001 | 1006 | if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) { |
| 1002 | − mlx5_fc_query_cached(ipsec_rule->auth.fc, &bytes, &packets, &lastuse); | |
| 1003 | − x->stats.integrity_failed += packets; | |
| 1004 | − XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, packets); | |
| 1005 | − | |
| 1006 | − mlx5_fc_query_cached(ipsec_rule->trailer.fc, &bytes, &packets, &lastuse); | |
| 1007 | − XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, packets); | |
| 1007 | + mlx5_fc_query_cached(ipsec_rule->auth.fc, &auth_bytes, | |
| 1008 | + &auth_packets, &lastuse); | |
| 1009 | + x->stats.integrity_failed += auth_packets; | |
| 1010 | + XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, auth_packets); | |
| 1011 | + | |
| 1012 | + mlx5_fc_query_cached(ipsec_rule->trailer.fc, &trailer_bytes, | |
| 1013 | + &trailer_packets, &lastuse); | |
| 1014 | + XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, trailer_packets); | |
| 1008 | 1015 | } |
| 1009 | 1016 | |
| 1010 | 1017 | if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) |
| 1011 | 1018 | return; |
| 1012 | 1019 | |
| 1013 | − mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse); | |
| 1014 | − x->curlft.packets += packets; | |
| 1015 | − x->curlft.bytes += bytes; | |
| 1016 | − | |
| 1017 | 1020 | if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) { |
| 1018 | − mlx5_fc_query_cached(ipsec_rule->replay.fc, &bytes, &packets, &lastuse); | |
| 1019 | − x->stats.replay += packets; | |
| 1020 | − XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, packets); | |
| 1021 | + mlx5_fc_query_cached(ipsec_rule->replay.fc, &replay_bytes, | |
| 1022 | + &replay_packets, &lastuse); | |
| 1023 | + x->stats.replay += replay_packets; | |
| 1024 | + XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, replay_packets); | |
| 1021 | 1025 | } |
| 1026 | + | |
| 1027 | + mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse); | |
| 1028 | + success_packets = packets - auth_packets - trailer_packets - replay_packets; | |
| 1029 | + x->curlft.packets += success_packets; | |
| 1030 | + /* NIC counts all bytes passed through flow steering and doesn't have | |
| 1031 | + * an ability to count payload data size which is needed for SA. | |
| 1032 | + * | |
| 1033 | + * To overcome HW limitestion, let's approximate the payload size | |
| 1034 | + * by removing always available headers. | |
| 1035 | + */ | |
| 1036 | + headers = sizeof(struct ethhdr); | |
| 1037 | + if (sa_entry->attrs.family == AF_INET) | |
| 1038 | + headers += sizeof(struct iphdr); | |
| 1039 | + else | |
| 1040 | + headers += sizeof(struct ipv6hdr); | |
| 1041 | + | |
| 1042 | + success_bytes = bytes - auth_bytes - trailer_bytes - replay_bytes; | |
| 1043 | + x->curlft.bytes += success_bytes - headers * success_packets; | |
| 1022 | 1044 | } |
| 1023 | 1045 | |
| 1024 | 1046 | static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev, |
| @@ -6034,6 +6034,11 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) · 6033 unmodified lines | ||
| 6034 | 6034 | kfree(priv->htb_qos_sq_stats[i]); |
| 6035 | 6035 | kvfree(priv->htb_qos_sq_stats); |
| 6036 | 6036 | |
| 6037 | + if (priv->mqprio_rl) { | |
| 6038 | + mlx5e_mqprio_rl_cleanup(priv->mqprio_rl); | |
| 6039 | + mlx5e_mqprio_rl_free(priv->mqprio_rl); | |
| 6040 | + } | |
| 6041 | + | |
| 6037 | 6042 | memset(priv, 0, sizeof(*priv)); |
| 6038 | 6043 | } |
| 6039 | 6044 | |
| @@ -1197,9 +1197,7 @@ static int get_num_eqs(struct mlx5_core_dev *dev) · 1196 unmodified lines | ||
| 1197 | 1197 | if (!mlx5_core_is_eth_enabled(dev) && mlx5_eth_supported(dev)) |
| 1198 | 1198 | return 1; |
| 1199 | 1199 | |
| 1200 | − max_dev_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ? | |
| 1201 | − MLX5_CAP_GEN(dev, max_num_eqs) : | |
| 1202 | − 1 << MLX5_CAP_GEN(dev, log_max_eq); | |
| 1200 | + max_dev_eqs = mlx5_max_eq_cap_get(dev); | |
| 1203 | 1201 | |
| 1204 | 1202 | num_eqs = min_t(int, mlx5_irq_table_get_num_comp(eq_table->irq_table), |
| 1205 | 1203 | max_dev_eqs - MLX5_MAX_ASYNC_EQS); |
| @@ -6,6 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "helper.h" |
| 7 | 7 | #include "ofld.h" |
| 8 | 8 | |
| 9 | +static int | |
| 10 | +acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport); | |
| 11 | + | |
| 9 | 12 | static bool |
| 10 | 13 | esw_acl_ingress_prio_tag_enabled(struct mlx5_eswitch *esw, |
| 11 | 14 | const struct mlx5_vport *vport) |
| @@ -123,18 +126,31 @@ static int esw_acl_ingress_src_port_drop_create(struct mlx5_eswitch *esw, · 111 unmodified lines | ||
| 123 | 126 | { |
| 124 | 127 | struct mlx5_flow_act flow_act = {}; |
| 125 | 128 | struct mlx5_flow_handle *flow_rule; |
| 129 | + bool created = false; | |
| 126 | 130 | int err = 0; |
| 127 | 131 | |
| 132 | + if (!vport->ingress.acl) { | |
| 133 | + err = acl_ingress_ofld_setup(esw, vport); | |
| 134 | + if (err) | |
| 135 | + return err; | |
| 136 | + created = true; | |
| 137 | + } | |
| 138 | + | |
| 128 | 139 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; |
| 129 | 140 | flow_act.fg = vport->ingress.offloads.drop_grp; |
| 130 | 141 | flow_rule = mlx5_add_flow_rules(vport->ingress.acl, NULL, &flow_act, NULL, 0); |
| 131 | 142 | if (IS_ERR(flow_rule)) { |
| 132 | 143 | err = PTR_ERR(flow_rule); |
| 133 | − goto out; | |
| 144 | + goto err_out; | |
| 134 | 145 | } |
| 135 | 146 | |
| 136 | 147 | vport->ingress.offloads.drop_rule = flow_rule; |
| 137 | −out: | |
| 148 | + | |
| 149 | + return 0; | |
| 150 | +err_out: | |
| 151 | + /* Only destroy ingress acl created in this function. */ | |
| 152 | + if (created) | |
| 153 | + esw_acl_ingress_ofld_cleanup(esw, vport); | |
| 138 | 154 | return err; |
| 139 | 155 | } |
| 140 | 156 | |
| @@ -299,16 +315,12 @@ static void esw_acl_ingress_ofld_groups_destroy(struct mlx5_vport *vport) · 158 unmodified lines | ||
| 299 | 315 | } |
| 300 | 316 | } |
| 301 | 317 | |
| 302 | −int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw, | |
| 303 | − struct mlx5_vport *vport) | |
| 318 | +static int | |
| 319 | +acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport) | |
| 304 | 320 | { |
| 305 | 321 | int num_ftes = 0; |
| 306 | 322 | int err; |
| 307 | 323 | |
| 308 | − if (!mlx5_eswitch_vport_match_metadata_enabled(esw) && | |
| 309 | − !esw_acl_ingress_prio_tag_enabled(esw, vport)) | |
| 310 | − return 0; | |
| 311 | − | |
| 312 | 324 | esw_acl_ingress_allow_rule_destroy(vport); |
| 313 | 325 | |
| 314 | 326 | if (mlx5_eswitch_vport_match_metadata_enabled(esw)) |
| @@ -347,6 +359,15 @@ group_err: · 32 unmodified lines | ||
| 347 | 359 | return err; |
| 348 | 360 | } |
| 349 | 361 | |
| 362 | +int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport) | |
| 363 | +{ | |
| 364 | + if (!mlx5_eswitch_vport_match_metadata_enabled(esw) && | |
| 365 | + !esw_acl_ingress_prio_tag_enabled(esw, vport)) | |
| 366 | + return 0; | |
| 367 | + | |
| 368 | + return acl_ingress_ofld_setup(esw, vport); | |
| 369 | +} | |
| 370 | + | |
| 350 | 371 | void esw_acl_ingress_ofld_cleanup(struct mlx5_eswitch *esw, |
| 351 | 372 | struct mlx5_vport *vport) |
| 352 | 373 | { |
| @@ -4600,20 +4600,26 @@ mlx5_devlink_port_fn_max_io_eqs_get(struct devlink_port *port, u32 *max_io_eqs, · 4599 unmodified lines | ||
| 4600 | 4600 | return -EOPNOTSUPP; |
| 4601 | 4601 | } |
| 4602 | 4602 | |
| 4603 | + if (!MLX5_CAP_GEN_2(esw->dev, max_num_eqs_24b)) { | |
| 4604 | + NL_SET_ERR_MSG_MOD(extack, | |
| 4605 | + "Device doesn't support getting the max number of EQs"); | |
| 4606 | + return -EOPNOTSUPP; | |
| 4607 | + } | |
| 4608 | + | |
| 4603 | 4609 | query_ctx = kzalloc(query_out_sz, GFP_KERNEL); |
| 4604 | 4610 | if (!query_ctx) |
| 4605 | 4611 | return -ENOMEM; |
| 4606 | 4612 | |
| 4607 | 4613 | mutex_lock(&esw->state_lock); |
| 4608 | 4614 | err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx, |
| 4609 | − MLX5_CAP_GENERAL); | |
| 4615 | + MLX5_CAP_GENERAL_2); | |
| 4610 | 4616 | if (err) { |
| 4611 | 4617 | NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps"); |
| 4612 | 4618 | goto out; |
| 4613 | 4619 | } |
| 4614 | 4620 | |
| 4615 | 4621 | hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); |
| 4616 | − max_eqs = MLX5_GET(cmd_hca_cap, hca_caps, max_num_eqs); | |
| 4622 | + max_eqs = MLX5_GET(cmd_hca_cap_2, hca_caps, max_num_eqs_24b); | |
| 4617 | 4623 | if (max_eqs < MLX5_ESW_MAX_CTRL_EQS) |
| 4618 | 4624 | *max_io_eqs = 0; |
| 4619 | 4625 | else |
| @@ -4644,6 +4650,12 @@ mlx5_devlink_port_fn_max_io_eqs_set(struct devlink_port *port, u32 max_io_eqs, · 24 unmodified lines | ||
| 4644 | 4650 | return -EOPNOTSUPP; |
| 4645 | 4651 | } |
| 4646 | 4652 | |
| 4653 | + if (!MLX5_CAP_GEN_2(esw->dev, max_num_eqs_24b)) { | |
| 4654 | + NL_SET_ERR_MSG_MOD(extack, | |
| 4655 | + "Device doesn't support changing the max number of EQs"); | |
| 4656 | + return -EOPNOTSUPP; | |
| 4657 | + } | |
| 4658 | + | |
| 4647 | 4659 | if (check_add_overflow(max_io_eqs, MLX5_ESW_MAX_CTRL_EQS, &max_eqs)) { |
| 4648 | 4660 | NL_SET_ERR_MSG_MOD(extack, "Supplied value out of range"); |
| 4649 | 4661 | return -EINVAL; |
| @@ -4655,17 +4667,17 @@ mlx5_devlink_port_fn_max_io_eqs_set(struct devlink_port *port, u32 max_io_eqs, · 5 unmodified lines | ||
| 4655 | 4667 | |
| 4656 | 4668 | mutex_lock(&esw->state_lock); |
| 4657 | 4669 | err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx, |
| 4658 | − MLX5_CAP_GENERAL); | |
| 4670 | + MLX5_CAP_GENERAL_2); | |
| 4659 | 4671 | if (err) { |
| 4660 | 4672 | NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps"); |
| 4661 | 4673 | goto out; |
| 4662 | 4674 | } |
| 4663 | 4675 | |
| 4664 | 4676 | hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); |
| 4665 | − MLX5_SET(cmd_hca_cap, hca_caps, max_num_eqs, max_eqs); | |
| 4677 | + MLX5_SET(cmd_hca_cap_2, hca_caps, max_num_eqs_24b, max_eqs); | |
| 4666 | 4678 | |
| 4667 | 4679 | err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport_num, |
| 4668 | − MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE); | |
| 4680 | + MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2); | |
| 4669 | 4681 | if (err) |
| 4670 | 4682 | NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA caps"); |
| 4671 | 4683 | |
| @@ -383,4 +383,14 @@ static inline int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vpo · 382 unmodified lines | ||
| 383 | 383 | : vport; |
| 384 | 384 | } |
| 385 | 385 | |
| 386 | +static inline int mlx5_max_eq_cap_get(const struct mlx5_core_dev *dev) | |
| 387 | +{ | |
| 388 | + if (MLX5_CAP_GEN_2(dev, max_num_eqs_24b)) | |
| 389 | + return MLX5_CAP_GEN_2(dev, max_num_eqs_24b); | |
| 390 | + | |
| 391 | + if (MLX5_CAP_GEN(dev, max_num_eqs)) | |
| 392 | + return MLX5_CAP_GEN(dev, max_num_eqs); | |
| 393 | + | |
| 394 | + return 1 << MLX5_CAP_GEN(dev, log_max_eq); | |
| 395 | +} | |
| 386 | 396 | #endif /* __MLX5_CORE_H__ */ |
| @@ -711,9 +711,7 @@ int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table) · 710 unmodified lines | ||
| 711 | 711 | |
| 712 | 712 | int mlx5_irq_table_create(struct mlx5_core_dev *dev) |
| 713 | 713 | { |
| 714 | − int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ? | |
| 715 | − MLX5_CAP_GEN(dev, max_num_eqs) : | |
| 716 | − 1 << MLX5_CAP_GEN(dev, log_max_eq); | |
| 714 | + int num_eqs = mlx5_max_eq_cap_get(dev); | |
| 717 | 715 | int total_vec; |
| 718 | 716 | int pcif_vec; |
| 719 | 717 | int req_vec; |
| @@ -1484,6 +1484,7 @@ err_type_file_file_validate: · 1483 unmodified lines | ||
| 1484 | 1484 | vfree(types_info->data); |
| 1485 | 1485 | err_data_alloc: |
| 1486 | 1486 | kfree(types_info); |
| 1487 | + linecards->types_info = NULL; | |
| 1487 | 1488 | return err; |
| 1488 | 1489 | } |
| 1489 | 1490 | |
| @@ -871,13 +871,13 @@ static void rswitch_tx_free(struct net_device *ndev) · 870 unmodified lines | ||
| 871 | 871 | dma_rmb(); |
| 872 | 872 | skb = gq->skbs[gq->dirty]; |
| 873 | 873 | if (skb) { |
| 874 | + rdev->ndev->stats.tx_packets++; | |
| 875 | + rdev->ndev->stats.tx_bytes += skb->len; | |
| 874 | 876 | dma_unmap_single(ndev->dev.parent, |
| 875 | 877 | gq->unmap_addrs[gq->dirty], |
| 876 | 878 | skb->len, DMA_TO_DEVICE); |
| 877 | 879 | dev_kfree_skb_any(gq->skbs[gq->dirty]); |
| 878 | 880 | gq->skbs[gq->dirty] = NULL; |
| 879 | − rdev->ndev->stats.tx_packets++; | |
| 880 | − rdev->ndev->stats.tx_bytes += skb->len; | |
| 881 | 881 | } |
| 882 | 882 | desc->desc.die_dt = DT_EEMPTY; |
| 883 | 883 | } |
| @@ -272,7 +272,7 @@ static const struct ethqos_emac_por emac_v4_0_0_por[] = { · 271 unmodified lines | ||
| 272 | 272 | |
| 273 | 273 | static const struct ethqos_emac_driver_data emac_v4_0_0_data = { |
| 274 | 274 | .por = emac_v4_0_0_por, |
| 275 | − .num_por = ARRAY_SIZE(emac_v3_0_0_por), | |
| 275 | + .num_por = ARRAY_SIZE(emac_v4_0_0_por), | |
| 276 | 276 | .rgmii_config_loopback_en = false, |
| 277 | 277 | .has_emac_ge_3 = true, |
| 278 | 278 | .link_clk_name = "phyaux", |
| @@ -7663,9 +7663,10 @@ int stmmac_dvr_probe(struct device *device, · 7662 unmodified lines | ||
| 7663 | 7663 | #ifdef STMMAC_VLAN_TAG_USED |
| 7664 | 7664 | /* Both mac100 and gmac support receive VLAN tag detection */ |
| 7665 | 7665 | ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX; |
| 7666 | − ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX; | |
| 7667 | − priv->hw->hw_vlan_en = true; | |
| 7668 | − | |
| 7666 | + if (priv->plat->has_gmac4) { | |
| 7667 | + ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX; | |
| 7668 | + priv->hw->hw_vlan_en = true; | |
| 7669 | + } | |
| 7669 | 7670 | if (priv->dma_cap.vlhash) { |
| 7670 | 7671 | ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
| 7671 | 7672 | ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER; |
| @@ -1978,6 +1978,7 @@ int wx_sw_init(struct wx *wx) · 1977 unmodified lines | ||
| 1978 | 1978 | |
| 1979 | 1979 | bitmap_zero(wx->state, WX_STATE_NBITS); |
| 1980 | 1980 | bitmap_zero(wx->flags, WX_PF_FLAGS_NBITS); |
| 1981 | + wx->misc_irq_domain = false; | |
| 1981 | 1982 | |
| 1982 | 1983 | return 0; |
| 1983 | 1984 | } |
| @@ -1711,6 +1711,7 @@ static int wx_set_interrupt_capability(struct wx *wx) · 1710 unmodified lines | ||
| 1711 | 1711 | } |
| 1712 | 1712 | |
| 1713 | 1713 | pdev->irq = pci_irq_vector(pdev, 0); |
| 1714 | + wx->num_q_vectors = 1; | |
| 1714 | 1715 | |
| 1715 | 1716 | return 0; |
| 1716 | 1717 | } |
| @@ -2021,7 +2022,8 @@ void wx_free_irq(struct wx *wx) · 304 unmodified lines | ||
| 2021 | 2022 | int vector; |
| 2022 | 2023 | |
| 2023 | 2024 | if (!(pdev->msix_enabled)) { |
| 2024 | − free_irq(pdev->irq, wx); | |
| 2025 | + if (!wx->misc_irq_domain) | |
| 2026 | + free_irq(pdev->irq, wx); | |
| 2025 | 2027 | return; |
| 2026 | 2028 | } |
| 2027 | 2029 | |
| @@ -2036,7 +2038,7 @@ void wx_free_irq(struct wx *wx) · 8 unmodified lines | ||
| 2036 | 2038 | free_irq(entry->vector, q_vector); |
| 2037 | 2039 | } |
| 2038 | 2040 | |
| 2039 | − if (wx->mac.type == wx_mac_em) | |
| 2041 | + if (!wx->misc_irq_domain) | |
| 2040 | 2042 | free_irq(wx->msix_entry->vector, wx); |
| 2041 | 2043 | } |
| 2042 | 2044 | EXPORT_SYMBOL(wx_free_irq); |
| @@ -2051,6 +2053,9 @@ int wx_setup_isb_resources(struct wx *wx) · 8 unmodified lines | ||
| 2051 | 2053 | { |
| 2052 | 2054 | struct pci_dev *pdev = wx->pdev; |
| 2053 | 2055 | |
| 2056 | + if (wx->isb_mem) | |
| 2057 | + return 0; | |
| 2058 | + | |
| 2054 | 2059 | wx->isb_mem = dma_alloc_coherent(&pdev->dev, |
| 2055 | 2060 | sizeof(u32) * 4, |
| 2056 | 2061 | &wx->isb_dma, |
| @@ -2410,7 +2415,6 @@ static void wx_free_all_tx_resources(struct wx *wx) · 353 unmodified lines | ||
| 2410 | 2415 | |
| 2411 | 2416 | void wx_free_resources(struct wx *wx) |
| 2412 | 2417 | { |
| 2413 | − wx_free_isb_resources(wx); | |
| 2414 | 2418 | wx_free_all_rx_resources(wx); |
| 2415 | 2419 | wx_free_all_tx_resources(wx); |
| 2416 | 2420 | } |
| @@ -1109,6 +1109,7 @@ struct wx { · 1108 unmodified lines | ||
| 1109 | 1109 | dma_addr_t isb_dma; |
| 1110 | 1110 | u32 *isb_mem; |
| 1111 | 1111 | u32 isb_tag[WX_ISB_MAX]; |
| 1112 | + bool misc_irq_domain; | |
| 1112 | 1113 | |
| 1113 | 1114 | #define WX_MAX_RETA_ENTRIES 128 |
| 1114 | 1115 | #define WX_RSS_INDIR_TBL_MAX 64 |
| @@ -387,6 +387,7 @@ err_dis_phy: · 386 unmodified lines | ||
| 387 | 387 | err_free_irq: |
| 388 | 388 | wx_free_irq(wx); |
| 389 | 389 | err_free_resources: |
| 390 | + wx_free_isb_resources(wx); | |
| 390 | 391 | wx_free_resources(wx); |
| 391 | 392 | return err; |
| 392 | 393 | } |
| @@ -408,6 +409,7 @@ static int ngbe_close(struct net_device *netdev) · 15 unmodified lines | ||
| 408 | 409 | |
| 409 | 410 | ngbe_down(wx); |
| 410 | 411 | wx_free_irq(wx); |
| 412 | + wx_free_isb_resources(wx); | |
| 411 | 413 | wx_free_resources(wx); |
| 412 | 414 | phylink_disconnect_phy(wx->phylink); |
| 413 | 415 | wx_control_hw(wx, false); |
| @@ -27,57 +27,19 @@ void txgbe_irq_enable(struct wx *wx, bool queues) · 26 unmodified lines | ||
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | /** |
| 30 | − * txgbe_intr - msi/legacy mode Interrupt Handler | |
| 31 | − * @irq: interrupt number | |
| 32 | − * @data: pointer to a network interface device structure | |
| 33 | − **/ | |
| 34 | −static irqreturn_t txgbe_intr(int __always_unused irq, void *data) | |
| 35 | −{ | |
| 36 | − struct wx_q_vector *q_vector; | |
| 37 | − struct wx *wx = data; | |
| 38 | − struct pci_dev *pdev; | |
| 39 | − u32 eicr; | |
| 40 | − | |
| 41 | − q_vector = wx->q_vector[0]; | |
| 42 | − pdev = wx->pdev; | |
| 43 | − | |
| 44 | − eicr = wx_misc_isb(wx, WX_ISB_VEC0); | |
| 45 | − if (!eicr) { | |
| 46 | − /* shared interrupt alert! | |
| 47 | − * the interrupt that we masked before the ICR read. | |
| 48 | − */ | |
| 49 | − if (netif_running(wx->netdev)) | |
| 50 | − txgbe_irq_enable(wx, true); | |
| 51 | − return IRQ_NONE; /* Not our interrupt */ | |
| 52 | − } | |
| 53 | − wx->isb_mem[WX_ISB_VEC0] = 0; | |
| 54 | − if (!(pdev->msi_enabled)) | |
| 55 | − wr32(wx, WX_PX_INTA, 1); | |
| 56 | − | |
| 57 | − wx->isb_mem[WX_ISB_MISC] = 0; | |
| 58 | − /* would disable interrupts here but it is auto disabled */ | |
| 59 | − napi_schedule_irqoff(&q_vector->napi); | |
| 60 | − | |
| 61 | − /* re-enable link(maybe) and non-queue interrupts, no flush. | |
| 62 | − * txgbe_poll will re-enable the queue interrupts | |
| 63 | − */ | |
| 64 | − if (netif_running(wx->netdev)) | |
| 65 | − txgbe_irq_enable(wx, false); | |
| 66 | − | |
| 67 | − return IRQ_HANDLED; | |
| 68 | −} | |
| 69 | − | |
| 70 | −/** | |
| 71 | − * txgbe_request_msix_irqs - Initialize MSI-X interrupts | |
| 30 | + * txgbe_request_queue_irqs - Initialize MSI-X queue interrupts | |
| 72 | 31 | * @wx: board private structure |
| 73 | 32 | * |
| 74 | − * Allocate MSI-X vectors and request interrupts from the kernel. | |
| 33 | + * Allocate MSI-X queue vectors and request interrupts from the kernel. | |
| 75 | 34 | **/ |
| 76 | −static int txgbe_request_msix_irqs(struct wx *wx) | |
| 35 | +int txgbe_request_queue_irqs(struct wx *wx) | |
| 77 | 36 | { |
| 78 | 37 | struct net_device *netdev = wx->netdev; |
| 79 | 38 | int vector, err; |
| 80 | 39 | |
| 40 | + if (!wx->pdev->msix_enabled) | |
| 41 | + return 0; | |
| 42 | + | |
| 81 | 43 | for (vector = 0; vector < wx->num_q_vectors; vector++) { |
| 82 | 44 | struct wx_q_vector *q_vector = wx->q_vector[vector]; |
| 83 | 45 | struct msix_entry *entry = &wx->msix_q_entries[vector]; |
| @@ -110,34 +72,6 @@ free_queue_irqs: · 26 unmodified lines | ||
| 110 | 72 | return err; |
| 111 | 73 | } |
| 112 | 74 | |
| 113 | −/** | |
| 114 | − * txgbe_request_irq - initialize interrupts | |
| 115 | − * @wx: board private structure | |
| 116 | − * | |
| 117 | − * Attempt to configure interrupts using the best available | |
| 118 | − * capabilities of the hardware and kernel. | |
| 119 | − **/ | |
| 120 | −int txgbe_request_irq(struct wx *wx) | |
| 121 | −{ | |
| 122 | − struct net_device *netdev = wx->netdev; | |
| 123 | − struct pci_dev *pdev = wx->pdev; | |
| 124 | − int err; | |
| 125 | − | |
| 126 | − if (pdev->msix_enabled) | |
| 127 | − err = txgbe_request_msix_irqs(wx); | |
| 128 | − else if (pdev->msi_enabled) | |
| 129 | − err = request_irq(wx->pdev->irq, &txgbe_intr, 0, | |
| 130 | − netdev->name, wx); | |
| 131 | − else | |
| 132 | − err = request_irq(wx->pdev->irq, &txgbe_intr, IRQF_SHARED, | |
| 133 | − netdev->name, wx); | |
| 134 | − | |
| 135 | − if (err) | |
| 136 | − wx_err(wx, "request_irq failed, Error %d\n", err); | |
| 137 | − | |
| 138 | − return err; | |
| 139 | −} | |
| 140 | − | |
| 141 | 75 | static int txgbe_request_gpio_irq(struct txgbe *txgbe) |
| 142 | 76 | { |
| 143 | 77 | txgbe->gpio_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_GPIO); |
| @@ -177,6 +111,36 @@ static const struct irq_domain_ops txgbe_misc_irq_domain_ops = { · 33 unmodified lines | ||
| 177 | 111 | }; |
| 178 | 112 | |
| 179 | 113 | static irqreturn_t txgbe_misc_irq_handle(int irq, void *data) |
| 114 | +{ | |
| 115 | + struct wx_q_vector *q_vector; | |
| 116 | + struct txgbe *txgbe = data; | |
| 117 | + struct wx *wx = txgbe->wx; | |
| 118 | + u32 eicr; | |
| 119 | + | |
| 120 | + if (wx->pdev->msix_enabled) | |
| 121 | + return IRQ_WAKE_THREAD; | |
| 122 | + | |
| 123 | + eicr = wx_misc_isb(wx, WX_ISB_VEC0); | |
| 124 | + if (!eicr) { | |
| 125 | + /* shared interrupt alert! | |
| 126 | + * the interrupt that we masked before the ICR read. | |
| 127 | + */ | |
| 128 | + if (netif_running(wx->netdev)) | |
| 129 | + txgbe_irq_enable(wx, true); | |
| 130 | + return IRQ_NONE; /* Not our interrupt */ | |
| 131 | + } | |
| 132 | + wx->isb_mem[WX_ISB_VEC0] = 0; | |
| 133 | + if (!(wx->pdev->msi_enabled)) | |
| 134 | + wr32(wx, WX_PX_INTA, 1); | |
| 135 | + | |
| 136 | + /* would disable interrupts here but it is auto disabled */ | |
| 137 | + q_vector = wx->q_vector[0]; | |
| 138 | + napi_schedule_irqoff(&q_vector->napi); | |
| 139 | + | |
| 140 | + return IRQ_WAKE_THREAD; | |
| 141 | +} | |
| 142 | + | |
| 143 | +static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data) | |
| 180 | 144 | { |
| 181 | 145 | struct txgbe *txgbe = data; |
| 182 | 146 | struct wx *wx = txgbe->wx; |
| @@ -223,6 +187,7 @@ void txgbe_free_misc_irq(struct txgbe *txgbe) · 40 unmodified lines | ||
| 223 | 187 | |
| 224 | 188 | int txgbe_setup_misc_irq(struct txgbe *txgbe) |
| 225 | 189 | { |
| 190 | + unsigned long flags = IRQF_ONESHOT; | |
| 226 | 191 | struct wx *wx = txgbe->wx; |
| 227 | 192 | int hwirq, err; |
| 228 | 193 | |
| @@ -236,14 +201,17 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe) · 7 unmodified lines | ||
| 236 | 201 | irq_create_mapping(txgbe->misc.domain, hwirq); |
| 237 | 202 | |
| 238 | 203 | txgbe->misc.chip = txgbe_irq_chip; |
| 239 | − if (wx->pdev->msix_enabled) | |
| 204 | + if (wx->pdev->msix_enabled) { | |
| 240 | 205 | txgbe->misc.irq = wx->msix_entry->vector; |
| 241 | − else | |
| 206 | + } else { | |
| 242 | 207 | txgbe->misc.irq = wx->pdev->irq; |
| 208 | + if (!wx->pdev->msi_enabled) | |
| 209 | + flags |= IRQF_SHARED; | |
| 210 | + } | |
| 243 | 211 | |
| 244 | − err = request_threaded_irq(txgbe->misc.irq, NULL, | |
| 245 | − txgbe_misc_irq_handle, | |
| 246 | − IRQF_ONESHOT, | |
| 212 | + err = request_threaded_irq(txgbe->misc.irq, txgbe_misc_irq_handle, | |
| 213 | + txgbe_misc_irq_thread_fn, | |
| 214 | + flags, | |
| 247 | 215 | wx->netdev->name, txgbe); |
| 248 | 216 | if (err) |
| 249 | 217 | goto del_misc_irq; |
| @@ -256,6 +224,8 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe) · 6 unmodified lines | ||
| 256 | 224 | if (err) |
| 257 | 225 | goto free_gpio_irq; |
| 258 | 226 | |
| 227 | + wx->misc_irq_domain = true; | |
| 228 | + | |
| 259 | 229 | return 0; |
| 260 | 230 | |
| 261 | 231 | free_gpio_irq: |
| @@ -2,6 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2015 - 2024 Beijing WangXun Technology Co., Ltd. */ |
| 3 | 3 | |
| 4 | 4 | void txgbe_irq_enable(struct wx *wx, bool queues); |
| 5 | −int txgbe_request_irq(struct wx *wx); | |
| 5 | +int txgbe_request_queue_irqs(struct wx *wx); | |
| 6 | 6 | void txgbe_free_misc_irq(struct txgbe *txgbe); |
| 7 | 7 | int txgbe_setup_misc_irq(struct txgbe *txgbe); |
| @@ -309,9 +309,9 @@ static int txgbe_open(struct net_device *netdev) · 308 unmodified lines | ||
| 309 | 309 | |
| 310 | 310 | wx_configure(wx); |
| 311 | 311 | |
| 312 | − err = txgbe_request_irq(wx); | |
| 312 | + err = txgbe_request_queue_irqs(wx); | |
| 313 | 313 | if (err) |
| 314 | − goto err_free_isb; | |
| 314 | + goto err_free_resources; | |
| 315 | 315 | |
| 316 | 316 | /* Notify the stack of the actual queue counts. */ |
| 317 | 317 | err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues); |
| @@ -328,8 +328,8 @@ static int txgbe_open(struct net_device *netdev) · 10 unmodified lines | ||
| 328 | 328 | |
| 329 | 329 | err_free_irq: |
| 330 | 330 | wx_free_irq(wx); |
| 331 | −err_free_isb: | |
| 332 | − wx_free_isb_resources(wx); | |
| 331 | +err_free_resources: | |
| 332 | + wx_free_resources(wx); | |
| 333 | 333 | err_reset: |
| 334 | 334 | txgbe_reset(wx); |
| 335 | 335 | |
| @@ -747,6 +747,7 @@ static void txgbe_remove(struct pci_dev *pdev) · 411 unmodified lines | ||
| 747 | 747 | |
| 748 | 748 | txgbe_remove_phy(txgbe); |
| 749 | 749 | txgbe_free_misc_irq(txgbe); |
| 750 | + wx_free_isb_resources(wx); | |
| 750 | 751 | |
| 751 | 752 | pci_release_selected_regions(pdev, |
| 752 | 753 | pci_select_bars(pdev, IORESOURCE_MEM)); |
| @@ -119,7 +119,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data, · 118 unmodified lines | ||
| 119 | 119 | skb->protocol = eth_type_trans(skb, ndev); |
| 120 | 120 | skb->ip_summed = CHECKSUM_NONE; |
| 121 | 121 | |
| 122 | − if (__netif_rx(skb) == NET_RX_DROP) { | |
| 122 | + if (netif_rx(skb) == NET_RX_DROP) { | |
| 123 | 123 | ndev->stats.rx_errors++; |
| 124 | 124 | ndev->stats.rx_dropped++; |
| 125 | 125 | } else { |
| @@ -6,6 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | * Author: Heiner Kallweit <hkallweit1@gmail.com> |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | +#ifndef AQUANTIA_H | |
| 10 | +#define AQUANTIA_H | |
| 11 | + | |
| 9 | 12 | #include <linux/device.h> |
| 10 | 13 | #include <linux/phy.h> |
| 11 | 14 | |
| @@ -198,3 +201,4 @@ int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index, · 186 unmodified lines | ||
| 198 | 201 | int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable); |
| 199 | 202 | int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, |
| 200 | 203 | unsigned long modes); |
| 204 | +#endif /* AQUANTIA_H */ | |
| @@ -666,7 +666,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) · 665 unmodified lines | ||
| 666 | 666 | hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES; |
| 667 | 667 | |
| 668 | 668 | if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_KEK_KCK_MATERIAL, |
| 669 | − IWL_FW_CMD_VER_UNKNOWN) == 3) | |
| 669 | + IWL_FW_CMD_VER_UNKNOWN) >= 3) | |
| 670 | 670 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK; |
| 671 | 671 | |
| 672 | 672 | if (fw_has_api(&mvm->fw->ucode_capa, |
| @@ -1698,7 +1698,8 @@ static void iwl_mvm_prevent_esr_done_wk(struct wiphy *wiphy, · 1025 unmodified lines | ||
| 1698 | 1698 | struct iwl_mvm_vif *mvmvif = |
| 1699 | 1699 | container_of(wk, struct iwl_mvm_vif, prevent_esr_done_wk.work); |
| 1700 | 1700 | struct iwl_mvm *mvm = mvmvif->mvm; |
| 1701 | − struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm); | |
| 1701 | + struct ieee80211_vif *vif = | |
| 1702 | + container_of((void *)mvmvif, struct ieee80211_vif, drv_priv); | |
| 1702 | 1703 | |
| 1703 | 1704 | guard(mvm)(mvm); |
| 1704 | 1705 | iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_PREVENTION); |
| @@ -1720,7 +1721,8 @@ static void iwl_mvm_unblock_esr_tpt(struct wiphy *wiphy, struct wiphy_work *wk) · 15 unmodified lines | ||
| 1720 | 1721 | struct iwl_mvm_vif *mvmvif = |
| 1721 | 1722 | container_of(wk, struct iwl_mvm_vif, unblock_esr_tpt_wk); |
| 1722 | 1723 | struct iwl_mvm *mvm = mvmvif->mvm; |
| 1723 | − struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm); | |
| 1724 | + struct ieee80211_vif *vif = | |
| 1725 | + container_of((void *)mvmvif, struct ieee80211_vif, drv_priv); | |
| 1724 | 1726 | |
| 1725 | 1727 | guard(mvm)(mvm); |
| 1726 | 1728 | iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT); |
| @@ -6406,11 +6408,9 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, · 4679 unmodified lines | ||
| 6406 | 6408 | if (sync) { |
| 6407 | 6409 | lockdep_assert_held(&mvm->mutex); |
| 6408 | 6410 | ret = wait_event_timeout(mvm->rx_sync_waitq, |
| 6409 | − READ_ONCE(mvm->queue_sync_state) == 0 || | |
| 6410 | − iwl_mvm_is_radio_hw_killed(mvm), | |
| 6411 | + READ_ONCE(mvm->queue_sync_state) == 0, | |
| 6411 | 6412 | SYNC_RX_QUEUE_TIMEOUT); |
| 6412 | − WARN_ONCE(!ret && !iwl_mvm_is_radio_hw_killed(mvm), | |
| 6413 | − "queue sync: failed to sync, state is 0x%lx, cookie %d\n", | |
| 6413 | + WARN_ONCE(!ret, "queue sync: failed to sync, state is 0x%lx, cookie %d\n", | |
| 6414 | 6414 | mvm->queue_sync_state, |
| 6415 | 6415 | mvm->queue_sync_cookie); |
| 6416 | 6416 | } |
| @@ -149,7 +149,7 @@ static void iwl_mvm_rx_esr_mode_notif(struct iwl_mvm *mvm, · 148 unmodified lines | ||
| 149 | 149 | struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm); |
| 150 | 150 | |
| 151 | 151 | /* FW recommendations is only for entering EMLSR */ |
| 152 | − if (!vif || iwl_mvm_vif_from_mac80211(vif)->esr_active) | |
| 152 | + if (IS_ERR_OR_NULL(vif) || iwl_mvm_vif_from_mac80211(vif)->esr_active) | |
| 153 | 153 | return; |
| 154 | 154 | |
| 155 | 155 | if (le32_to_cpu(notif->action) == ESR_RECOMMEND_ENTER) |
| @@ -1898,12 +1898,10 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) · 1742 unmodified lines | ||
| 1898 | 1898 | bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done); |
| 1899 | 1899 | bool unified = iwl_mvm_has_unified_ucode(mvm); |
| 1900 | 1900 | |
| 1901 | − if (state) { | |
| 1901 | + if (state) | |
| 1902 | 1902 | set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); |
| 1903 | − wake_up(&mvm->rx_sync_waitq); | |
| 1904 | − } else { | |
| 1903 | + else | |
| 1905 | 1904 | clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); |
| 1906 | − } | |
| 1907 | 1905 | |
| 1908 | 1906 | iwl_mvm_set_rfkill_state(mvm); |
| 1909 | 1907 | |
| @@ -557,12 +557,10 @@ struct iwl_mvm_stat_data_all_macs { · 556 unmodified lines | ||
| 557 | 557 | }; |
| 558 | 558 | |
| 559 | 559 | static void iwl_mvm_update_link_sig(struct ieee80211_vif *vif, int sig, |
| 560 | − struct iwl_mvm_vif_link_info *link_info) | |
| 560 | + struct iwl_mvm_vif_link_info *link_info, | |
| 561 | + struct ieee80211_bss_conf *bss_conf) | |
| 561 | 562 | { |
| 562 | 563 | struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(vif)->mvm; |
| 563 | − struct ieee80211_bss_conf *bss_conf = | |
| 564 | − iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, link_info->fw_link_id, | |
| 565 | − false); | |
| 566 | 564 | int thold = bss_conf->cqm_rssi_thold; |
| 567 | 565 | int hyst = bss_conf->cqm_rssi_hyst; |
| 568 | 566 | int last_event; |
| @@ -670,7 +668,7 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, · 101 unmodified lines | ||
| 670 | 668 | mvmvif->deflink.beacon_stats.num_beacons; |
| 671 | 669 | |
| 672 | 670 | /* This is used in pre-MLO API so use deflink */ |
| 673 | − iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink); | |
| 671 | + iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink, &vif->bss_conf); | |
| 674 | 672 | } |
| 675 | 673 | |
| 676 | 674 | static void iwl_mvm_stat_iterator_all_macs(void *_data, u8 *mac, |
| @@ -705,7 +703,7 @@ static void iwl_mvm_stat_iterator_all_macs(void *_data, u8 *mac, · 28 unmodified lines | ||
| 705 | 703 | sig = -le32_to_cpu(mac_stats->beacon_filter_average_energy); |
| 706 | 704 | |
| 707 | 705 | /* This is used in pre-MLO API so use deflink */ |
| 708 | − iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink); | |
| 706 | + iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink, &vif->bss_conf); | |
| 709 | 707 | } |
| 710 | 708 | |
| 711 | 709 | static inline void |
| @@ -921,7 +919,8 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm, · 209 unmodified lines | ||
| 921 | 919 | mvmvif->link[link_id]->beacon_stats.num_beacons; |
| 922 | 920 | |
| 923 | 921 | sig = -le32_to_cpu(link_stats->beacon_filter_average_energy); |
| 924 | − iwl_mvm_update_link_sig(bss_conf->vif, sig, link_info); | |
| 922 | + iwl_mvm_update_link_sig(bss_conf->vif, sig, link_info, | |
| 923 | + bss_conf); | |
| 925 | 924 | |
| 926 | 925 | if (WARN_ONCE(mvmvif->id >= MAC_INDEX_AUX, |
| 927 | 926 | "invalid mvmvif id: %d", mvmvif->id)) |
| @@ -967,7 +966,7 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm) · 39 unmodified lines | ||
| 967 | 966 | |
| 968 | 967 | lockdep_assert_held(&mvm->mutex); |
| 969 | 968 | |
| 970 | − if (!bss_vif) | |
| 969 | + if (IS_ERR_OR_NULL(bss_vif)) | |
| 971 | 970 | return; |
| 972 | 971 | |
| 973 | 972 | mvmvif = iwl_mvm_vif_from_mac80211(bss_vif); |
| @@ -382,7 +382,8 @@ wilc_parse_join_bss_param(struct cfg80211_bss *bss, · 381 unmodified lines | ||
| 382 | 382 | struct ieee80211_p2p_noa_attr noa_attr; |
| 383 | 383 | const struct cfg80211_bss_ies *ies; |
| 384 | 384 | struct wilc_join_bss_param *param; |
| 385 | − u8 rates_len = 0, ies_len; | |
| 385 | + u8 rates_len = 0; | |
| 386 | + int ies_len; | |
| 386 | 387 | int ret; |
| 387 | 388 | |
| 388 | 389 | param = kzalloc(sizeof(*param), GFP_KERNEL); |
| @@ -1602,4 +1602,5 @@ static struct platform_driver apple_nvme_driver = { · 1601 unmodified lines | ||
| 1602 | 1602 | module_platform_driver(apple_nvme_driver); |
| 1603 | 1603 | |
| 1604 | 1604 | MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>"); |
| 1605 | +MODULE_DESCRIPTION("Apple ANS NVM Express device driver"); | |
| 1605 | 1606 | MODULE_LICENSE("GPL"); |
| @@ -502,7 +502,7 @@ static inline bool nvme_ns_head_multipath(struct nvme_ns_head *head) · 501 unmodified lines | ||
| 502 | 502 | enum nvme_ns_features { |
| 503 | 503 | NVME_NS_EXT_LBAS = 1 << 0, /* support extended LBA format */ |
| 504 | 504 | NVME_NS_METADATA_SUPPORTED = 1 << 1, /* support getting generated md */ |
| 505 | − NVME_NS_DEAC, /* DEAC bit in Write Zeores supported */ | |
| 505 | + NVME_NS_DEAC = 1 << 2, /* DEAC bit in Write Zeores supported */ | |
| 506 | 506 | }; |
| 507 | 507 | |
| 508 | 508 | struct nvme_ns { |
| @@ -410,7 +410,29 @@ static ssize_t nvmet_addr_tsas_show(struct config_item *item, · 409 unmodified lines | ||
| 410 | 410 | return sprintf(page, "%s\n", nvmet_addr_tsas_rdma[i].name); |
| 411 | 411 | } |
| 412 | 412 | } |
| 413 | − return sprintf(page, "reserved\n"); | |
| 413 | + return sprintf(page, "\n"); | |
| 414 | +} | |
| 415 | + | |
| 416 | +static u8 nvmet_addr_tsas_rdma_store(const char *page) | |
| 417 | +{ | |
| 418 | + int i; | |
| 419 | + | |
| 420 | + for (i = 0; i < ARRAY_SIZE(nvmet_addr_tsas_rdma); i++) { | |
| 421 | + if (sysfs_streq(page, nvmet_addr_tsas_rdma[i].name)) | |
| 422 | + return nvmet_addr_tsas_rdma[i].type; | |
| 423 | + } | |
| 424 | + return NVMF_RDMA_QPTYPE_INVALID; | |
| 425 | +} | |
| 426 | + | |
| 427 | +static u8 nvmet_addr_tsas_tcp_store(const char *page) | |
| 428 | +{ | |
| 429 | + int i; | |
| 430 | + | |
| 431 | + for (i = 0; i < ARRAY_SIZE(nvmet_addr_tsas_tcp); i++) { | |
| 432 | + if (sysfs_streq(page, nvmet_addr_tsas_tcp[i].name)) | |
| 433 | + return nvmet_addr_tsas_tcp[i].type; | |
| 434 | + } | |
| 435 | + return NVMF_TCP_SECTYPE_INVALID; | |
| 414 | 436 | } |
| 415 | 437 | |
| 416 | 438 | static ssize_t nvmet_addr_tsas_store(struct config_item *item, |
| @@ -418,20 +440,19 @@ static ssize_t nvmet_addr_tsas_store(struct config_item *item, · 1 unmodified line | ||
| 418 | 440 | { |
| 419 | 441 | struct nvmet_port *port = to_nvmet_port(item); |
| 420 | 442 | u8 treq = nvmet_port_disc_addr_treq_mask(port); |
| 421 | − u8 sectype; | |
| 422 | − int i; | |
| 443 | + u8 sectype, qptype; | |
| 423 | 444 | |
| 424 | 445 | if (nvmet_is_port_enabled(port, __func__)) |
| 425 | 446 | return -EACCES; |
| 426 | 447 | |
| 427 | − if (port->disc_addr.trtype != NVMF_TRTYPE_TCP) | |
| 428 | − return -EINVAL; | |
| 429 | − | |
| 430 | − for (i = 0; i < ARRAY_SIZE(nvmet_addr_tsas_tcp); i++) { | |
| 431 | − if (sysfs_streq(page, nvmet_addr_tsas_tcp[i].name)) { | |
| 432 | − sectype = nvmet_addr_tsas_tcp[i].type; | |
| 448 | + if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA) { | |
| 449 | + qptype = nvmet_addr_tsas_rdma_store(page); | |
| 450 | + if (qptype == port->disc_addr.tsas.rdma.qptype) | |
| 451 | + return count; | |
| 452 | + } else if (port->disc_addr.trtype == NVMF_TRTYPE_TCP) { | |
| 453 | + sectype = nvmet_addr_tsas_tcp_store(page); | |
| 454 | + if (sectype != NVMF_TCP_SECTYPE_INVALID) | |
| 433 | 455 | goto found; |
| 434 | − } | |
| 435 | 456 | } |
| 436 | 457 | |
| 437 | 458 | pr_err("Invalid value '%s' for tsas\n", page); |
| @@ -148,7 +148,7 @@ struct nvmet_fc_tgt_queue { · 147 unmodified lines | ||
| 148 | 148 | struct workqueue_struct *work_q; |
| 149 | 149 | struct kref ref; |
| 150 | 150 | /* array of fcp_iods */ |
| 151 | − struct nvmet_fc_fcp_iod fod[] __counted_by(sqsize); | |
| 151 | + struct nvmet_fc_fcp_iod fod[] /* __counted_by(sqsize) */; | |
| 152 | 152 | } __aligned(sizeof(unsigned long long)); |
| 153 | 153 | |
| 154 | 154 | struct nvmet_fc_hostport { |
| @@ -352,7 +352,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, · 351 unmodified lines | ||
| 352 | 352 | struct irq_affinity *affd) |
| 353 | 353 | { |
| 354 | 354 | struct irq_affinity_desc *masks = NULL; |
| 355 | − struct msi_desc *entry; | |
| 355 | + struct msi_desc *entry, desc; | |
| 356 | 356 | int ret; |
| 357 | 357 | |
| 358 | 358 | /* Reject multi-MSI early on irq domain enabled architectures */ |
| @@ -377,6 +377,12 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, · 18 unmodified lines | ||
| 377 | 377 | /* All MSIs are unmasked by default; mask them all */ |
| 378 | 378 | entry = msi_first_desc(&dev->dev, MSI_DESC_ALL); |
| 379 | 379 | pci_msi_mask(entry, msi_multi_mask(entry)); |
| 380 | + /* | |
| 381 | + * Copy the MSI descriptor for the error path because | |
| 382 | + * pci_msi_setup_msi_irqs() will free it for the hierarchical | |
| 383 | + * interrupt domain case. | |
| 384 | + */ | |
| 385 | + memcpy(&desc, entry, sizeof(desc)); | |
| 380 | 386 | |
| 381 | 387 | /* Configure MSI capability structure */ |
| 382 | 388 | ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); |
| @@ -396,7 +402,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, · 13 unmodified lines | ||
| 396 | 402 | goto unlock; |
| 397 | 403 | |
| 398 | 404 | err: |
| 399 | − pci_msi_unmask(entry, msi_multi_mask(entry)); | |
| 405 | + pci_msi_unmask(&desc, msi_multi_mask(&desc)); | |
| 400 | 406 | pci_free_msi_irqs(dev); |
| 401 | 407 | fail: |
| 402 | 408 | dev->msi_enabled = 0; |
| @@ -1198,6 +1198,7 @@ static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201) · 1197 unmodified lines | ||
| 1198 | 1198 | static int nvsw_sn2201_probe(struct platform_device *pdev) |
| 1199 | 1199 | { |
| 1200 | 1200 | struct nvsw_sn2201 *nvsw_sn2201; |
| 1201 | + int ret; | |
| 1201 | 1202 | |
| 1202 | 1203 | nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL); |
| 1203 | 1204 | if (!nvsw_sn2201) |
| @@ -1205,8 +1206,10 @@ static int nvsw_sn2201_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 1205 | 1206 | |
| 1206 | 1207 | nvsw_sn2201->dev = &pdev->dev; |
| 1207 | 1208 | platform_set_drvdata(pdev, nvsw_sn2201); |
| 1208 | − platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources, | |
| 1209 | + ret = platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources, | |
| 1209 | 1210 | ARRAY_SIZE(nvsw_sn2201_lpc_io_resources)); |
| 1211 | + if (ret) | |
| 1212 | + return ret; | |
| 1210 | 1213 | |
| 1211 | 1214 | nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR; |
| 1212 | 1215 | nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo; |
| @@ -171,6 +171,7 @@ static void __exit amilo_rfkill_exit(void) · 170 unmodified lines | ||
| 171 | 171 | } |
| 172 | 172 | |
| 173 | 173 | MODULE_AUTHOR("Ben Hutchings <ben@decadent.org.uk>"); |
| 174 | +MODULE_DESCRIPTION("Fujitsu-Siemens Amilo rfkill support"); | |
| 174 | 175 | MODULE_LICENSE("GPL"); |
| 175 | 176 | MODULE_DEVICE_TABLE(dmi, amilo_rfkill_id_table); |
| 176 | 177 | |
| @@ -49,4 +49,5 @@ int fw_attributes_class_put(void) · 48 unmodified lines | ||
| 49 | 49 | EXPORT_SYMBOL_GPL(fw_attributes_class_put); |
| 50 | 50 | |
| 51 | 51 | MODULE_AUTHOR("Mark Pearson <markpearson@lenovo.com>"); |
| 52 | +MODULE_DESCRIPTION("Firmware attributes class helper module"); | |
| 52 | 53 | MODULE_LICENSE("GPL"); |
| @@ -29,6 +29,7 @@ static bool debug; · 28 unmodified lines | ||
| 29 | 29 | module_param(debug, bool, 0644); |
| 30 | 30 | MODULE_PARM_DESC(debug, "Show debug output"); |
| 31 | 31 | |
| 32 | +MODULE_DESCRIPTION("IBM Premium Real Time Mode (PRTM) driver"); | |
| 32 | 33 | MODULE_LICENSE("GPL"); |
| 33 | 34 | MODULE_AUTHOR("Keith Mannthey <kmmanth@us.ibm.com>"); |
| 34 | 35 | MODULE_AUTHOR("Vernon Mauery <vernux@us.ibm.com>"); |
| @@ -38,6 +38,7 @@ MODULE_PARM_DESC(enable_sw_tablet_mode, · 37 unmodified lines | ||
| 38 | 38 | /* When NOT in tablet mode, VGBS returns with the flag 0x40 */ |
| 39 | 39 | #define TABLET_MODE_FLAG BIT(6) |
| 40 | 40 | |
| 41 | +MODULE_DESCRIPTION("Intel HID Event hotkey driver"); | |
| 41 | 42 | MODULE_LICENSE("GPL"); |
| 42 | 43 | MODULE_AUTHOR("Alex Hung"); |
| 43 | 44 | |
| @@ -86,4 +86,5 @@ static void __exit pmc_core_platform_exit(void) · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | module_init(pmc_core_platform_init); |
| 88 | 88 | module_exit(pmc_core_platform_exit); |
| 89 | +MODULE_DESCRIPTION("Intel PMC Core platform driver"); | |
| 89 | 90 | MODULE_LICENSE("GPL v2"); |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | #include <linux/slab.h> |
| 9 | 9 | |
| 10 | +MODULE_DESCRIPTION("Intel Rapid Start Technology Driver"); | |
| 10 | 11 | MODULE_LICENSE("GPL"); |
| 11 | 12 | |
| 12 | 13 | static ssize_t irst_show_wakeup_events(struct device *dev, |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/acpi.h> |
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | |
| 9 | +MODULE_DESCRIPTION("Intel Smart Connect disabling driver"); | |
| 9 | 10 | MODULE_LICENSE("GPL"); |
| 10 | 11 | |
| 11 | 12 | static int smartconnect_acpi_init(struct acpi_device *acpi) |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #define VGBS_TABLET_MODE_FLAGS (VGBS_TABLET_MODE_FLAG | VGBS_TABLET_MODE_FLAG_ALT) |
| 26 | 26 | |
| 27 | +MODULE_DESCRIPTION("Intel Virtual Button driver"); | |
| 27 | 28 | MODULE_LICENSE("GPL"); |
| 28 | 29 | MODULE_AUTHOR("AceLan Kao"); |
| 29 | 30 | |
| @@ -39,8 +39,6 @@ MODULE_LICENSE("GPL"); · 38 unmodified lines | ||
| 39 | 39 | #define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210" |
| 40 | 40 | #define WMI_EVENT_GUID WMI_EVENT_GUID0 |
| 41 | 41 | |
| 42 | −#define WMAB_METHOD "\\XINI.WMAB" | |
| 43 | −#define WMBB_METHOD "\\XINI.WMBB" | |
| 44 | 42 | #define SB_GGOV_METHOD "\\_SB.GGOV" |
| 45 | 43 | #define GOV_TLED 0x2020008 |
| 46 | 44 | #define WM_GET 1 |
| @@ -74,7 +72,7 @@ static u32 inited; · 27 unmodified lines | ||
| 74 | 72 | |
| 75 | 73 | static int battery_limit_use_wmbb; |
| 76 | 74 | static struct led_classdev kbd_backlight; |
| 77 | −static enum led_brightness get_kbd_backlight_level(void); | |
| 75 | +static enum led_brightness get_kbd_backlight_level(struct device *dev); | |
| 78 | 76 | |
| 79 | 77 | static const struct key_entry wmi_keymap[] = { |
| 80 | 78 | {KE_KEY, 0x70, {KEY_F15} }, /* LG control panel (F1) */ |
| @@ -84,7 +82,6 @@ static const struct key_entry wmi_keymap[] = { · 3 unmodified lines | ||
| 84 | 82 | * this key both sends an event and |
| 85 | 83 | * changes backlight level. |
| 86 | 84 | */ |
| 87 | − {KE_KEY, 0x80, {KEY_RFKILL} }, | |
| 88 | 85 | {KE_END, 0} |
| 89 | 86 | }; |
| 90 | 87 | |
| @@ -128,11 +125,10 @@ static int ggov(u32 arg0) · 37 unmodified lines | ||
| 128 | 125 | return res; |
| 129 | 126 | } |
| 130 | 127 | |
| 131 | −static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2) | |
| 128 | +static union acpi_object *lg_wmab(struct device *dev, u32 method, u32 arg1, u32 arg2) | |
| 132 | 129 | { |
| 133 | 130 | union acpi_object args[3]; |
| 134 | 131 | acpi_status status; |
| 135 | − acpi_handle handle; | |
| 136 | 132 | struct acpi_object_list arg; |
| 137 | 133 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 138 | 134 | |
| @@ -143,29 +139,22 @@ static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2) · 4 unmodified lines | ||
| 143 | 139 | args[2].type = ACPI_TYPE_INTEGER; |
| 144 | 140 | args[2].integer.value = arg2; |
| 145 | 141 | |
| 146 | − status = acpi_get_handle(NULL, (acpi_string) WMAB_METHOD, &handle); | |
| 147 | − if (ACPI_FAILURE(status)) { | |
| 148 | − pr_err("Cannot get handle"); | |
| 149 | − return NULL; | |
| 150 | − } | |
| 151 | − | |
| 152 | 142 | arg.count = 3; |
| 153 | 143 | arg.pointer = args; |
| 154 | 144 | |
| 155 | − status = acpi_evaluate_object(handle, NULL, &arg, &buffer); | |
| 145 | + status = acpi_evaluate_object(ACPI_HANDLE(dev), "WMAB", &arg, &buffer); | |
| 156 | 146 | if (ACPI_FAILURE(status)) { |
| 157 | − acpi_handle_err(handle, "WMAB: call failed.\n"); | |
| 147 | + dev_err(dev, "WMAB: call failed.\n"); | |
| 158 | 148 | return NULL; |
| 159 | 149 | } |
| 160 | 150 | |
| 161 | 151 | return buffer.pointer; |
| 162 | 152 | } |
| 163 | 153 | |
| 164 | −static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2) | |
| 154 | +static union acpi_object *lg_wmbb(struct device *dev, u32 method_id, u32 arg1, u32 arg2) | |
| 165 | 155 | { |
| 166 | 156 | union acpi_object args[3]; |
| 167 | 157 | acpi_status status; |
| 168 | − acpi_handle handle; | |
| 169 | 158 | struct acpi_object_list arg; |
| 170 | 159 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 171 | 160 | u8 buf[32]; |
| @@ -181,18 +170,12 @@ static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2) · 9 unmodified lines | ||
| 181 | 170 | args[2].buffer.length = 32; |
| 182 | 171 | args[2].buffer.pointer = buf; |
| 183 | 172 | |
| 184 | − status = acpi_get_handle(NULL, (acpi_string)WMBB_METHOD, &handle); | |
| 185 | − if (ACPI_FAILURE(status)) { | |
| 186 | − pr_err("Cannot get handle"); | |
| 187 | − return NULL; | |
| 188 | − } | |
| 189 | − | |
| 190 | 173 | arg.count = 3; |
| 191 | 174 | arg.pointer = args; |
| 192 | 175 | |
| 193 | − status = acpi_evaluate_object(handle, NULL, &arg, &buffer); | |
| 176 | + status = acpi_evaluate_object(ACPI_HANDLE(dev), "WMBB", &arg, &buffer); | |
| 194 | 177 | if (ACPI_FAILURE(status)) { |
| 195 | − acpi_handle_err(handle, "WMAB: call failed.\n"); | |
| 178 | + dev_err(dev, "WMBB: call failed.\n"); | |
| 196 | 179 | return NULL; |
| 197 | 180 | } |
| 198 | 181 | |
| @@ -223,7 +206,7 @@ static void wmi_notify(u32 value, void *context) · 24 unmodified lines | ||
| 223 | 206 | |
| 224 | 207 | if (eventcode == 0x10000000) { |
| 225 | 208 | led_classdev_notify_brightness_hw_changed( |
| 226 | − &kbd_backlight, get_kbd_backlight_level()); | |
| 209 | + &kbd_backlight, get_kbd_backlight_level(kbd_backlight.dev->parent)); | |
| 227 | 210 | } else { |
| 228 | 211 | key = sparse_keymap_entry_from_scancode( |
| 229 | 212 | wmi_input_dev, eventcode); |
| @@ -272,14 +255,7 @@ static void wmi_input_setup(void) · 42 unmodified lines | ||
| 272 | 255 | |
| 273 | 256 | static void acpi_notify(struct acpi_device *device, u32 event) |
| 274 | 257 | { |
| 275 | − struct key_entry *key; | |
| 276 | − | |
| 277 | 258 | acpi_handle_debug(device->handle, "notify: %d\n", event); |
| 278 | − if (inited & INIT_SPARSE_KEYMAP) { | |
| 279 | − key = sparse_keymap_entry_from_scancode(wmi_input_dev, 0x80); | |
| 280 | − if (key && key->type == KE_KEY) | |
| 281 | − sparse_keymap_report_entry(wmi_input_dev, key, 1, true); | |
| 282 | − } | |
| 283 | 259 | } |
| 284 | 260 | |
| 285 | 261 | static ssize_t fan_mode_store(struct device *dev, |
| @@ -295,7 +271,7 @@ static ssize_t fan_mode_store(struct device *dev, · 9 unmodified lines | ||
| 295 | 271 | if (ret) |
| 296 | 272 | return ret; |
| 297 | 273 | |
| 298 | − r = lg_wmab(WM_FAN_MODE, WM_GET, 0); | |
| 274 | + r = lg_wmab(dev, WM_FAN_MODE, WM_GET, 0); | |
| 299 | 275 | if (!r) |
| 300 | 276 | return -EIO; |
| 301 | 277 | |
| @@ -306,9 +282,9 @@ static ssize_t fan_mode_store(struct device *dev, · 4 unmodified lines | ||
| 306 | 282 | |
| 307 | 283 | m = r->integer.value; |
| 308 | 284 | kfree(r); |
| 309 | − r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4)); | |
| 285 | + r = lg_wmab(dev, WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4)); | |
| 310 | 286 | kfree(r); |
| 311 | − r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value); | |
| 287 | + r = lg_wmab(dev, WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value); | |
| 312 | 288 | kfree(r); |
| 313 | 289 | |
| 314 | 290 | return count; |
| @@ -320,7 +296,7 @@ static ssize_t fan_mode_show(struct device *dev, · 5 unmodified lines | ||
| 320 | 296 | unsigned int status; |
| 321 | 297 | union acpi_object *r; |
| 322 | 298 | |
| 323 | − r = lg_wmab(WM_FAN_MODE, WM_GET, 0); | |
| 299 | + r = lg_wmab(dev, WM_FAN_MODE, WM_GET, 0); | |
| 324 | 300 | if (!r) |
| 325 | 301 | return -EIO; |
| 326 | 302 | |
| @@ -347,7 +323,7 @@ static ssize_t usb_charge_store(struct device *dev, · 20 unmodified lines | ||
| 347 | 323 | if (ret) |
| 348 | 324 | return ret; |
| 349 | 325 | |
| 350 | − r = lg_wmbb(WMBB_USB_CHARGE, WM_SET, value); | |
| 326 | + r = lg_wmbb(dev, WMBB_USB_CHARGE, WM_SET, value); | |
| 351 | 327 | if (!r) |
| 352 | 328 | return -EIO; |
| 353 | 329 | |
| @@ -361,7 +337,7 @@ static ssize_t usb_charge_show(struct device *dev, · 7 unmodified lines | ||
| 361 | 337 | unsigned int status; |
| 362 | 338 | union acpi_object *r; |
| 363 | 339 | |
| 364 | − r = lg_wmbb(WMBB_USB_CHARGE, WM_GET, 0); | |
| 340 | + r = lg_wmbb(dev, WMBB_USB_CHARGE, WM_GET, 0); | |
| 365 | 341 | if (!r) |
| 366 | 342 | return -EIO; |
| 367 | 343 | |
| @@ -389,7 +365,7 @@ static ssize_t reader_mode_store(struct device *dev, · 21 unmodified lines | ||
| 389 | 365 | if (ret) |
| 390 | 366 | return ret; |
| 391 | 367 | |
| 392 | − r = lg_wmab(WM_READER_MODE, WM_SET, value); | |
| 368 | + r = lg_wmab(dev, WM_READER_MODE, WM_SET, value); | |
| 393 | 369 | if (!r) |
| 394 | 370 | return -EIO; |
| 395 | 371 | |
| @@ -403,7 +379,7 @@ static ssize_t reader_mode_show(struct device *dev, · 7 unmodified lines | ||
| 403 | 379 | unsigned int status; |
| 404 | 380 | union acpi_object *r; |
| 405 | 381 | |
| 406 | − r = lg_wmab(WM_READER_MODE, WM_GET, 0); | |
| 382 | + r = lg_wmab(dev, WM_READER_MODE, WM_GET, 0); | |
| 407 | 383 | if (!r) |
| 408 | 384 | return -EIO; |
| 409 | 385 | |
| @@ -431,7 +407,7 @@ static ssize_t fn_lock_store(struct device *dev, · 21 unmodified lines | ||
| 431 | 407 | if (ret) |
| 432 | 408 | return ret; |
| 433 | 409 | |
| 434 | − r = lg_wmab(WM_FN_LOCK, WM_SET, value); | |
| 410 | + r = lg_wmab(dev, WM_FN_LOCK, WM_SET, value); | |
| 435 | 411 | if (!r) |
| 436 | 412 | return -EIO; |
| 437 | 413 | |
| @@ -445,7 +421,7 @@ static ssize_t fn_lock_show(struct device *dev, · 7 unmodified lines | ||
| 445 | 421 | unsigned int status; |
| 446 | 422 | union acpi_object *r; |
| 447 | 423 | |
| 448 | − r = lg_wmab(WM_FN_LOCK, WM_GET, 0); | |
| 424 | + r = lg_wmab(dev, WM_FN_LOCK, WM_GET, 0); | |
| 449 | 425 | if (!r) |
| 450 | 426 | return -EIO; |
| 451 | 427 | |
| @@ -475,9 +451,9 @@ static ssize_t charge_control_end_threshold_store(struct device *dev, · 23 unmodified lines | ||
| 475 | 451 | union acpi_object *r; |
| 476 | 452 | |
| 477 | 453 | if (battery_limit_use_wmbb) |
| 478 | − r = lg_wmbb(WMBB_BATT_LIMIT, WM_SET, value); | |
| 454 | + r = lg_wmbb(&pf_device->dev, WMBB_BATT_LIMIT, WM_SET, value); | |
| 479 | 455 | else |
| 480 | − r = lg_wmab(WM_BATT_LIMIT, WM_SET, value); | |
| 456 | + r = lg_wmab(&pf_device->dev, WM_BATT_LIMIT, WM_SET, value); | |
| 481 | 457 | if (!r) |
| 482 | 458 | return -EIO; |
| 483 | 459 | |
| @@ -496,7 +472,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device, · 12 unmodified lines | ||
| 496 | 472 | union acpi_object *r; |
| 497 | 473 | |
| 498 | 474 | if (battery_limit_use_wmbb) { |
| 499 | − r = lg_wmbb(WMBB_BATT_LIMIT, WM_GET, 0); | |
| 475 | + r = lg_wmbb(&pf_device->dev, WMBB_BATT_LIMIT, WM_GET, 0); | |
| 500 | 476 | if (!r) |
| 501 | 477 | return -EIO; |
| 502 | 478 | |
| @@ -507,7 +483,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device, · 4 unmodified lines | ||
| 507 | 483 | |
| 508 | 484 | status = r->buffer.pointer[0x10]; |
| 509 | 485 | } else { |
| 510 | − r = lg_wmab(WM_BATT_LIMIT, WM_GET, 0); | |
| 486 | + r = lg_wmab(&pf_device->dev, WM_BATT_LIMIT, WM_GET, 0); | |
| 511 | 487 | if (!r) |
| 512 | 488 | return -EIO; |
| 513 | 489 | |
| @@ -586,7 +562,7 @@ static void tpad_led_set(struct led_classdev *cdev, · 72 unmodified lines | ||
| 586 | 562 | { |
| 587 | 563 | union acpi_object *r; |
| 588 | 564 | |
| 589 | − r = lg_wmab(WM_TLED, WM_SET, brightness > LED_OFF); | |
| 565 | + r = lg_wmab(cdev->dev->parent, WM_TLED, WM_SET, brightness > LED_OFF); | |
| 590 | 566 | kfree(r); |
| 591 | 567 | } |
| 592 | 568 | |
| @@ -608,16 +584,16 @@ static void kbd_backlight_set(struct led_classdev *cdev, · 15 unmodified lines | ||
| 608 | 584 | val = 0; |
| 609 | 585 | if (brightness >= LED_FULL) |
| 610 | 586 | val = 0x24; |
| 611 | − r = lg_wmab(WM_KEY_LIGHT, WM_SET, val); | |
| 587 | + r = lg_wmab(cdev->dev->parent, WM_KEY_LIGHT, WM_SET, val); | |
| 612 | 588 | kfree(r); |
| 613 | 589 | } |
| 614 | 590 | |
| 615 | −static enum led_brightness get_kbd_backlight_level(void) | |
| 591 | +static enum led_brightness get_kbd_backlight_level(struct device *dev) | |
| 616 | 592 | { |
| 617 | 593 | union acpi_object *r; |
| 618 | 594 | int val; |
| 619 | 595 | |
| 620 | − r = lg_wmab(WM_KEY_LIGHT, WM_GET, 0); | |
| 596 | + r = lg_wmab(dev, WM_KEY_LIGHT, WM_GET, 0); | |
| 621 | 597 | |
| 622 | 598 | if (!r) |
| 623 | 599 | return LED_OFF; |
| @@ -645,7 +621,7 @@ static enum led_brightness get_kbd_backlight_level(void) · 21 unmodified lines | ||
| 645 | 621 | |
| 646 | 622 | static enum led_brightness kbd_backlight_get(struct led_classdev *cdev) |
| 647 | 623 | { |
| 648 | − return get_kbd_backlight_level(); | |
| 624 | + return get_kbd_backlight_level(cdev->dev->parent); | |
| 649 | 625 | } |
| 650 | 626 | |
| 651 | 627 | static LED_DEVICE(kbd_backlight, 255, LED_BRIGHT_HW_CHANGED); |
| @@ -672,6 +648,11 @@ static struct platform_driver pf_driver = { · 20 unmodified lines | ||
| 672 | 648 | |
| 673 | 649 | static int acpi_add(struct acpi_device *device) |
| 674 | 650 | { |
| 651 | + struct platform_device_info pdev_info = { | |
| 652 | + .fwnode = acpi_fwnode_handle(device), | |
| 653 | + .name = PLATFORM_NAME, | |
| 654 | + .id = PLATFORM_DEVID_NONE, | |
| 655 | + }; | |
| 675 | 656 | int ret; |
| 676 | 657 | const char *product; |
| 677 | 658 | int year = 2017; |
| @@ -683,9 +664,7 @@ static int acpi_add(struct acpi_device *device) · 5 unmodified lines | ||
| 683 | 664 | if (ret) |
| 684 | 665 | return ret; |
| 685 | 666 | |
| 686 | − pf_device = platform_device_register_simple(PLATFORM_NAME, | |
| 687 | − PLATFORM_DEVID_NONE, | |
| 688 | − NULL, 0); | |
| 667 | + pf_device = platform_device_register_full(&pdev_info); | |
| 689 | 668 | if (IS_ERR(pf_device)) { |
| 690 | 669 | ret = PTR_ERR(pf_device); |
| 691 | 670 | pf_device = NULL; |
| @@ -776,7 +755,7 @@ static void acpi_remove(struct acpi_device *device) · 84 unmodified lines | ||
| 776 | 755 | } |
| 777 | 756 | |
| 778 | 757 | static const struct acpi_device_id device_ids[] = { |
| 779 | − {"LGEX0815", 0}, | |
| 758 | + {"LGEX0820", 0}, | |
| 780 | 759 | {"", 0} |
| 781 | 760 | }; |
| 782 | 761 | MODULE_DEVICE_TABLE(acpi, device_ids); |
| @@ -45,6 +45,7 @@ static struct platform_driver simatic_ipc_batt_driver = { · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | module_platform_driver(simatic_ipc_batt_driver); |
| 47 | 47 | |
| 48 | +MODULE_DESCRIPTION("CMOS Battery monitoring for Simatic IPCs based on Apollo Lake GPIO"); | |
| 48 | 49 | MODULE_LICENSE("GPL"); |
| 49 | 50 | MODULE_ALIAS("platform:" KBUILD_MODNAME); |
| 50 | 51 | MODULE_SOFTDEP("pre: simatic-ipc-batt platform:apollolake-pinctrl"); |
| @@ -45,6 +45,7 @@ static struct platform_driver simatic_ipc_batt_driver = { · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | module_platform_driver(simatic_ipc_batt_driver); |
| 47 | 47 | |
| 48 | +MODULE_DESCRIPTION("CMOS Battery monitoring for Simatic IPCs based on Elkhart Lake GPIO"); | |
| 48 | 49 | MODULE_LICENSE("GPL"); |
| 49 | 50 | MODULE_ALIAS("platform:" KBUILD_MODNAME); |
| 50 | 51 | MODULE_SOFTDEP("pre: simatic-ipc-batt platform:elkhartlake-pinctrl"); |
| @@ -81,6 +81,7 @@ static struct platform_driver simatic_ipc_batt_driver = { · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | module_platform_driver(simatic_ipc_batt_driver); |
| 83 | 83 | |
| 84 | +MODULE_DESCRIPTION("CMOS Battery monitoring for Simatic IPCs based on Nuvoton GPIO"); | |
| 84 | 85 | MODULE_LICENSE("GPL"); |
| 85 | 86 | MODULE_ALIAS("platform:" KBUILD_MODNAME); |
| 86 | 87 | MODULE_SOFTDEP("pre: simatic-ipc-batt gpio_f7188x platform:elkhartlake-pinctrl platform:alderlake-pinctrl"); |
| @@ -247,6 +247,7 @@ static struct platform_driver simatic_ipc_batt_driver = { · 246 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | module_platform_driver(simatic_ipc_batt_driver); |
| 249 | 249 | |
| 250 | +MODULE_DESCRIPTION("CMOS core battery driver for Siemens Simatic IPCs"); | |
| 250 | 251 | MODULE_LICENSE("GPL"); |
| 251 | 252 | MODULE_ALIAS("platform:" KBUILD_MODNAME); |
| 252 | 253 | MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>"); |
| @@ -231,6 +231,7 @@ static void __exit simatic_ipc_exit_module(void) · 230 unmodified lines | ||
| 231 | 231 | module_init(simatic_ipc_init_module); |
| 232 | 232 | module_exit(simatic_ipc_exit_module); |
| 233 | 233 | |
| 234 | +MODULE_DESCRIPTION("Siemens SIMATIC IPC platform driver"); | |
| 234 | 235 | MODULE_LICENSE("GPL v2"); |
| 235 | 236 | MODULE_AUTHOR("Gerd Haeussler <gerd.haeussler.ext@siemens.com>"); |
| 236 | 237 | MODULE_ALIAS("dmi:*:svnSIEMENSAG:*"); |
| @@ -3271,7 +3271,7 @@ static const char *find_hci_method(acpi_handle handle) · 3270 unmodified lines | ||
| 3271 | 3271 | */ |
| 3272 | 3272 | #define QUIRK_HCI_HOTKEY_QUICKSTART BIT(1) |
| 3273 | 3273 | |
| 3274 | −static const struct dmi_system_id toshiba_dmi_quirks[] = { | |
| 3274 | +static const struct dmi_system_id toshiba_dmi_quirks[] __initconst = { | |
| 3275 | 3275 | { |
| 3276 | 3276 | /* Toshiba Portégé R700 */ |
| 3277 | 3277 | /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ |
| @@ -3306,8 +3306,6 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) · 28 unmodified lines | ||
| 3306 | 3306 | struct toshiba_acpi_dev *dev; |
| 3307 | 3307 | const char *hci_method; |
| 3308 | 3308 | u32 dummy; |
| 3309 | − const struct dmi_system_id *dmi_id; | |
| 3310 | − long quirks = 0; | |
| 3311 | 3309 | int ret = 0; |
| 3312 | 3310 | |
| 3313 | 3311 | if (toshiba_acpi) |
| @@ -3460,16 +3458,6 @@ iio_error: · 146 unmodified lines | ||
| 3460 | 3458 | } |
| 3461 | 3459 | #endif |
| 3462 | 3460 | |
| 3463 | − dmi_id = dmi_first_match(toshiba_dmi_quirks); | |
| 3464 | − if (dmi_id) | |
| 3465 | − quirks = (long)dmi_id->driver_data; | |
| 3466 | − | |
| 3467 | − if (turn_on_panel_on_resume == -1) | |
| 3468 | − turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME); | |
| 3469 | − | |
| 3470 | − if (hci_hotkey_quickstart == -1) | |
| 3471 | − hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART); | |
| 3472 | − | |
| 3473 | 3461 | toshiba_wwan_available(dev); |
| 3474 | 3462 | if (dev->wwan_supported) |
| 3475 | 3463 | toshiba_acpi_setup_wwan_rfkill(dev); |
| @@ -3618,10 +3606,27 @@ static struct acpi_driver toshiba_acpi_driver = { · 142 unmodified lines | ||
| 3618 | 3606 | .drv.pm = &toshiba_acpi_pm, |
| 3619 | 3607 | }; |
| 3620 | 3608 | |
| 3609 | +static void __init toshiba_dmi_init(void) | |
| 3610 | +{ | |
| 3611 | + const struct dmi_system_id *dmi_id; | |
| 3612 | + long quirks = 0; | |
| 3613 | + | |
| 3614 | + dmi_id = dmi_first_match(toshiba_dmi_quirks); | |
| 3615 | + if (dmi_id) | |
| 3616 | + quirks = (long)dmi_id->driver_data; | |
| 3617 | + | |
| 3618 | + if (turn_on_panel_on_resume == -1) | |
| 3619 | + turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME); | |
| 3620 | + | |
| 3621 | + if (hci_hotkey_quickstart == -1) | |
| 3622 | + hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART); | |
| 3623 | +} | |
| 3624 | + | |
| 3621 | 3625 | static int __init toshiba_acpi_init(void) |
| 3622 | 3626 | { |
| 3623 | 3627 | int ret; |
| 3624 | 3628 | |
| 3629 | + toshiba_dmi_init(); | |
| 3625 | 3630 | toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); |
| 3626 | 3631 | if (!toshiba_proc_dir) { |
| 3627 | 3632 | pr_err("Unable to create proc dir " PROC_TOSHIBA "\n"); |
| @@ -929,4 +929,5 @@ module_init(uv_sysfs_init); · 928 unmodified lines | ||
| 929 | 929 | module_exit(uv_sysfs_exit); |
| 930 | 930 | |
| 931 | 931 | MODULE_AUTHOR("Hewlett Packard Enterprise"); |
| 932 | +MODULE_DESCRIPTION("Sysfs structure for HPE UV systems"); | |
| 932 | 933 | MODULE_LICENSE("GPL"); |
| @@ -14,11 +14,13 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/acpi.h> |
| 15 | 15 | #include <acpi/acpi_bus.h> |
| 16 | 16 | |
| 17 | +MODULE_DESCRIPTION("Airplane mode button for AMD, HP & Xiaomi laptops"); | |
| 17 | 18 | MODULE_LICENSE("GPL"); |
| 18 | 19 | MODULE_AUTHOR("Alex Hung"); |
| 19 | 20 | MODULE_ALIAS("acpi*:HPQ6001:*"); |
| 20 | 21 | MODULE_ALIAS("acpi*:WSTADEF:*"); |
| 21 | 22 | MODULE_ALIAS("acpi*:AMDI0051:*"); |
| 23 | +MODULE_ALIAS("acpi*:LGEX0815:*"); | |
| 22 | 24 | |
| 23 | 25 | struct wl_button { |
| 24 | 26 | struct input_dev *input_dev; |
| @@ -29,6 +31,7 @@ static const struct acpi_device_id wl_ids[] = { · 4 unmodified lines | ||
| 29 | 31 | {"HPQ6001", 0}, |
| 30 | 32 | {"WSTADEF", 0}, |
| 31 | 33 | {"AMDI0051", 0}, |
| 34 | + {"LGEX0815", 0}, | |
| 32 | 35 | {"", 0}, |
| 33 | 36 | }; |
| 34 | 37 | |
| @@ -74,5 +74,6 @@ static struct platform_driver xo1_rfkill_driver = { · 73 unmodified lines | ||
| 74 | 74 | module_platform_driver(xo1_rfkill_driver); |
| 75 | 75 | |
| 76 | 76 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); |
| 77 | +MODULE_DESCRIPTION("OLPC XO-1 software RF kill switch"); | |
| 77 | 78 | MODULE_LICENSE("GPL"); |
| 78 | 79 | MODULE_ALIAS("platform:xo1-rfkill"); |
| @@ -68,6 +68,7 @@ config RESET_BRCMSTB_RESCAL · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | config RESET_GPIO |
| 70 | 70 | tristate "GPIO reset controller" |
| 71 | + depends on GPIOLIB | |
| 71 | 72 | help |
| 72 | 73 | This enables a generic reset controller for resets attached via |
| 73 | 74 | GPIOs. Typically for OF platforms this driver expects "reset-gpios" |
| @@ -219,4 +219,5 @@ static int __init hi6220_reset_init(void) · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | postcore_initcall(hi6220_reset_init); |
| 221 | 221 | |
| 222 | +MODULE_DESCRIPTION("Hisilicon Hi6220 reset controller driver"); | |
| 222 | 223 | MODULE_LICENSE("GPL v2"); |
| @@ -4906,7 +4906,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) · 4905 unmodified lines | ||
| 4906 | 4906 | ccw++; |
| 4907 | 4907 | if (dst) { |
| 4908 | 4908 | if (ccw->flags & CCW_FLAG_IDA) |
| 4909 | − cda = *((char **)dma32_to_virt(ccw->cda)); | |
| 4909 | + cda = dma64_to_virt(*((dma64_t *)dma32_to_virt(ccw->cda))); | |
| 4910 | 4910 | else |
| 4911 | 4911 | cda = dma32_to_virt(ccw->cda); |
| 4912 | 4912 | if (dst != cda) { |
| @@ -5525,7 +5525,7 @@ dasd_eckd_dump_ccw_range(struct dasd_device *device, struct ccw1 *from, · 612 unmodified lines | ||
| 5525 | 5525 | |
| 5526 | 5526 | /* get pointer to data (consider IDALs) */ |
| 5527 | 5527 | if (from->flags & CCW_FLAG_IDA) |
| 5528 | − datap = (char *)*((addr_t *)dma32_to_virt(from->cda)); | |
| 5528 | + datap = dma64_to_virt(*((dma64_t *)dma32_to_virt(from->cda))); | |
| 5529 | 5529 | else |
| 5530 | 5530 | datap = dma32_to_virt(from->cda); |
| 5531 | 5531 | |
| @@ -585,7 +585,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req) · 584 unmodified lines | ||
| 585 | 585 | ccw++; |
| 586 | 586 | if (dst) { |
| 587 | 587 | if (ccw->flags & CCW_FLAG_IDA) |
| 588 | − cda = *((char **)dma32_to_virt(ccw->cda)); | |
| 588 | + cda = dma64_to_virt(*((dma64_t *)dma32_to_virt(ccw->cda))); | |
| 589 | 589 | else |
| 590 | 590 | cda = dma32_to_virt(ccw->cda); |
| 591 | 591 | if (dst != cda) { |
| @@ -1293,6 +1293,7 @@ sclp_init(void) · 1292 unmodified lines | ||
| 1293 | 1293 | fail_unregister_reboot_notifier: |
| 1294 | 1294 | unregister_reboot_notifier(&sclp_reboot_notifier); |
| 1295 | 1295 | fail_init_state_uninitialized: |
| 1296 | + list_del(&sclp_state_change_event.list); | |
| 1296 | 1297 | sclp_init_state = sclp_init_state_uninitialized; |
| 1297 | 1298 | free_page((unsigned long) sclp_read_sccb); |
| 1298 | 1299 | free_page((unsigned long) sclp_init_sccb); |
| @@ -490,13 +490,14 @@ static int ccwchain_fetch_tic(struct ccw1 *ccw, · 489 unmodified lines | ||
| 490 | 490 | struct channel_program *cp) |
| 491 | 491 | { |
| 492 | 492 | struct ccwchain *iter; |
| 493 | − u32 cda, ccw_head; | |
| 493 | + u32 offset, ccw_head; | |
| 494 | 494 | |
| 495 | 495 | list_for_each_entry(iter, &cp->ccwchain_list, next) { |
| 496 | 496 | ccw_head = iter->ch_iova; |
| 497 | 497 | if (is_cpa_within_range(ccw->cda, ccw_head, iter->ch_len)) { |
| 498 | − cda = (u64)iter->ch_ccw + dma32_to_u32(ccw->cda) - ccw_head; | |
| 499 | − ccw->cda = u32_to_dma32(cda); | |
| 498 | + /* Calculate offset of TIC target */ | |
| 499 | + offset = dma32_to_u32(ccw->cda) - ccw_head; | |
| 500 | + ccw->cda = virt_to_dma32((void *)iter->ch_ccw + offset); | |
| 500 | 501 | return 0; |
| 501 | 502 | } |
| 502 | 503 | } |
| @@ -914,7 +915,7 @@ void cp_update_scsw(struct channel_program *cp, union scsw *scsw) · 411 unmodified lines | ||
| 914 | 915 | * in the ioctl directly. Path status changes etc. |
| 915 | 916 | */ |
| 916 | 917 | list_for_each_entry(chain, &cp->ccwchain_list, next) { |
| 917 | − ccw_head = (u32)(u64)chain->ch_ccw; | |
| 918 | + ccw_head = dma32_to_u32(virt_to_dma32(chain->ch_ccw)); | |
| 918 | 919 | /* |
| 919 | 920 | * On successful execution, cpa points just beyond the end |
| 920 | 921 | * of the chain. |
| @@ -698,6 +698,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, · 697 unmodified lines | ||
| 698 | 698 | dma64_t *indicatorp = NULL; |
| 699 | 699 | int ret, i, queue_idx = 0; |
| 700 | 700 | struct ccw1 *ccw; |
| 701 | + dma32_t indicatorp_dma = 0; | |
| 701 | 702 | |
| 702 | 703 | ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); |
| 703 | 704 | if (!ccw) |
| @@ -725,7 +726,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, · 21 unmodified lines | ||
| 725 | 726 | */ |
| 726 | 727 | indicatorp = ccw_device_dma_zalloc(vcdev->cdev, |
| 727 | 728 | sizeof(*indicatorp), |
| 728 | − &ccw->cda); | |
| 729 | + &indicatorp_dma); | |
| 729 | 730 | if (!indicatorp) |
| 730 | 731 | goto out; |
| 731 | 732 | *indicatorp = indicators_dma(vcdev); |
| @@ -735,6 +736,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, · 3 unmodified lines | ||
| 735 | 736 | /* no error, just fall back to legacy interrupts */ |
| 736 | 737 | vcdev->is_thinint = false; |
| 737 | 738 | } |
| 739 | + ccw->cda = indicatorp_dma; | |
| 738 | 740 | if (!vcdev->is_thinint) { |
| 739 | 741 | /* Register queue indicators with host. */ |
| 740 | 742 | *indicators(vcdev) = 0; |
| @@ -610,15 +610,15 @@ int sas_ata_init(struct domain_device *found_dev) · 609 unmodified lines | ||
| 610 | 610 | |
| 611 | 611 | rc = ata_sas_tport_add(ata_host->dev, ap); |
| 612 | 612 | if (rc) |
| 613 | − goto destroy_port; | |
| 613 | + goto free_port; | |
| 614 | 614 | |
| 615 | 615 | found_dev->sata_dev.ata_host = ata_host; |
| 616 | 616 | found_dev->sata_dev.ap = ap; |
| 617 | 617 | |
| 618 | 618 | return 0; |
| 619 | 619 | |
| 620 | −destroy_port: | |
| 621 | − kfree(ap); | |
| 620 | +free_port: | |
| 621 | + ata_port_free(ap); | |
| 622 | 622 | free_host: |
| 623 | 623 | ata_host_put(ata_host); |
| 624 | 624 | return rc; |
| @@ -301,7 +301,7 @@ void sas_free_device(struct kref *kref) · 300 unmodified lines | ||
| 301 | 301 | |
| 302 | 302 | if (dev_is_sata(dev) && dev->sata_dev.ap) { |
| 303 | 303 | ata_sas_tport_delete(dev->sata_dev.ap); |
| 304 | − kfree(dev->sata_dev.ap); | |
| 304 | + ata_port_free(dev->sata_dev.ap); | |
| 305 | 305 | ata_host_put(dev->sata_dev.ata_host); |
| 306 | 306 | dev->sata_dev.ata_host = NULL; |
| 307 | 307 | dev->sata_dev.ap = NULL; |
| @@ -145,6 +145,20 @@ static inline void sas_fail_probe(struct domain_device *dev, const char *func, i · 144 unmodified lines | ||
| 145 | 145 | func, dev->parent ? "exp-attached" : |
| 146 | 146 | "direct-attached", |
| 147 | 147 | SAS_ADDR(dev->sas_addr), err); |
| 148 | + | |
| 149 | + /* | |
| 150 | + * If the device probe failed, the expander phy attached address | |
| 151 | + * needs to be reset so that the phy will not be treated as flutter | |
| 152 | + * in the next revalidation | |
| 153 | + */ | |
| 154 | + if (dev->parent && !dev_is_expander(dev->dev_type)) { | |
| 155 | + struct sas_phy *phy = dev->phy; | |
| 156 | + struct domain_device *parent = dev->parent; | |
| 157 | + struct ex_phy *ex_phy = &parent->ex_dev.ex_phy[phy->number]; | |
| 158 | + | |
| 159 | + memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); | |
| 160 | + } | |
| 161 | + | |
| 148 | 162 | sas_unregister_dev(dev->port, dev); |
| 149 | 163 | } |
| 150 | 164 | |
| @@ -926,6 +926,7 @@ static const int device_qfull_result = · 925 unmodified lines | ||
| 926 | 926 | static const int condition_met_result = SAM_STAT_CONDITION_MET; |
| 927 | 927 | |
| 928 | 928 | static struct dentry *sdebug_debugfs_root; |
| 929 | +static ASYNC_DOMAIN_EXCLUSIVE(sdebug_async_domain); | |
| 929 | 930 | |
| 930 | 931 | static void sdebug_err_free(struct rcu_head *head) |
| 931 | 932 | { |
| @@ -1148,6 +1149,8 @@ static int sdebug_target_alloc(struct scsi_target *starget) · 216 unmodified lines | ||
| 1148 | 1149 | if (!targetip) |
| 1149 | 1150 | return -ENOMEM; |
| 1150 | 1151 | |
| 1152 | + async_synchronize_full_domain(&sdebug_async_domain); | |
| 1153 | + | |
| 1151 | 1154 | targetip->debugfs_entry = debugfs_create_dir(dev_name(&starget->dev), |
| 1152 | 1155 | sdebug_debugfs_root); |
| 1153 | 1156 | |
| @@ -1174,7 +1177,8 @@ static void sdebug_target_destroy(struct scsi_target *starget) · 20 unmodified lines | ||
| 1174 | 1177 | targetip = (struct sdebug_target_info *)starget->hostdata; |
| 1175 | 1178 | if (targetip) { |
| 1176 | 1179 | starget->hostdata = NULL; |
| 1177 | − async_schedule(sdebug_tartget_cleanup_async, targetip); | |
| 1180 | + async_schedule_domain(sdebug_tartget_cleanup_async, targetip, | |
| 1181 | + &sdebug_async_domain); | |
| 1178 | 1182 | } |
| 1179 | 1183 | } |
| 1180 | 1184 | |
| @@ -7,7 +7,7 @@ config LITEX · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | config LITEX_SOC_CONTROLLER |
| 9 | 9 | tristate "Enable LiteX SoC Controller driver" |
| 10 | − depends on OF || COMPILE_TEST | |
| 10 | + depends on OF | |
| 11 | 11 | depends on HAS_IOMEM |
| 12 | 12 | select LITEX |
| 13 | 13 | help |
| @@ -82,13 +82,11 @@ static int litex_reset_handler(struct notifier_block *this, unsigned long mode, · 81 unmodified lines | ||
| 82 | 82 | return NOTIFY_DONE; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | −#ifdef CONFIG_OF | |
| 86 | 85 | static const struct of_device_id litex_soc_ctrl_of_match[] = { |
| 87 | 86 | {.compatible = "litex,soc-controller"}, |
| 88 | 87 | {}, |
| 89 | 88 | }; |
| 90 | 89 | MODULE_DEVICE_TABLE(of, litex_soc_ctrl_of_match); |
| 91 | −#endif /* CONFIG_OF */ | |
| 92 | 90 | |
| 93 | 91 | static int litex_soc_ctrl_probe(struct platform_device *pdev) |
| 94 | 92 | { |
| @@ -130,7 +128,7 @@ static void litex_soc_ctrl_remove(struct platform_device *pdev) · 35 unmodified lines | ||
| 130 | 128 | static struct platform_driver litex_soc_ctrl_driver = { |
| 131 | 129 | .driver = { |
| 132 | 130 | .name = "litex-soc-controller", |
| 133 | − .of_match_table = of_match_ptr(litex_soc_ctrl_of_match) | |
| 131 | + .of_match_table = litex_soc_ctrl_of_match, | |
| 134 | 132 | }, |
| 135 | 133 | .probe = litex_soc_ctrl_probe, |
| 136 | 134 | .remove_new = litex_soc_ctrl_remove, |
| @@ -707,7 +707,7 @@ int vchiq_initialise(struct vchiq_state *state, struct vchiq_instance **instance · 706 unmodified lines | ||
| 707 | 707 | * block forever. |
| 708 | 708 | */ |
| 709 | 709 | for (i = 0; i < VCHIQ_INIT_RETRIES; i++) { |
| 710 | − if (state) | |
| 710 | + if (vchiq_remote_initialised(state)) | |
| 711 | 711 | break; |
| 712 | 712 | usleep_range(500, 600); |
| 713 | 713 | } |
| @@ -1202,7 +1202,7 @@ void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f · 488 unmodified lines | ||
| 1202 | 1202 | { |
| 1203 | 1203 | int i; |
| 1204 | 1204 | |
| 1205 | − if (!state) | |
| 1205 | + if (!vchiq_remote_initialised(state)) | |
| 1206 | 1206 | return; |
| 1207 | 1207 | |
| 1208 | 1208 | /* |
| @@ -413,6 +413,11 @@ struct vchiq_state { · 412 unmodified lines | ||
| 413 | 413 | struct opaque_platform_state *platform_state; |
| 414 | 414 | }; |
| 415 | 415 | |
| 416 | +static inline bool vchiq_remote_initialised(const struct vchiq_state *state) | |
| 417 | +{ | |
| 418 | + return state->remote && state->remote->initialised; | |
| 419 | +} | |
| 420 | + | |
| 416 | 421 | struct bulk_waiter { |
| 417 | 422 | struct vchiq_bulk *bulk; |
| 418 | 423 | struct completion event; |
| @@ -138,7 +138,7 @@ void vchiq_debugfs_deinit(void) · 137 unmodified lines | ||
| 138 | 138 | |
| 139 | 139 | #else /* CONFIG_DEBUG_FS */ |
| 140 | 140 | |
| 141 | −void vchiq_debugfs_init(void) | |
| 141 | +void vchiq_debugfs_init(struct vchiq_state *state) | |
| 142 | 142 | { |
| 143 | 143 | } |
| 144 | 144 | |
| @@ -1170,6 +1170,11 @@ static int vchiq_open(struct inode *inode, struct file *file) · 1169 unmodified lines | ||
| 1170 | 1170 | |
| 1171 | 1171 | dev_dbg(state->dev, "arm: vchiq open\n"); |
| 1172 | 1172 | |
| 1173 | + if (!vchiq_remote_initialised(state)) { | |
| 1174 | + dev_dbg(state->dev, "arm: vchiq has no connection to VideoCore\n"); | |
| 1175 | + return -ENOTCONN; | |
| 1176 | + } | |
| 1177 | + | |
| 1173 | 1178 | instance = kzalloc(sizeof(*instance), GFP_KERNEL); |
| 1174 | 1179 | if (!instance) |
| 1175 | 1180 | return -ENOMEM; |
| @@ -1200,7 +1205,7 @@ static int vchiq_release(struct inode *inode, struct file *file) · 24 unmodified lines | ||
| 1200 | 1205 | |
| 1201 | 1206 | dev_dbg(state->dev, "arm: instance=%p\n", instance); |
| 1202 | 1207 | |
| 1203 | − if (!state) { | |
| 1208 | + if (!vchiq_remote_initialised(state)) { | |
| 1204 | 1209 | ret = -EPERM; |
| 1205 | 1210 | goto out; |
| 1206 | 1211 | } |
| @@ -660,7 +660,9 @@ static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev, · 659 unmodified lines | ||
| 660 | 660 | const struct ffa_ops *ops) |
| 661 | 661 | { |
| 662 | 662 | const struct ffa_msg_ops *msg_ops = ops->msg_ops; |
| 663 | − struct ffa_send_direct_data data = { OPTEE_FFA_GET_API_VERSION }; | |
| 663 | + struct ffa_send_direct_data data = { | |
| 664 | + .data0 = OPTEE_FFA_GET_API_VERSION, | |
| 665 | + }; | |
| 664 | 666 | int rc; |
| 665 | 667 | |
| 666 | 668 | msg_ops->mode_32bit_set(ffa_dev); |
| @@ -677,7 +679,9 @@ static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev, · 10 unmodified lines | ||
| 677 | 679 | return false; |
| 678 | 680 | } |
| 679 | 681 | |
| 680 | − data = (struct ffa_send_direct_data){ OPTEE_FFA_GET_OS_VERSION }; | |
| 682 | + data = (struct ffa_send_direct_data){ | |
| 683 | + .data0 = OPTEE_FFA_GET_OS_VERSION, | |
| 684 | + }; | |
| 681 | 685 | rc = msg_ops->sync_send_receive(ffa_dev, &data); |
| 682 | 686 | if (rc) { |
| 683 | 687 | pr_err("Unexpected error %d\n", rc); |
| @@ -698,7 +702,9 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev, · 14 unmodified lines | ||
| 698 | 702 | unsigned int *rpc_param_count, |
| 699 | 703 | unsigned int *max_notif_value) |
| 700 | 704 | { |
| 701 | − struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES }; | |
| 705 | + struct ffa_send_direct_data data = { | |
| 706 | + .data0 = OPTEE_FFA_EXCHANGE_CAPABILITIES, | |
| 707 | + }; | |
| 702 | 708 | int rc; |
| 703 | 709 | |
| 704 | 710 | rc = ops->msg_ops->sync_send_receive(ffa_dev, &data); |
| @@ -55,7 +55,11 @@ static unsigned long get_target_state(struct thermal_instance *instance, · 54 unmodified lines | ||
| 55 | 55 | if (cur_state <= instance->lower) |
| 56 | 56 | return THERMAL_NO_TARGET; |
| 57 | 57 | |
| 58 | − return clamp(cur_state - 1, instance->lower, instance->upper); | |
| 58 | + /* | |
| 59 | + * If 'throttle' is false, no mitigation is necessary, so | |
| 60 | + * request the lower state for this instance. | |
| 61 | + */ | |
| 62 | + return instance->lower; | |
| 59 | 63 | } |
| 60 | 64 | |
| 61 | 65 | return instance->target; |
| @@ -93,23 +97,6 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, · 31 unmodified lines | ||
| 93 | 97 | if (instance->initialized && old_target == instance->target) |
| 94 | 98 | continue; |
| 95 | 99 | |
| 96 | − if (trip->type == THERMAL_TRIP_PASSIVE) { | |
| 97 | − /* | |
| 98 | − * If the target state for this thermal instance | |
| 99 | − * changes from THERMAL_NO_TARGET to something else, | |
| 100 | − * ensure that the zone temperature will be updated | |
| 101 | − * (assuming enabled passive cooling) until it becomes | |
| 102 | − * THERMAL_NO_TARGET again, or the cooling device may | |
| 103 | − * not be reset to its initial state. | |
| 104 | − */ | |
| 105 | − if (old_target == THERMAL_NO_TARGET && | |
| 106 | − instance->target != THERMAL_NO_TARGET) | |
| 107 | − tz->passive++; | |
| 108 | − else if (old_target != THERMAL_NO_TARGET && | |
| 109 | − instance->target == THERMAL_NO_TARGET) | |
| 110 | − tz->passive--; | |
| 111 | − } | |
| 112 | − | |
| 113 | 100 | instance->initialized = true; |
| 114 | 101 | |
| 115 | 102 | mutex_lock(&instance->cdev->lock); |
| @@ -288,7 +288,7 @@ struct mxser_board { · 287 unmodified lines | ||
| 288 | 288 | enum mxser_must_hwid must_hwid; |
| 289 | 289 | speed_t max_baud; |
| 290 | 290 | |
| 291 | − struct mxser_port ports[] __counted_by(nports); | |
| 291 | + struct mxser_port ports[] /* __counted_by(nports) */; | |
| 292 | 292 | }; |
| 293 | 293 | |
| 294 | 294 | static DECLARE_BITMAP(mxser_boards, MXSER_BOARDS); |
| @@ -15,7 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | 17 | #include <linux/acpi.h> |
| 18 | −#include <linux/cleanup.h> | |
| 19 | 18 | #include <linux/module.h> |
| 20 | 19 | #include <linux/moduleparam.h> |
| 21 | 20 | #include <linux/ioport.h> |
| @@ -42,8 +41,6 @@ · 20 unmodified lines | ||
| 42 | 41 | |
| 43 | 42 | #include <asm/irq.h> |
| 44 | 43 | |
| 45 | −#include "../serial_base.h" /* For serial_base_add_isa_preferred_console() */ | |
| 46 | − | |
| 47 | 44 | #include "8250.h" |
| 48 | 45 | |
| 49 | 46 | /* |
| @@ -563,8 +560,6 @@ static void __init serial8250_isa_init_ports(void) · 513 unmodified lines | ||
| 563 | 560 | port->irqflags |= irqflag; |
| 564 | 561 | if (serial8250_isa_config != NULL) |
| 565 | 562 | serial8250_isa_config(i, &up->port, &up->capabilities); |
| 566 | − | |
| 567 | − serial_base_add_isa_preferred_console(serial8250_reg.dev_name, i); | |
| 568 | 563 | } |
| 569 | 564 | } |
| 570 | 565 | |
| @@ -115,6 +115,10 @@ · 114 unmodified lines | ||
| 115 | 115 | /* RX FIFO occupancy indicator */ |
| 116 | 116 | #define UART_OMAP_RX_LVL 0x19 |
| 117 | 117 | |
| 118 | +/* Timeout low and High */ | |
| 119 | +#define UART_OMAP_TO_L 0x26 | |
| 120 | +#define UART_OMAP_TO_H 0x27 | |
| 121 | + | |
| 118 | 122 | /* |
| 119 | 123 | * Copy of the genpd flags for the console. |
| 120 | 124 | * Only used if console suspend is disabled |
| @@ -663,13 +667,24 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) · 542 unmodified lines | ||
| 663 | 667 | |
| 664 | 668 | /* |
| 665 | 669 | * On K3 SoCs, it is observed that RX TIMEOUT is signalled after |
| 666 | − * FIFO has been drained, in which case a dummy read of RX FIFO | |
| 667 | − * is required to clear RX TIMEOUT condition. | |
| 670 | + * FIFO has been drained or erroneously. | |
| 671 | + * So apply solution of Errata i2310 as mentioned in | |
| 672 | + * https://www.ti.com/lit/pdf/sprz536 | |
| 668 | 673 | */ |
| 669 | 674 | if (priv->habit & UART_RX_TIMEOUT_QUIRK && |
| 670 | − (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT && | |
| 671 | − serial_port_in(port, UART_OMAP_RX_LVL) == 0) { | |
| 672 | − serial_port_in(port, UART_RX); | |
| 675 | + (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT) { | |
| 676 | + unsigned char efr2, timeout_h, timeout_l; | |
| 677 | + | |
| 678 | + efr2 = serial_in(up, UART_OMAP_EFR2); | |
| 679 | + timeout_h = serial_in(up, UART_OMAP_TO_H); | |
| 680 | + timeout_l = serial_in(up, UART_OMAP_TO_L); | |
| 681 | + serial_out(up, UART_OMAP_TO_H, 0xFF); | |
| 682 | + serial_out(up, UART_OMAP_TO_L, 0xFF); | |
| 683 | + serial_out(up, UART_OMAP_EFR2, UART_OMAP_EFR2_TIMEOUT_BEHAVE); | |
| 684 | + serial_in(up, UART_IIR); | |
| 685 | + serial_out(up, UART_OMAP_EFR2, efr2); | |
| 686 | + serial_out(up, UART_OMAP_TO_H, timeout_h); | |
| 687 | + serial_out(up, UART_OMAP_TO_L, timeout_l); | |
| 673 | 688 | } |
| 674 | 689 | |
| 675 | 690 | /* Stop processing interrupts on input overrun */ |
| @@ -1985,6 +1985,17 @@ enum { · 1984 unmodified lines | ||
| 1985 | 1985 | MOXA_SUPP_RS485 = BIT(2), |
| 1986 | 1986 | }; |
| 1987 | 1987 | |
| 1988 | +static unsigned short moxa_get_nports(unsigned short device) | |
| 1989 | +{ | |
| 1990 | + switch (device) { | |
| 1991 | + case PCI_DEVICE_ID_MOXA_CP116E_A_A: | |
| 1992 | + case PCI_DEVICE_ID_MOXA_CP116E_A_B: | |
| 1993 | + return 8; | |
| 1994 | + } | |
| 1995 | + | |
| 1996 | + return FIELD_GET(0x00F0, device); | |
| 1997 | +} | |
| 1998 | + | |
| 1988 | 1999 | static bool pci_moxa_is_mini_pcie(unsigned short device) |
| 1989 | 2000 | { |
| 1990 | 2001 | if (device == PCI_DEVICE_ID_MOXA_CP102N || |
| @@ -2038,7 +2049,7 @@ static int pci_moxa_init(struct pci_dev *dev) · 47 unmodified lines | ||
| 2038 | 2049 | { |
| 2039 | 2050 | unsigned short device = dev->device; |
| 2040 | 2051 | resource_size_t iobar_addr = pci_resource_start(dev, 2); |
| 2041 | − unsigned int num_ports = (device & 0x00F0) >> 4, i; | |
| 2052 | + unsigned int i, num_ports = moxa_get_nports(device); | |
| 2042 | 2053 | u8 val, init_mode = MOXA_RS232; |
| 2043 | 2054 | |
| 2044 | 2055 | if (!(pci_moxa_supported_rs(dev) & MOXA_SUPP_RS232)) { |
| @@ -308,8 +308,8 @@ static void bcm_uart_do_tx(struct uart_port *port) · 307 unmodified lines | ||
| 308 | 308 | |
| 309 | 309 | val = bcm_uart_readl(port, UART_MCTL_REG); |
| 310 | 310 | val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT; |
| 311 | − | |
| 312 | − pending = uart_port_tx_limited(port, ch, port->fifosize - val, | |
| 311 | + pending = uart_port_tx_limited_flags(port, ch, UART_TX_NOSTOP, | |
| 312 | + port->fifosize - val, | |
| 313 | 313 | true, |
| 314 | 314 | bcm_uart_writel(port, ch, UART_FIFO_REG), |
| 315 | 315 | ({})); |
| @@ -320,6 +320,9 @@ static void bcm_uart_do_tx(struct uart_port *port) · 4 unmodified lines | ||
| 320 | 320 | val = bcm_uart_readl(port, UART_IR_REG); |
| 321 | 321 | val &= ~UART_TX_INT_MASK; |
| 322 | 322 | bcm_uart_writel(port, val, UART_IR_REG); |
| 323 | + | |
| 324 | + if (uart_tx_stopped(port)) | |
| 325 | + bcm_uart_stop_tx(port); | |
| 323 | 326 | } |
| 324 | 327 | |
| 325 | 328 | /* |
| @@ -1952,8 +1952,10 @@ static int imx_uart_rs485_config(struct uart_port *port, struct ktermios *termio · 1951 unmodified lines | ||
| 1952 | 1952 | |
| 1953 | 1953 | /* Make sure Rx is enabled in case Tx is active with Rx disabled */ |
| 1954 | 1954 | if (!(rs485conf->flags & SER_RS485_ENABLED) || |
| 1955 | − rs485conf->flags & SER_RS485_RX_DURING_TX) | |
| 1955 | + rs485conf->flags & SER_RS485_RX_DURING_TX) { | |
| 1956 | + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); | |
| 1956 | 1957 | imx_uart_start_rx(port); |
| 1958 | + } | |
| 1957 | 1959 | |
| 1958 | 1960 | return 0; |
| 1959 | 1961 | } |
| @@ -462,7 +462,7 @@ static const struct uart_ops mcf_uart_ops = { · 461 unmodified lines | ||
| 462 | 462 | .verify_port = mcf_verify_port, |
| 463 | 463 | }; |
| 464 | 464 | |
| 465 | −static struct mcf_uart mcf_ports[4]; | |
| 465 | +static struct mcf_uart mcf_ports[10]; | |
| 466 | 466 | |
| 467 | 467 | #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) |
| 468 | 468 | |
| @@ -49,33 +49,3 @@ void serial_ctrl_unregister_port(struct uart_driver *drv, struct uart_port *port · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | int serial_core_register_port(struct uart_driver *drv, struct uart_port *port); |
| 51 | 51 | void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port); |
| 52 | − | |
| 53 | −#ifdef CONFIG_SERIAL_CORE_CONSOLE | |
| 54 | − | |
| 55 | −int serial_base_add_preferred_console(struct uart_driver *drv, | |
| 56 | − struct uart_port *port); | |
| 57 | − | |
| 58 | −#else | |
| 59 | − | |
| 60 | −static inline | |
| 61 | −int serial_base_add_preferred_console(struct uart_driver *drv, | |
| 62 | − struct uart_port *port) | |
| 63 | −{ | |
| 64 | − return 0; | |
| 65 | −} | |
| 66 | − | |
| 67 | −#endif | |
| 68 | − | |
| 69 | −#ifdef CONFIG_SERIAL_8250_CONSOLE | |
| 70 | − | |
| 71 | −int serial_base_add_isa_preferred_console(const char *name, int idx); | |
| 72 | − | |
| 73 | −#else | |
| 74 | − | |
| 75 | −static inline | |
| 76 | −int serial_base_add_isa_preferred_console(const char *name, int idx) | |
| 77 | −{ | |
| 78 | − return 0; | |
| 79 | −} | |
| 80 | − | |
| 81 | −#endif | |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | * The serial core bus manages the serial core controller instances. |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | −#include <linux/cleanup.h> | |
| 12 | 11 | #include <linux/container_of.h> |
| 13 | 12 | #include <linux/device.h> |
| 14 | 13 | #include <linux/idr.h> |
| @@ -205,134 +204,6 @@ void serial_base_port_device_remove(struct serial_port_device *port_dev) · 190 unmodified lines | ||
| 205 | 204 | put_device(&port_dev->dev); |
| 206 | 205 | } |
| 207 | 206 | |
| 208 | −#ifdef CONFIG_SERIAL_CORE_CONSOLE | |
| 209 | − | |
| 210 | −static int serial_base_add_one_prefcon(const char *match, const char *dev_name, | |
| 211 | − int port_id) | |
| 212 | −{ | |
| 213 | − int ret; | |
| 214 | − | |
| 215 | − ret = add_preferred_console_match(match, dev_name, port_id); | |
| 216 | − if (ret == -ENOENT) | |
| 217 | − return 0; | |
| 218 | − | |
| 219 | − return ret; | |
| 220 | −} | |
| 221 | − | |
| 222 | −#ifdef __sparc__ | |
| 223 | − | |
| 224 | −/* Handle Sparc ttya and ttyb options as done in console_setup() */ | |
| 225 | −static int serial_base_add_sparc_console(const char *dev_name, int idx) | |
| 226 | −{ | |
| 227 | − const char *name; | |
| 228 | − | |
| 229 | − switch (idx) { | |
| 230 | − case 0: | |
| 231 | − name = "ttya"; | |
| 232 | − break; | |
| 233 | − case 1: | |
| 234 | − name = "ttyb"; | |
| 235 | − break; | |
| 236 | − default: | |
| 237 | − return 0; | |
| 238 | − } | |
| 239 | − | |
| 240 | − return serial_base_add_one_prefcon(name, dev_name, idx); | |
| 241 | −} | |
| 242 | − | |
| 243 | −#else | |
| 244 | − | |
| 245 | −static inline int serial_base_add_sparc_console(const char *dev_name, int idx) | |
| 246 | −{ | |
| 247 | − return 0; | |
| 248 | −} | |
| 249 | − | |
| 250 | −#endif | |
| 251 | − | |
| 252 | −static int serial_base_add_prefcon(const char *name, int idx) | |
| 253 | −{ | |
| 254 | − const char *char_match __free(kfree) = NULL; | |
| 255 | − const char *nmbr_match __free(kfree) = NULL; | |
| 256 | − int ret; | |
| 257 | − | |
| 258 | − /* Handle ttyS specific options */ | |
| 259 | − if (strstarts(name, "ttyS")) { | |
| 260 | − /* No name, just a number */ | |
| 261 | − nmbr_match = kasprintf(GFP_KERNEL, "%i", idx); | |
| 262 | − if (!nmbr_match) | |
| 263 | − return -ENODEV; | |
| 264 | − | |
| 265 | − ret = serial_base_add_one_prefcon(nmbr_match, name, idx); | |
| 266 | − if (ret) | |
| 267 | − return ret; | |
| 268 | − | |
| 269 | − /* Sparc ttya and ttyb */ | |
| 270 | − ret = serial_base_add_sparc_console(name, idx); | |
| 271 | − if (ret) | |
| 272 | − return ret; | |
| 273 | − } | |
| 274 | − | |
| 275 | − /* Handle the traditional character device name style console=ttyS0 */ | |
| 276 | − char_match = kasprintf(GFP_KERNEL, "%s%i", name, idx); | |
| 277 | − if (!char_match) | |
| 278 | − return -ENOMEM; | |
| 279 | − | |
| 280 | − return serial_base_add_one_prefcon(char_match, name, idx); | |
| 281 | −} | |
| 282 | − | |
| 283 | −/** | |
| 284 | − * serial_base_add_preferred_console - Adds a preferred console | |
| 285 | − * @drv: Serial port device driver | |
| 286 | − * @port: Serial port instance | |
| 287 | − * | |
| 288 | − * Tries to add a preferred console for a serial port if specified in the | |
| 289 | − * kernel command line. Supports both the traditional character device such | |
| 290 | − * as console=ttyS0, and a hardware addressing based console=DEVNAME:0.0 | |
| 291 | − * style name. | |
| 292 | − * | |
| 293 | − * Translates the kernel command line option using a hardware based addressing | |
| 294 | − * console=DEVNAME:0.0 to the serial port character device such as ttyS0. | |
| 295 | − * Cannot be called early for ISA ports, depends on struct device. | |
| 296 | − * | |
| 297 | − * Note that duplicates are ignored by add_preferred_console(). | |
| 298 | − * | |
| 299 | − * Return: 0 on success, negative error code on failure. | |
| 300 | − */ | |
| 301 | −int serial_base_add_preferred_console(struct uart_driver *drv, | |
| 302 | − struct uart_port *port) | |
| 303 | −{ | |
| 304 | − const char *port_match __free(kfree) = NULL; | |
| 305 | − int ret; | |
| 306 | − | |
| 307 | − ret = serial_base_add_prefcon(drv->dev_name, port->line); | |
| 308 | − if (ret) | |
| 309 | − return ret; | |
| 310 | − | |
| 311 | − port_match = kasprintf(GFP_KERNEL, "%s:%i.%i", dev_name(port->dev), | |
| 312 | − port->ctrl_id, port->port_id); | |
| 313 | − if (!port_match) | |
| 314 | − return -ENOMEM; | |
| 315 | − | |
| 316 | − /* Translate a hardware addressing style console=DEVNAME:0.0 */ | |
| 317 | − return serial_base_add_one_prefcon(port_match, drv->dev_name, port->line); | |
| 318 | −} | |
| 319 | − | |
| 320 | −#endif | |
| 321 | − | |
| 322 | −#ifdef CONFIG_SERIAL_8250_CONSOLE | |
| 323 | − | |
| 324 | −/* | |
| 325 | − * Early ISA ports initialize the console before there is no struct device. | |
| 326 | − * This should be only called from serial8250_isa_init_preferred_console(), | |
| 327 | − * other callers are likely wrong and should rely on earlycon instead. | |
| 328 | − */ | |
| 329 | −int serial_base_add_isa_preferred_console(const char *name, int idx) | |
| 330 | −{ | |
| 331 | − return serial_base_add_prefcon(name, idx); | |
| 332 | −} | |
| 333 | − | |
| 334 | −#endif | |
| 335 | − | |
| 336 | 207 | static int serial_base_init(void) |
| 337 | 208 | { |
| 338 | 209 | int ret; |
| @@ -3422,10 +3422,6 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) · 3421 unmodified lines | ||
| 3422 | 3422 | if (ret) |
| 3423 | 3423 | goto err_unregister_ctrl_dev; |
| 3424 | 3424 | |
| 3425 | − ret = serial_base_add_preferred_console(drv, port); | |
| 3426 | − if (ret) | |
| 3427 | − goto err_unregister_port_dev; | |
| 3428 | − | |
| 3429 | 3425 | ret = serial_core_add_one_port(drv, port); |
| 3430 | 3426 | if (ret) |
| 3431 | 3427 | goto err_unregister_port_dev; |
| @@ -1131,6 +1131,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, · 1130 unmodified lines | ||
| 1131 | 1131 | struct cxacru_data *instance; |
| 1132 | 1132 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
| 1133 | 1133 | struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; |
| 1134 | + struct usb_endpoint_descriptor *in, *out; | |
| 1134 | 1135 | int ret; |
| 1135 | 1136 | |
| 1136 | 1137 | /* instance init */ |
| @@ -1177,6 +1178,19 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, · 40 unmodified lines | ||
| 1177 | 1178 | goto fail; |
| 1178 | 1179 | } |
| 1179 | 1180 | |
| 1181 | + if (usb_endpoint_xfer_int(&cmd_ep->desc)) | |
| 1182 | + ret = usb_find_common_endpoints(intf->cur_altsetting, | |
| 1183 | + NULL, NULL, &in, &out); | |
| 1184 | + else | |
| 1185 | + ret = usb_find_common_endpoints(intf->cur_altsetting, | |
| 1186 | + &in, &out, NULL, NULL); | |
| 1187 | + | |
| 1188 | + if (ret) { | |
| 1189 | + usb_err(usbatm_instance, "cxacru_bind: interface has incorrect endpoints\n"); | |
| 1190 | + ret = -ENODEV; | |
| 1191 | + goto fail; | |
| 1192 | + } | |
| 1193 | + | |
| 1180 | 1194 | if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) |
| 1181 | 1195 | == USB_ENDPOINT_XFER_INT) { |
| 1182 | 1196 | usb_fill_int_urb(instance->rcv_urb, |
| @@ -957,12 +957,16 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc) · 956 unmodified lines | ||
| 957 | 957 | |
| 958 | 958 | static void dwc3_core_setup_global_control(struct dwc3 *dwc) |
| 959 | 959 | { |
| 960 | + unsigned int power_opt; | |
| 961 | + unsigned int hw_mode; | |
| 960 | 962 | u32 reg; |
| 961 | 963 | |
| 962 | 964 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
| 963 | 965 | reg &= ~DWC3_GCTL_SCALEDOWN_MASK; |
| 966 | + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); | |
| 967 | + power_opt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1); | |
| 964 | 968 | |
| 965 | − switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { | |
| 969 | + switch (power_opt) { | |
| 966 | 970 | case DWC3_GHWPARAMS1_EN_PWROPT_CLK: |
| 967 | 971 | /** |
| 968 | 972 | * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an |
| @@ -995,6 +999,20 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) · 26 unmodified lines | ||
| 995 | 999 | break; |
| 996 | 1000 | } |
| 997 | 1001 | |
| 1002 | + /* | |
| 1003 | + * This is a workaround for STAR#4846132, which only affects | |
| 1004 | + * DWC_usb31 version2.00a operating in host mode. | |
| 1005 | + * | |
| 1006 | + * There is a problem in DWC_usb31 version 2.00a operating | |
| 1007 | + * in host mode that would cause a CSR read timeout When CSR | |
| 1008 | + * read coincides with RAM Clock Gating Entry. By disable | |
| 1009 | + * Clock Gating, sacrificing power consumption for normal | |
| 1010 | + * operation. | |
| 1011 | + */ | |
| 1012 | + if (power_opt != DWC3_GHWPARAMS1_EN_PWROPT_NO && | |
| 1013 | + hw_mode != DWC3_GHWPARAMS0_MODE_GADGET && DWC3_VER_IS(DWC31, 200A)) | |
| 1014 | + reg |= DWC3_GCTL_DSBLCLKGTNG; | |
| 1015 | + | |
| 998 | 1016 | /* check if current dwc3 is on simulation board */ |
| 999 | 1017 | if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { |
| 1000 | 1018 | dev_info(dwc->dev, "Running with FPGA optimizations\n"); |
| @@ -2250,7 +2268,6 @@ assert_reset: · 1249 unmodified lines | ||
| 2250 | 2268 | |
| 2251 | 2269 | static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) |
| 2252 | 2270 | { |
| 2253 | − unsigned long flags; | |
| 2254 | 2271 | u32 reg; |
| 2255 | 2272 | int i; |
| 2256 | 2273 | |
| @@ -2293,9 +2310,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 36 unmodified lines | ||
| 2293 | 2310 | break; |
| 2294 | 2311 | |
| 2295 | 2312 | if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { |
| 2296 | − spin_lock_irqsave(&dwc->lock, flags); | |
| 2297 | 2313 | dwc3_gadget_suspend(dwc); |
| 2298 | − spin_unlock_irqrestore(&dwc->lock, flags); | |
| 2299 | 2314 | synchronize_irq(dwc->irq_gadget); |
| 2300 | 2315 | } |
| 2301 | 2316 | |
| @@ -2312,7 +2327,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 10 unmodified lines | ||
| 2312 | 2327 | |
| 2313 | 2328 | static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) |
| 2314 | 2329 | { |
| 2315 | − unsigned long flags; | |
| 2316 | 2330 | int ret; |
| 2317 | 2331 | u32 reg; |
| 2318 | 2332 | int i; |
| @@ -2366,9 +2380,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) · 47 unmodified lines | ||
| 2366 | 2380 | if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) { |
| 2367 | 2381 | dwc3_otg_host_init(dwc); |
| 2368 | 2382 | } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { |
| 2369 | − spin_lock_irqsave(&dwc->lock, flags); | |
| 2370 | 2383 | dwc3_gadget_resume(dwc); |
| 2371 | − spin_unlock_irqrestore(&dwc->lock, flags); | |
| 2372 | 2384 | } |
| 2373 | 2385 | |
| 2374 | 2386 | break; |
| @@ -213,6 +213,7 @@ static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, · 212 unmodified lines | ||
| 213 | 213 | struct usb_endpoint_descriptor *ss) |
| 214 | 214 | { |
| 215 | 215 | switch (gadget->speed) { |
| 216 | + case USB_SPEED_SUPER_PLUS: | |
| 216 | 217 | case USB_SPEED_SUPER: |
| 217 | 218 | return ss; |
| 218 | 219 | case USB_SPEED_HIGH: |
| @@ -449,11 +450,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) · 230 unmodified lines | ||
| 449 | 450 | mutex_lock(&dev->lock_printer_io); |
| 450 | 451 | spin_lock_irqsave(&dev->lock, flags); |
| 451 | 452 | |
| 452 | − if (dev->interface < 0) { | |
| 453 | − spin_unlock_irqrestore(&dev->lock, flags); | |
| 454 | − mutex_unlock(&dev->lock_printer_io); | |
| 455 | − return -ENODEV; | |
| 456 | − } | |
| 453 | + if (dev->interface < 0) | |
| 454 | + goto out_disabled; | |
| 457 | 455 | |
| 458 | 456 | /* We will use this flag later to check if a printer reset happened |
| 459 | 457 | * after we turn interrupts back on. |
| @@ -461,6 +459,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) · 1 unmodified line | ||
| 461 | 459 | dev->reset_printer = 0; |
| 462 | 460 | |
| 463 | 461 | setup_rx_reqs(dev); |
| 462 | + /* this dropped the lock - need to retest */ | |
| 463 | + if (dev->interface < 0) | |
| 464 | + goto out_disabled; | |
| 464 | 465 | |
| 465 | 466 | bytes_copied = 0; |
| 466 | 467 | current_rx_req = dev->current_rx_req; |
| @@ -494,6 +495,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) · 27 unmodified lines | ||
| 494 | 495 | wait_event_interruptible(dev->rx_wait, |
| 495 | 496 | (likely(!list_empty(&dev->rx_buffers)))); |
| 496 | 497 | spin_lock_irqsave(&dev->lock, flags); |
| 498 | + if (dev->interface < 0) | |
| 499 | + goto out_disabled; | |
| 497 | 500 | } |
| 498 | 501 | |
| 499 | 502 | /* We have data to return then copy it to the caller's buffer.*/ |
| @@ -537,6 +540,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) · 37 unmodified lines | ||
| 537 | 540 | return -EAGAIN; |
| 538 | 541 | } |
| 539 | 542 | |
| 543 | + if (dev->interface < 0) | |
| 544 | + goto out_disabled; | |
| 545 | + | |
| 540 | 546 | /* If we not returning all the data left in this RX request |
| 541 | 547 | * buffer then adjust the amount of data left in the buffer. |
| 542 | 548 | * Othewise if we are done with this RX request buffer then |
| @@ -566,6 +572,11 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) · 23 unmodified lines | ||
| 566 | 572 | return bytes_copied; |
| 567 | 573 | else |
| 568 | 574 | return -EAGAIN; |
| 575 | + | |
| 576 | +out_disabled: | |
| 577 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 578 | + mutex_unlock(&dev->lock_printer_io); | |
| 579 | + return -ENODEV; | |
| 569 | 580 | } |
| 570 | 581 | |
| 571 | 582 | static ssize_t |
| @@ -586,11 +597,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 14 unmodified lines | ||
| 586 | 597 | mutex_lock(&dev->lock_printer_io); |
| 587 | 598 | spin_lock_irqsave(&dev->lock, flags); |
| 588 | 599 | |
| 589 | − if (dev->interface < 0) { | |
| 590 | − spin_unlock_irqrestore(&dev->lock, flags); | |
| 591 | − mutex_unlock(&dev->lock_printer_io); | |
| 592 | − return -ENODEV; | |
| 593 | − } | |
| 600 | + if (dev->interface < 0) | |
| 601 | + goto out_disabled; | |
| 594 | 602 | |
| 595 | 603 | /* Check if a printer reset happens while we have interrupts on */ |
| 596 | 604 | dev->reset_printer = 0; |
| @@ -613,6 +621,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 16 unmodified lines | ||
| 613 | 621 | wait_event_interruptible(dev->tx_wait, |
| 614 | 622 | (likely(!list_empty(&dev->tx_reqs)))); |
| 615 | 623 | spin_lock_irqsave(&dev->lock, flags); |
| 624 | + if (dev->interface < 0) | |
| 625 | + goto out_disabled; | |
| 616 | 626 | } |
| 617 | 627 | |
| 618 | 628 | while (likely(!list_empty(&dev->tx_reqs)) && len) { |
| @@ -662,6 +672,9 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 43 unmodified lines | ||
| 662 | 672 | return -EAGAIN; |
| 663 | 673 | } |
| 664 | 674 | |
| 675 | + if (dev->interface < 0) | |
| 676 | + goto out_disabled; | |
| 677 | + | |
| 665 | 678 | list_add(&req->list, &dev->tx_reqs_active); |
| 666 | 679 | |
| 667 | 680 | /* here, we unlock, and only unlock, to avoid deadlock. */ |
| @@ -674,6 +687,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 6 unmodified lines | ||
| 674 | 687 | mutex_unlock(&dev->lock_printer_io); |
| 675 | 688 | return -EAGAIN; |
| 676 | 689 | } |
| 690 | + if (dev->interface < 0) | |
| 691 | + goto out_disabled; | |
| 677 | 692 | } |
| 678 | 693 | |
| 679 | 694 | spin_unlock_irqrestore(&dev->lock, flags); |
| @@ -685,6 +700,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 5 unmodified lines | ||
| 685 | 700 | return bytes_copied; |
| 686 | 701 | else |
| 687 | 702 | return -EAGAIN; |
| 703 | + | |
| 704 | +out_disabled: | |
| 705 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 706 | + mutex_unlock(&dev->lock_printer_io); | |
| 707 | + return -ENODEV; | |
| 688 | 708 | } |
| 689 | 709 | |
| 690 | 710 | static int |
| @@ -1163,8 +1163,6 @@ struct net_device *gether_connect(struct gether *link) · 1162 unmodified lines | ||
| 1163 | 1163 | if (netif_running(dev->net)) |
| 1164 | 1164 | eth_start(dev, GFP_ATOMIC); |
| 1165 | 1165 | |
| 1166 | − netif_device_attach(dev->net); | |
| 1167 | − | |
| 1168 | 1166 | /* on error, disable any endpoints */ |
| 1169 | 1167 | } else { |
| 1170 | 1168 | (void) usb_ep_disable(link->out_ep); |
| @@ -1202,7 +1200,7 @@ void gether_disconnect(struct gether *link) · 31 unmodified lines | ||
| 1202 | 1200 | |
| 1203 | 1201 | DBG(dev, "%s\n", __func__); |
| 1204 | 1202 | |
| 1205 | − netif_device_detach(dev->net); | |
| 1203 | + netif_stop_queue(dev->net); | |
| 1206 | 1204 | netif_carrier_off(dev->net); |
| 1207 | 1205 | |
| 1208 | 1206 | /* disable endpoints, forcing (synchronous) completion |
| @@ -66,8 +66,8 @@ · 65 unmodified lines | ||
| 66 | 66 | #define USB_UPSTREAM_EN BIT(0) |
| 67 | 67 | |
| 68 | 68 | /* Main config reg */ |
| 69 | −#define UDC_CFG_SET_ADDR(x) ((x) & 0x3f) | |
| 70 | −#define UDC_CFG_ADDR_MASK (0x3f) | |
| 69 | +#define UDC_CFG_SET_ADDR(x) ((x) & UDC_CFG_ADDR_MASK) | |
| 70 | +#define UDC_CFG_ADDR_MASK GENMASK(6, 0) | |
| 71 | 71 | |
| 72 | 72 | /* Interrupt ctrl & status reg */ |
| 73 | 73 | #define UDC_IRQ_EP_POOL_NAK BIT(17) |
| @@ -556,7 +556,7 @@ static int da8xx_probe(struct platform_device *pdev) · 555 unmodified lines | ||
| 556 | 556 | ret = of_platform_populate(pdev->dev.of_node, NULL, |
| 557 | 557 | da8xx_auxdata_lookup, &pdev->dev); |
| 558 | 558 | if (ret) |
| 559 | − return ret; | |
| 559 | + goto err_unregister_phy; | |
| 560 | 560 | |
| 561 | 561 | pinfo = da8xx_dev_info; |
| 562 | 562 | pinfo.parent = &pdev->dev; |
| @@ -571,9 +571,13 @@ static int da8xx_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 571 | 571 | ret = PTR_ERR_OR_ZERO(glue->musb); |
| 572 | 572 | if (ret) { |
| 573 | 573 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
| 574 | − usb_phy_generic_unregister(glue->usb_phy); | |
| 574 | + goto err_unregister_phy; | |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | + return 0; | |
| 578 | + | |
| 579 | +err_unregister_phy: | |
| 580 | + usb_phy_generic_unregister(glue->usb_phy); | |
| 577 | 581 | return ret; |
| 578 | 582 | } |
| 579 | 583 | |
| @@ -25,6 +25,7 @@ struct ucsi_acpi { · 24 unmodified lines | ||
| 25 | 25 | unsigned long flags; |
| 26 | 26 | #define UCSI_ACPI_COMMAND_PENDING 1 |
| 27 | 27 | #define UCSI_ACPI_ACK_PENDING 2 |
| 28 | +#define UCSI_ACPI_CHECK_BOGUS_EVENT 3 | |
| 28 | 29 | guid_t guid; |
| 29 | 30 | u64 cmd; |
| 30 | 31 | }; |
| @@ -128,6 +129,58 @@ static const struct ucsi_operations ucsi_zenbook_ops = { · 97 unmodified lines | ||
| 128 | 129 | .async_write = ucsi_acpi_async_write |
| 129 | 130 | }; |
| 130 | 131 | |
| 132 | +static int ucsi_gram_read(struct ucsi *ucsi, unsigned int offset, | |
| 133 | + void *val, size_t val_len) | |
| 134 | +{ | |
| 135 | + u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE | | |
| 136 | + UCSI_CONSTAT_PDOS_CHANGE; | |
| 137 | + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); | |
| 138 | + struct ucsi_connector_status *status; | |
| 139 | + int ret; | |
| 140 | + | |
| 141 | + ret = ucsi_acpi_read(ucsi, offset, val, val_len); | |
| 142 | + if (ret < 0) | |
| 143 | + return ret; | |
| 144 | + | |
| 145 | + if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS && | |
| 146 | + test_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags) && | |
| 147 | + offset == UCSI_MESSAGE_IN) { | |
| 148 | + status = (struct ucsi_connector_status *)val; | |
| 149 | + | |
| 150 | + /* Clear the bogus change */ | |
| 151 | + if (status->change == bogus_change) | |
| 152 | + status->change = 0; | |
| 153 | + | |
| 154 | + clear_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags); | |
| 155 | + } | |
| 156 | + | |
| 157 | + return ret; | |
| 158 | +} | |
| 159 | + | |
| 160 | +static int ucsi_gram_sync_write(struct ucsi *ucsi, unsigned int offset, | |
| 161 | + const void *val, size_t val_len) | |
| 162 | +{ | |
| 163 | + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); | |
| 164 | + int ret; | |
| 165 | + | |
| 166 | + ret = ucsi_acpi_sync_write(ucsi, offset, val, val_len); | |
| 167 | + if (ret < 0) | |
| 168 | + return ret; | |
| 169 | + | |
| 170 | + if (UCSI_COMMAND(ua->cmd) == UCSI_GET_PDOS && | |
| 171 | + ua->cmd & UCSI_GET_PDOS_PARTNER_PDO(1) && | |
| 172 | + ua->cmd & UCSI_GET_PDOS_SRC_PDOS) | |
| 173 | + set_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags); | |
| 174 | + | |
| 175 | + return ret; | |
| 176 | +} | |
| 177 | + | |
| 178 | +static const struct ucsi_operations ucsi_gram_ops = { | |
| 179 | + .read = ucsi_gram_read, | |
| 180 | + .sync_write = ucsi_gram_sync_write, | |
| 181 | + .async_write = ucsi_acpi_async_write | |
| 182 | +}; | |
| 183 | + | |
| 131 | 184 | static const struct dmi_system_id ucsi_acpi_quirks[] = { |
| 132 | 185 | { |
| 133 | 186 | .matches = { |
| @@ -136,6 +189,14 @@ static const struct dmi_system_id ucsi_acpi_quirks[] = { · 2 unmodified lines | ||
| 136 | 189 | }, |
| 137 | 190 | .driver_data = (void *)&ucsi_zenbook_ops, |
| 138 | 191 | }, |
| 192 | + { | |
| 193 | + .matches = { | |
| 194 | + DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | |
| 195 | + DMI_MATCH(DMI_PRODUCT_FAMILY, "LG gram PC"), | |
| 196 | + DMI_MATCH(DMI_PRODUCT_NAME, "90Q"), | |
| 197 | + }, | |
| 198 | + .driver_data = (void *)&ucsi_gram_ops, | |
| 199 | + }, | |
| 139 | 200 | { } |
| 140 | 201 | }; |
| 141 | 202 | |
| @@ -372,6 +372,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, · 371 unmodified lines | ||
| 372 | 372 | ret = fwnode_property_read_u32(fwnode, "reg", &port); |
| 373 | 373 | if (ret < 0) { |
| 374 | 374 | dev_err(dev, "missing reg property of %pOFn\n", fwnode); |
| 375 | + fwnode_handle_put(fwnode); | |
| 375 | 376 | return ret; |
| 376 | 377 | } |
| 377 | 378 | |
| @@ -386,9 +387,11 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, · 8 unmodified lines | ||
| 386 | 387 | if (!desc) |
| 387 | 388 | continue; |
| 388 | 389 | |
| 389 | − if (IS_ERR(desc)) | |
| 390 | + if (IS_ERR(desc)) { | |
| 391 | + fwnode_handle_put(fwnode); | |
| 390 | 392 | return dev_err_probe(dev, PTR_ERR(desc), |
| 391 | 393 | "unable to acquire orientation gpio\n"); |
| 394 | + } | |
| 392 | 395 | ucsi->port_orientation[port] = desc; |
| 393 | 396 | } |
| 394 | 397 | |
| @@ -65,6 +65,7 @@ struct ucsi_stm32g0 { · 64 unmodified lines | ||
| 65 | 65 | struct device *dev; |
| 66 | 66 | unsigned long flags; |
| 67 | 67 | #define COMMAND_PENDING 1 |
| 68 | +#define ACK_PENDING 2 | |
| 68 | 69 | const char *fw_name; |
| 69 | 70 | struct ucsi *ucsi; |
| 70 | 71 | bool suspended; |
| @@ -396,9 +397,13 @@ static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const · 325 unmodified lines | ||
| 396 | 397 | size_t len) |
| 397 | 398 | { |
| 398 | 399 | struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); |
| 400 | + bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; | |
| 399 | 401 | int ret; |
| 400 | 402 | |
| 401 | − set_bit(COMMAND_PENDING, &g0->flags); | |
| 403 | + if (ack) | |
| 404 | + set_bit(ACK_PENDING, &g0->flags); | |
| 405 | + else | |
| 406 | + set_bit(COMMAND_PENDING, &g0->flags); | |
| 402 | 407 | |
| 403 | 408 | ret = ucsi_stm32g0_async_write(ucsi, offset, val, len); |
| 404 | 409 | if (ret) |
| @@ -406,9 +411,14 @@ static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const · 1 unmodified line | ||
| 406 | 411 | |
| 407 | 412 | if (!wait_for_completion_timeout(&g0->complete, msecs_to_jiffies(5000))) |
| 408 | 413 | ret = -ETIMEDOUT; |
| 414 | + else | |
| 415 | + return 0; | |
| 409 | 416 | |
| 410 | 417 | out_clear_bit: |
| 411 | − clear_bit(COMMAND_PENDING, &g0->flags); | |
| 418 | + if (ack) | |
| 419 | + clear_bit(ACK_PENDING, &g0->flags); | |
| 420 | + else | |
| 421 | + clear_bit(COMMAND_PENDING, &g0->flags); | |
| 412 | 422 | |
| 413 | 423 | return ret; |
| 414 | 424 | } |
| @@ -429,8 +439,9 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data) · 14 unmodified lines | ||
| 429 | 439 | if (UCSI_CCI_CONNECTOR(cci)) |
| 430 | 440 | ucsi_connector_change(g0->ucsi, UCSI_CCI_CONNECTOR(cci)); |
| 431 | 441 | |
| 432 | − if (test_bit(COMMAND_PENDING, &g0->flags) && | |
| 433 | − cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE)) | |
| 442 | + if (cci & UCSI_CCI_ACK_COMPLETE && test_and_clear_bit(ACK_PENDING, &g0->flags)) | |
| 443 | + complete(&g0->complete); | |
| 444 | + if (cci & UCSI_CCI_COMMAND_COMPLETE && test_and_clear_bit(COMMAND_PENDING, &g0->flags)) | |
| 434 | 445 | complete(&g0->complete); |
| 435 | 446 | |
| 436 | 447 | return IRQ_HANDLED; |
| @@ -257,6 +257,7 @@ config GPIO_WATCHDOG_ARCH_INITCALL · 256 unmodified lines | ||
| 257 | 257 | config LENOVO_SE10_WDT |
| 258 | 258 | tristate "Lenovo SE10 Watchdog" |
| 259 | 259 | depends on (X86 && DMI) || COMPILE_TEST |
| 260 | + depends on HAS_IOPORT | |
| 260 | 261 | select WATCHDOG_CORE |
| 261 | 262 | help |
| 262 | 263 | If you say yes here you get support for the watchdog |
| @@ -161,6 +161,7 @@ static struct mcb_driver men_z069_driver = { · 160 unmodified lines | ||
| 161 | 161 | module_mcb_driver(men_z069_driver); |
| 162 | 162 | |
| 163 | 163 | MODULE_AUTHOR("Johannes Thumshirn <jth@kernel.org>"); |
| 164 | +MODULE_DESCRIPTION("Watchdog driver for the MEN z069 IP-Core"); | |
| 164 | 165 | MODULE_LICENSE("GPL v2"); |
| 165 | 166 | MODULE_ALIAS("mcb:16z069"); |
| 166 | 167 | MODULE_IMPORT_NS(MCB); |
| @@ -370,5 +370,6 @@ static struct platform_driver omap_wdt_driver = { · 369 unmodified lines | ||
| 370 | 370 | module_platform_driver(omap_wdt_driver); |
| 371 | 371 | |
| 372 | 372 | MODULE_AUTHOR("George G. Davis"); |
| 373 | +MODULE_DESCRIPTION("Driver for the TI OMAP 16xx/24xx/34xx 32KHz (non-secure) watchdog"); | |
| 373 | 374 | MODULE_LICENSE("GPL"); |
| 374 | 375 | MODULE_ALIAS("platform:omap_wdt"); |
| @@ -227,6 +227,7 @@ static struct platform_driver simatic_ipc_wdt_driver = { · 226 unmodified lines | ||
| 227 | 227 | |
| 228 | 228 | module_platform_driver(simatic_ipc_wdt_driver); |
| 229 | 229 | |
| 230 | +MODULE_DESCRIPTION("Siemens SIMATIC IPC driver for Watchdogs"); | |
| 230 | 231 | MODULE_LICENSE("GPL v2"); |
| 231 | 232 | MODULE_ALIAS("platform:" KBUILD_MODNAME); |
| 232 | 233 | MODULE_AUTHOR("Gerd Haeussler <gerd.haeussler.ext@siemens.com>"); |
| @@ -200,5 +200,6 @@ static struct platform_driver ts4800_wdt_driver = { · 199 unmodified lines | ||
| 200 | 200 | module_platform_driver(ts4800_wdt_driver); |
| 201 | 201 | |
| 202 | 202 | MODULE_AUTHOR("Damien Riegel <damien.riegel@savoirfairelinux.com>"); |
| 203 | +MODULE_DESCRIPTION("Watchdog driver for TS-4800 based boards"); | |
| 203 | 204 | MODULE_LICENSE("GPL v2"); |
| 204 | 205 | MODULE_ALIAS("platform:ts4800_wdt"); |
| @@ -118,6 +118,7 @@ static struct platform_driver twl4030_wdt_driver = { · 117 unmodified lines | ||
| 118 | 118 | module_platform_driver(twl4030_wdt_driver); |
| 119 | 119 | |
| 120 | 120 | MODULE_AUTHOR("Nokia Corporation"); |
| 121 | +MODULE_DESCRIPTION("TWL4030 Watchdog"); | |
| 121 | 122 | MODULE_LICENSE("GPL"); |
| 122 | 123 | MODULE_ALIAS("platform:twl4030_wdt"); |
| 123 | 124 | |
| @@ -512,7 +512,7 @@ static int afs_iget5_set_root(struct inode *inode, void *opaque) · 511 unmodified lines | ||
| 512 | 512 | struct afs_vnode *vnode = AFS_FS_I(inode); |
| 513 | 513 | |
| 514 | 514 | vnode->volume = as->volume; |
| 515 | − vnode->fid.vid = as->volume->vid, | |
| 515 | + vnode->fid.vid = as->volume->vid; | |
| 516 | 516 | vnode->fid.vnode = 1; |
| 517 | 517 | vnode->fid.unique = 1; |
| 518 | 518 | inode->i_ino = 1; |
| @@ -545,7 +545,7 @@ struct inode *afs_root_iget(struct super_block *sb, struct key *key) · 26 unmodified lines | ||
| 545 | 545 | BUG_ON(!(inode->i_state & I_NEW)); |
| 546 | 546 | |
| 547 | 547 | vnode = AFS_FS_I(inode); |
| 548 | − vnode->cb_v_check = atomic_read(&as->volume->cb_v_break), | |
| 548 | + vnode->cb_v_check = atomic_read(&as->volume->cb_v_break); | |
| 549 | 549 | afs_set_netfs_context(vnode); |
| 550 | 550 | |
| 551 | 551 | op = afs_alloc_operation(key, as->volume); |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/sched/task.h> |
| 30 | 30 | #include <linux/sort.h> |
| 31 | 31 | |
| 32 | −static void bch2_discard_one_bucket_fast(struct bch_fs *c, struct bpos bucket); | |
| 32 | +static void bch2_discard_one_bucket_fast(struct bch_dev *, u64); | |
| 33 | 33 | |
| 34 | 34 | /* Persistent alloc info: */ |
| 35 | 35 | |
| @@ -893,12 +893,12 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 857 unmodified lines | ||
| 893 | 893 | if (statechange(a->data_type == BCH_DATA_need_discard) && |
| 894 | 894 | !bch2_bucket_is_open_safe(c, new.k->p.inode, new.k->p.offset) && |
| 895 | 895 | bucket_flushed(new_a)) |
| 896 | − bch2_discard_one_bucket_fast(c, new.k->p); | |
| 896 | + bch2_discard_one_bucket_fast(ca, new.k->p.offset); | |
| 897 | 897 | |
| 898 | 898 | if (statechange(a->data_type == BCH_DATA_cached) && |
| 899 | 899 | !bch2_bucket_is_open(c, new.k->p.inode, new.k->p.offset) && |
| 900 | 900 | should_invalidate_buckets(ca, bch2_dev_usage_read(ca))) |
| 901 | − bch2_do_invalidates(c); | |
| 901 | + bch2_dev_do_invalidates(ca); | |
| 902 | 902 | |
| 903 | 903 | if (statechange(a->data_type == BCH_DATA_need_gc_gens)) |
| 904 | 904 | bch2_gc_gens_async(c); |
| @@ -1636,34 +1636,38 @@ int bch2_check_alloc_to_lru_refs(struct bch_fs *c) · 731 unmodified lines | ||
| 1636 | 1636 | return ret; |
| 1637 | 1637 | } |
| 1638 | 1638 | |
| 1639 | −static int discard_in_flight_add(struct bch_fs *c, struct bpos bucket) | |
| 1639 | +static int discard_in_flight_add(struct bch_dev *ca, u64 bucket, bool in_progress) | |
| 1640 | 1640 | { |
| 1641 | 1641 | int ret; |
| 1642 | 1642 | |
| 1643 | − mutex_lock(&c->discard_buckets_in_flight_lock); | |
| 1644 | − darray_for_each(c->discard_buckets_in_flight, i) | |
| 1645 | − if (bkey_eq(*i, bucket)) { | |
| 1643 | + mutex_lock(&ca->discard_buckets_in_flight_lock); | |
| 1644 | + darray_for_each(ca->discard_buckets_in_flight, i) | |
| 1645 | + if (i->bucket == bucket) { | |
| 1646 | 1646 | ret = -BCH_ERR_EEXIST_discard_in_flight_add; |
| 1647 | 1647 | goto out; |
| 1648 | 1648 | } |
| 1649 | 1649 | |
| 1650 | − ret = darray_push(&c->discard_buckets_in_flight, bucket); | |
| 1650 | + ret = darray_push(&ca->discard_buckets_in_flight, ((struct discard_in_flight) { | |
| 1651 | + .in_progress = in_progress, | |
| 1652 | + .bucket = bucket, | |
| 1653 | + })); | |
| 1651 | 1654 | out: |
| 1652 | − mutex_unlock(&c->discard_buckets_in_flight_lock); | |
| 1655 | + mutex_unlock(&ca->discard_buckets_in_flight_lock); | |
| 1653 | 1656 | return ret; |
| 1654 | 1657 | } |
| 1655 | 1658 | |
| 1656 | −static void discard_in_flight_remove(struct bch_fs *c, struct bpos bucket) | |
| 1659 | +static void discard_in_flight_remove(struct bch_dev *ca, u64 bucket) | |
| 1657 | 1660 | { |
| 1658 | − mutex_lock(&c->discard_buckets_in_flight_lock); | |
| 1659 | − darray_for_each(c->discard_buckets_in_flight, i) | |
| 1660 | − if (bkey_eq(*i, bucket)) { | |
| 1661 | − darray_remove_item(&c->discard_buckets_in_flight, i); | |
| 1661 | + mutex_lock(&ca->discard_buckets_in_flight_lock); | |
| 1662 | + darray_for_each(ca->discard_buckets_in_flight, i) | |
| 1663 | + if (i->bucket == bucket) { | |
| 1664 | + BUG_ON(!i->in_progress); | |
| 1665 | + darray_remove_item(&ca->discard_buckets_in_flight, i); | |
| 1662 | 1666 | goto found; |
| 1663 | 1667 | } |
| 1664 | 1668 | BUG(); |
| 1665 | 1669 | found: |
| 1666 | − mutex_unlock(&c->discard_buckets_in_flight_lock); | |
| 1670 | + mutex_unlock(&ca->discard_buckets_in_flight_lock); | |
| 1667 | 1671 | } |
| 1668 | 1672 | |
| 1669 | 1673 | struct discard_buckets_state { |
| @@ -1671,26 +1675,11 @@ struct discard_buckets_state { · 1 unmodified line | ||
| 1671 | 1675 | u64 open; |
| 1672 | 1676 | u64 need_journal_commit; |
| 1673 | 1677 | u64 discarded; |
| 1674 | − struct bch_dev *ca; | |
| 1675 | 1678 | u64 need_journal_commit_this_dev; |
| 1676 | 1679 | }; |
| 1677 | 1680 | |
| 1678 | −static void discard_buckets_next_dev(struct bch_fs *c, struct discard_buckets_state *s, struct bch_dev *ca) | |
| 1679 | −{ | |
| 1680 | − if (s->ca == ca) | |
| 1681 | − return; | |
| 1682 | − | |
| 1683 | − if (s->ca && s->need_journal_commit_this_dev > | |
| 1684 | − bch2_dev_usage_read(s->ca).d[BCH_DATA_free].buckets) | |
| 1685 | − bch2_journal_flush_async(&c->journal, NULL); | |
| 1686 | − | |
| 1687 | − if (s->ca) | |
| 1688 | − percpu_ref_put(&s->ca->io_ref); | |
| 1689 | − s->ca = ca; | |
| 1690 | − s->need_journal_commit_this_dev = 0; | |
| 1691 | −} | |
| 1692 | − | |
| 1693 | 1681 | static int bch2_discard_one_bucket(struct btree_trans *trans, |
| 1682 | + struct bch_dev *ca, | |
| 1694 | 1683 | struct btree_iter *need_discard_iter, |
| 1695 | 1684 | struct bpos *discard_pos_done, |
| 1696 | 1685 | struct discard_buckets_state *s) |
| @@ -1704,16 +1693,6 @@ static int bch2_discard_one_bucket(struct btree_trans *trans, · 7 unmodified lines | ||
| 1704 | 1693 | bool discard_locked = false; |
| 1705 | 1694 | int ret = 0; |
| 1706 | 1695 | |
| 1707 | − struct bch_dev *ca = s->ca && s->ca->dev_idx == pos.inode | |
| 1708 | − ? s->ca | |
| 1709 | − : bch2_dev_get_ioref(c, pos.inode, WRITE); | |
| 1710 | − if (!ca) { | |
| 1711 | − bch2_btree_iter_set_pos(need_discard_iter, POS(pos.inode + 1, 0)); | |
| 1712 | − return 0; | |
| 1713 | − } | |
| 1714 | − | |
| 1715 | − discard_buckets_next_dev(c, s, ca); | |
| 1716 | − | |
| 1717 | 1696 | if (bch2_bucket_is_open_safe(c, pos.inode, pos.offset)) { |
| 1718 | 1697 | s->open++; |
| 1719 | 1698 | goto out; |
| @@ -1773,7 +1752,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans, · 53 unmodified lines | ||
| 1773 | 1752 | goto out; |
| 1774 | 1753 | } |
| 1775 | 1754 | |
| 1776 | − if (discard_in_flight_add(c, SPOS(iter.pos.inode, iter.pos.offset, true))) | |
| 1755 | + if (discard_in_flight_add(ca, iter.pos.offset, true)) | |
| 1777 | 1756 | goto out; |
| 1778 | 1757 | |
| 1779 | 1758 | discard_locked = true; |
| @@ -1811,7 +1790,7 @@ write: · 31 unmodified lines | ||
| 1811 | 1790 | s->discarded++; |
| 1812 | 1791 | out: |
| 1813 | 1792 | if (discard_locked) |
| 1814 | − discard_in_flight_remove(c, iter.pos); | |
| 1793 | + discard_in_flight_remove(ca, iter.pos.offset); | |
| 1815 | 1794 | s->seen++; |
| 1816 | 1795 | bch2_trans_iter_exit(trans, &iter); |
| 1817 | 1796 | printbuf_exit(&buf); |
| @@ -1820,7 +1799,8 @@ out: · 2 unmodified lines | ||
| 1820 | 1799 | |
| 1821 | 1800 | static void bch2_do_discards_work(struct work_struct *work) |
| 1822 | 1801 | { |
| 1823 | − struct bch_fs *c = container_of(work, struct bch_fs, discard_work); | |
| 1802 | + struct bch_dev *ca = container_of(work, struct bch_dev, discard_work); | |
| 1803 | + struct bch_fs *c = ca->fs; | |
| 1824 | 1804 | struct discard_buckets_state s = {}; |
| 1825 | 1805 | struct bpos discard_pos_done = POS_MAX; |
| 1826 | 1806 | int ret; |
| @@ -1831,23 +1811,41 @@ static void bch2_do_discards_work(struct work_struct *work) · 4 unmodified lines | ||
| 1831 | 1811 | * successful commit: |
| 1832 | 1812 | */ |
| 1833 | 1813 | ret = bch2_trans_run(c, |
| 1834 | − for_each_btree_key(trans, iter, | |
| 1835 | − BTREE_ID_need_discard, POS_MIN, 0, k, | |
| 1836 | − bch2_discard_one_bucket(trans, &iter, &discard_pos_done, &s))); | |
| 1837 | − | |
| 1838 | − discard_buckets_next_dev(c, &s, NULL); | |
| 1814 | + for_each_btree_key_upto(trans, iter, | |
| 1815 | + BTREE_ID_need_discard, | |
| 1816 | + POS(ca->dev_idx, 0), | |
| 1817 | + POS(ca->dev_idx, U64_MAX), 0, k, | |
| 1818 | + bch2_discard_one_bucket(trans, ca, &iter, &discard_pos_done, &s))); | |
| 1839 | 1819 | |
| 1840 | 1820 | trace_discard_buckets(c, s.seen, s.open, s.need_journal_commit, s.discarded, |
| 1841 | 1821 | bch2_err_str(ret)); |
| 1842 | 1822 | |
| 1843 | 1823 | bch2_write_ref_put(c, BCH_WRITE_REF_discard); |
| 1824 | + percpu_ref_put(&ca->io_ref); | |
| 1825 | +} | |
| 1826 | + | |
| 1827 | +void bch2_dev_do_discards(struct bch_dev *ca) | |
| 1828 | +{ | |
| 1829 | + struct bch_fs *c = ca->fs; | |
| 1830 | + | |
| 1831 | + if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE)) | |
| 1832 | + return; | |
| 1833 | + | |
| 1834 | + if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard)) | |
| 1835 | + goto put_ioref; | |
| 1836 | + | |
| 1837 | + if (queue_work(c->write_ref_wq, &ca->discard_work)) | |
| 1838 | + return; | |
| 1839 | + | |
| 1840 | + bch2_write_ref_put(c, BCH_WRITE_REF_discard); | |
| 1841 | +put_ioref: | |
| 1842 | + percpu_ref_put(&ca->io_ref); | |
| 1844 | 1843 | } |
| 1845 | 1844 | |
| 1846 | 1845 | void bch2_do_discards(struct bch_fs *c) |
| 1847 | 1846 | { |
| 1848 | − if (bch2_write_ref_tryget(c, BCH_WRITE_REF_discard) && | |
| 1849 | − !queue_work(c->write_ref_wq, &c->discard_work)) | |
| 1850 | − bch2_write_ref_put(c, BCH_WRITE_REF_discard); | |
| 1847 | + for_each_member_device(c, ca) | |
| 1848 | + bch2_dev_do_discards(ca); | |
| 1851 | 1849 | } |
| 1852 | 1850 | |
| 1853 | 1851 | static int bch2_clear_bucket_needs_discard(struct btree_trans *trans, struct bpos bucket) |
| @@ -1876,68 +1874,69 @@ err: · 22 unmodified lines | ||
| 1876 | 1874 | |
| 1877 | 1875 | static void bch2_do_discards_fast_work(struct work_struct *work) |
| 1878 | 1876 | { |
| 1879 | − struct bch_fs *c = container_of(work, struct bch_fs, discard_fast_work); | |
| 1877 | + struct bch_dev *ca = container_of(work, struct bch_dev, discard_fast_work); | |
| 1878 | + struct bch_fs *c = ca->fs; | |
| 1880 | 1879 | |
| 1881 | 1880 | while (1) { |
| 1882 | 1881 | bool got_bucket = false; |
| 1883 | − struct bpos bucket; | |
| 1884 | − struct bch_dev *ca; | |
| 1882 | + u64 bucket; | |
| 1885 | 1883 | |
| 1886 | − mutex_lock(&c->discard_buckets_in_flight_lock); | |
| 1887 | − darray_for_each(c->discard_buckets_in_flight, i) { | |
| 1888 | − if (i->snapshot) | |
| 1884 | + mutex_lock(&ca->discard_buckets_in_flight_lock); | |
| 1885 | + darray_for_each(ca->discard_buckets_in_flight, i) { | |
| 1886 | + if (i->in_progress) | |
| 1889 | 1887 | continue; |
| 1890 | 1888 | |
| 1891 | − ca = bch2_dev_get_ioref(c, i->inode, WRITE); | |
| 1892 | − if (!ca) { | |
| 1893 | − darray_remove_item(&c->discard_buckets_in_flight, i); | |
| 1894 | − continue; | |
| 1895 | − } | |
| 1896 | − | |
| 1897 | 1889 | got_bucket = true; |
| 1898 | − bucket = *i; | |
| 1899 | − i->snapshot = true; | |
| 1890 | + bucket = i->bucket; | |
| 1891 | + i->in_progress = true; | |
| 1900 | 1892 | break; |
| 1901 | 1893 | } |
| 1902 | − mutex_unlock(&c->discard_buckets_in_flight_lock); | |
| 1894 | + mutex_unlock(&ca->discard_buckets_in_flight_lock); | |
| 1903 | 1895 | |
| 1904 | 1896 | if (!got_bucket) |
| 1905 | 1897 | break; |
| 1906 | 1898 | |
| 1907 | 1899 | if (ca->mi.discard && !c->opts.nochanges) |
| 1908 | 1900 | blkdev_issue_discard(ca->disk_sb.bdev, |
| 1909 | − bucket.offset * ca->mi.bucket_size, | |
| 1901 | + bucket_to_sector(ca, bucket), | |
| 1910 | 1902 | ca->mi.bucket_size, |
| 1911 | 1903 | GFP_KERNEL); |
| 1912 | 1904 | |
| 1913 | 1905 | int ret = bch2_trans_do(c, NULL, NULL, |
| 1914 | − BCH_WATERMARK_btree| | |
| 1915 | − BCH_TRANS_COMMIT_no_enospc, | |
| 1916 | − bch2_clear_bucket_needs_discard(trans, bucket)); | |
| 1906 | + BCH_WATERMARK_btree| | |
| 1907 | + BCH_TRANS_COMMIT_no_enospc, | |
| 1908 | + bch2_clear_bucket_needs_discard(trans, POS(ca->dev_idx, bucket))); | |
| 1917 | 1909 | bch_err_fn(c, ret); |
| 1918 | 1910 | |
| 1919 | − percpu_ref_put(&ca->io_ref); | |
| 1920 | − discard_in_flight_remove(c, bucket); | |
| 1911 | + discard_in_flight_remove(ca, bucket); | |
| 1921 | 1912 | |
| 1922 | 1913 | if (ret) |
| 1923 | 1914 | break; |
| 1924 | 1915 | } |
| 1925 | 1916 | |
| 1926 | 1917 | bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast); |
| 1918 | + percpu_ref_put(&ca->io_ref); | |
| 1927 | 1919 | } |
| 1928 | 1920 | |
| 1929 | −static void bch2_discard_one_bucket_fast(struct bch_fs *c, struct bpos bucket) | |
| 1921 | +static void bch2_discard_one_bucket_fast(struct bch_dev *ca, u64 bucket) | |
| 1930 | 1922 | { |
| 1931 | − rcu_read_lock(); | |
| 1932 | − struct bch_dev *ca = bch2_dev_rcu(c, bucket.inode); | |
| 1933 | − bool dead = !ca || percpu_ref_is_dying(&ca->io_ref); | |
| 1934 | − rcu_read_unlock(); | |
| 1923 | + struct bch_fs *c = ca->fs; | |
| 1924 | + | |
| 1925 | + if (discard_in_flight_add(ca, bucket, false)) | |
| 1926 | + return; | |
| 1927 | + | |
| 1928 | + if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE)) | |
| 1929 | + return; | |
| 1930 | + | |
| 1931 | + if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard_fast)) | |
| 1932 | + goto put_ioref; | |
| 1933 | + | |
| 1934 | + if (queue_work(c->write_ref_wq, &ca->discard_fast_work)) | |
| 1935 | + return; | |
| 1935 | 1936 | |
| 1936 | − if (!dead && | |
| 1937 | − !discard_in_flight_add(c, bucket) && | |
| 1938 | − bch2_write_ref_tryget(c, BCH_WRITE_REF_discard_fast) && | |
| 1939 | − !queue_work(c->write_ref_wq, &c->discard_fast_work)) | |
| 1940 | − bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast); | |
| 1937 | + bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast); | |
| 1938 | +put_ioref: | |
| 1939 | + percpu_ref_put(&ca->io_ref); | |
| 1941 | 1940 | } |
| 1942 | 1941 | |
| 1943 | 1942 | static int invalidate_one_bucket(struct btree_trans *trans, |
| @@ -2038,7 +2037,8 @@ again: · 94 unmodified lines | ||
| 2038 | 2037 | |
| 2039 | 2038 | static void bch2_do_invalidates_work(struct work_struct *work) |
| 2040 | 2039 | { |
| 2041 | − struct bch_fs *c = container_of(work, struct bch_fs, invalidate_work); | |
| 2040 | + struct bch_dev *ca = container_of(work, struct bch_dev, invalidate_work); | |
| 2041 | + struct bch_fs *c = ca->fs; | |
| 2042 | 2042 | struct btree_trans *trans = bch2_trans_get(c); |
| 2043 | 2043 | int ret = 0; |
| 2044 | 2044 | |
| @@ -2046,52 +2046,63 @@ static void bch2_do_invalidates_work(struct work_struct *work) · 1 unmodified line | ||
| 2046 | 2046 | if (ret) |
| 2047 | 2047 | goto err; |
| 2048 | 2048 | |
| 2049 | − for_each_member_device(c, ca) { | |
| 2050 | − s64 nr_to_invalidate = | |
| 2051 | − should_invalidate_buckets(ca, bch2_dev_usage_read(ca)); | |
| 2052 | − struct btree_iter iter; | |
| 2053 | − bool wrapped = false; | |
| 2054 | − | |
| 2055 | − bch2_trans_iter_init(trans, &iter, BTREE_ID_lru, | |
| 2056 | − lru_pos(ca->dev_idx, 0, | |
| 2057 | − ((bch2_current_io_time(c, READ) + U32_MAX) & | |
| 2058 | − LRU_TIME_MAX)), 0); | |
| 2059 | − | |
| 2060 | − while (true) { | |
| 2061 | − bch2_trans_begin(trans); | |
| 2062 | − | |
| 2063 | − struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped); | |
| 2064 | − ret = bkey_err(k); | |
| 2065 | − if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) | |
| 2066 | − continue; | |
| 2067 | − if (ret) | |
| 2068 | − break; | |
| 2069 | − if (!k.k) | |
| 2070 | − break; | |
| 2049 | + s64 nr_to_invalidate = | |
| 2050 | + should_invalidate_buckets(ca, bch2_dev_usage_read(ca)); | |
| 2051 | + struct btree_iter iter; | |
| 2052 | + bool wrapped = false; | |
| 2071 | 2053 | |
| 2072 | − ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate); | |
| 2073 | − if (ret) | |
| 2074 | − break; | |
| 2054 | + bch2_trans_iter_init(trans, &iter, BTREE_ID_lru, | |
| 2055 | + lru_pos(ca->dev_idx, 0, | |
| 2056 | + ((bch2_current_io_time(c, READ) + U32_MAX) & | |
| 2057 | + LRU_TIME_MAX)), 0); | |
| 2075 | 2058 | |
| 2076 | − bch2_btree_iter_advance(&iter); | |
| 2077 | − } | |
| 2078 | − bch2_trans_iter_exit(trans, &iter); | |
| 2059 | + while (true) { | |
| 2060 | + bch2_trans_begin(trans); | |
| 2079 | 2061 | |
| 2080 | − if (ret < 0) { | |
| 2081 | − bch2_dev_put(ca); | |
| 2062 | + struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped); | |
| 2063 | + ret = bkey_err(k); | |
| 2064 | + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) | |
| 2065 | + continue; | |
| 2066 | + if (ret) | |
| 2082 | 2067 | break; |
| 2083 | − } | |
| 2068 | + if (!k.k) | |
| 2069 | + break; | |
| 2070 | + | |
| 2071 | + ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate); | |
| 2072 | + if (ret) | |
| 2073 | + break; | |
| 2074 | + | |
| 2075 | + bch2_btree_iter_advance(&iter); | |
| 2084 | 2076 | } |
| 2077 | + bch2_trans_iter_exit(trans, &iter); | |
| 2085 | 2078 | err: |
| 2086 | 2079 | bch2_trans_put(trans); |
| 2087 | 2080 | bch2_write_ref_put(c, BCH_WRITE_REF_invalidate); |
| 2081 | + percpu_ref_put(&ca->io_ref); | |
| 2082 | +} | |
| 2083 | + | |
| 2084 | +void bch2_dev_do_invalidates(struct bch_dev *ca) | |
| 2085 | +{ | |
| 2086 | + struct bch_fs *c = ca->fs; | |
| 2087 | + | |
| 2088 | + if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE)) | |
| 2089 | + return; | |
| 2090 | + | |
| 2091 | + if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_invalidate)) | |
| 2092 | + goto put_ioref; | |
| 2093 | + | |
| 2094 | + if (queue_work(c->write_ref_wq, &ca->invalidate_work)) | |
| 2095 | + return; | |
| 2096 | + | |
| 2097 | + bch2_write_ref_put(c, BCH_WRITE_REF_invalidate); | |
| 2098 | +put_ioref: | |
| 2099 | + percpu_ref_put(&ca->io_ref); | |
| 2088 | 2100 | } |
| 2089 | 2101 | |
| 2090 | 2102 | void bch2_do_invalidates(struct bch_fs *c) |
| 2091 | 2103 | { |
| 2092 | − if (bch2_write_ref_tryget(c, BCH_WRITE_REF_invalidate) && | |
| 2093 | − !queue_work(c->write_ref_wq, &c->invalidate_work)) | |
| 2094 | − bch2_write_ref_put(c, BCH_WRITE_REF_invalidate); | |
| 2104 | + for_each_member_device(c, ca) | |
| 2105 | + bch2_dev_do_invalidates(ca); | |
| 2095 | 2106 | } |
| 2096 | 2107 | |
| 2097 | 2108 | int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca, |
| @@ -2407,16 +2418,20 @@ void bch2_dev_allocator_add(struct bch_fs *c, struct bch_dev *ca) · 309 unmodified lines | ||
| 2407 | 2418 | set_bit(ca->dev_idx, c->rw_devs[i].d); |
| 2408 | 2419 | } |
| 2409 | 2420 | |
| 2410 | −void bch2_fs_allocator_background_exit(struct bch_fs *c) | |
| 2421 | +void bch2_dev_allocator_background_exit(struct bch_dev *ca) | |
| 2422 | +{ | |
| 2423 | + darray_exit(&ca->discard_buckets_in_flight); | |
| 2424 | +} | |
| 2425 | + | |
| 2426 | +void bch2_dev_allocator_background_init(struct bch_dev *ca) | |
| 2411 | 2427 | { |
| 2412 | − darray_exit(&c->discard_buckets_in_flight); | |
| 2428 | + mutex_init(&ca->discard_buckets_in_flight_lock); | |
| 2429 | + INIT_WORK(&ca->discard_work, bch2_do_discards_work); | |
| 2430 | + INIT_WORK(&ca->discard_fast_work, bch2_do_discards_fast_work); | |
| 2431 | + INIT_WORK(&ca->invalidate_work, bch2_do_invalidates_work); | |
| 2413 | 2432 | } |
| 2414 | 2433 | |
| 2415 | 2434 | void bch2_fs_allocator_background_init(struct bch_fs *c) |
| 2416 | 2435 | { |
| 2417 | 2436 | spin_lock_init(&c->freelist_lock); |
| 2418 | − mutex_init(&c->discard_buckets_in_flight_lock); | |
| 2419 | − INIT_WORK(&c->discard_work, bch2_do_discards_work); | |
| 2420 | − INIT_WORK(&c->discard_fast_work, bch2_do_discards_fast_work); | |
| 2421 | − INIT_WORK(&c->invalidate_work, bch2_do_invalidates_work); | |
| 2422 | 2437 | } |
| @@ -275,6 +275,7 @@ int bch2_trigger_alloc(struct btree_trans *, enum btree_id, unsigned, · 274 unmodified lines | ||
| 275 | 275 | enum btree_iter_update_trigger_flags); |
| 276 | 276 | int bch2_check_alloc_info(struct bch_fs *); |
| 277 | 277 | int bch2_check_alloc_to_lru_refs(struct bch_fs *); |
| 278 | +void bch2_dev_do_discards(struct bch_dev *); | |
| 278 | 279 | void bch2_do_discards(struct bch_fs *); |
| 279 | 280 | |
| 280 | 281 | static inline u64 should_invalidate_buckets(struct bch_dev *ca, |
| @@ -289,6 +290,7 @@ static inline u64 should_invalidate_buckets(struct bch_dev *ca, · 8 unmodified lines | ||
| 289 | 290 | return clamp_t(s64, want_free - free, 0, u.d[BCH_DATA_cached].buckets); |
| 290 | 291 | } |
| 291 | 292 | |
| 293 | +void bch2_dev_do_invalidates(struct bch_dev *); | |
| 292 | 294 | void bch2_do_invalidates(struct bch_fs *); |
| 293 | 295 | |
| 294 | 296 | static inline struct bch_backpointer *alloc_v4_backpointers(struct bch_alloc_v4 *a) |
| @@ -312,7 +314,9 @@ u64 bch2_min_rw_member_capacity(struct bch_fs *); · 17 unmodified lines | ||
| 312 | 314 | void bch2_dev_allocator_remove(struct bch_fs *, struct bch_dev *); |
| 313 | 315 | void bch2_dev_allocator_add(struct bch_fs *, struct bch_dev *); |
| 314 | 316 | |
| 315 | −void bch2_fs_allocator_background_exit(struct bch_fs *); | |
| 317 | +void bch2_dev_allocator_background_exit(struct bch_dev *); | |
| 318 | +void bch2_dev_allocator_background_init(struct bch_dev *); | |
| 319 | + | |
| 316 | 320 | void bch2_fs_allocator_background_init(struct bch_fs *); |
| 317 | 321 | |
| 318 | 322 | #endif /* _BCACHEFS_ALLOC_BACKGROUND_H */ |
| @@ -621,13 +621,13 @@ again: · 620 unmodified lines | ||
| 621 | 621 | avail = dev_buckets_free(ca, *usage, watermark); |
| 622 | 622 | |
| 623 | 623 | if (usage->d[BCH_DATA_need_discard].buckets > avail) |
| 624 | − bch2_do_discards(c); | |
| 624 | + bch2_dev_do_discards(ca); | |
| 625 | 625 | |
| 626 | 626 | if (usage->d[BCH_DATA_need_gc_gens].buckets > avail) |
| 627 | 627 | bch2_gc_gens_async(c); |
| 628 | 628 | |
| 629 | 629 | if (should_invalidate_buckets(ca, *usage)) |
| 630 | − bch2_do_invalidates(c); | |
| 630 | + bch2_dev_do_invalidates(ca); | |
| 631 | 631 | |
| 632 | 632 | if (!avail) { |
| 633 | 633 | if (cl && !waiting) { |
| @@ -493,6 +493,11 @@ struct io_count { · 492 unmodified lines | ||
| 493 | 493 | u64 sectors[2][BCH_DATA_NR]; |
| 494 | 494 | }; |
| 495 | 495 | |
| 496 | +struct discard_in_flight { | |
| 497 | + bool in_progress:1; | |
| 498 | + u64 bucket:63; | |
| 499 | +}; | |
| 500 | + | |
| 496 | 501 | struct bch_dev { |
| 497 | 502 | struct kobject kobj; |
| 498 | 503 | #ifdef CONFIG_BCACHEFS_DEBUG |
| @@ -554,6 +559,12 @@ struct bch_dev { · 55 unmodified lines | ||
| 554 | 559 | size_t inc_gen_really_needs_gc; |
| 555 | 560 | size_t buckets_waiting_on_journal; |
| 556 | 561 | |
| 562 | + struct work_struct invalidate_work; | |
| 563 | + struct work_struct discard_work; | |
| 564 | + struct mutex discard_buckets_in_flight_lock; | |
| 565 | + DARRAY(struct discard_in_flight) discard_buckets_in_flight; | |
| 566 | + struct work_struct discard_fast_work; | |
| 567 | + | |
| 557 | 568 | atomic64_t rebalance_work; |
| 558 | 569 | |
| 559 | 570 | struct journal_device journal; |
| @@ -915,11 +926,6 @@ struct bch_fs { · 355 unmodified lines | ||
| 915 | 926 | unsigned write_points_nr; |
| 916 | 927 | |
| 917 | 928 | struct buckets_waiting_for_journal buckets_waiting_for_journal; |
| 918 | − struct work_struct invalidate_work; | |
| 919 | − struct work_struct discard_work; | |
| 920 | − struct mutex discard_buckets_in_flight_lock; | |
| 921 | − DARRAY(struct bpos) discard_buckets_in_flight; | |
| 922 | − struct work_struct discard_fast_work; | |
| 923 | 929 | |
| 924 | 930 | /* GARBAGE COLLECTION */ |
| 925 | 931 | struct work_struct gc_gens_work; |
| @@ -3130,7 +3130,6 @@ struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx) · 3129 unmodified lines | ||
| 3130 | 3130 | |
| 3131 | 3131 | trans = mempool_alloc(&c->btree_trans_pool, GFP_NOFS); |
| 3132 | 3132 | memset(trans, 0, sizeof(*trans)); |
| 3133 | − closure_init_stack(&trans->ref); | |
| 3134 | 3133 | |
| 3135 | 3134 | seqmutex_lock(&c->btree_trans_lock); |
| 3136 | 3135 | if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG)) { |
| @@ -3150,18 +3149,12 @@ struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx) · 13 unmodified lines | ||
| 3150 | 3149 | BUG_ON(pos_task && |
| 3151 | 3150 | pid == pos_task->pid && |
| 3152 | 3151 | pos->locked); |
| 3153 | − | |
| 3154 | − if (pos_task && pid < pos_task->pid) { | |
| 3155 | − list_add_tail(&trans->list, &pos->list); | |
| 3156 | − goto list_add_done; | |
| 3157 | − } | |
| 3158 | 3152 | } |
| 3159 | 3153 | } |
| 3160 | − list_add_tail(&trans->list, &c->btree_trans_list); | |
| 3161 | −list_add_done: | |
| 3154 | + | |
| 3155 | + list_add(&trans->list, &c->btree_trans_list); | |
| 3162 | 3156 | seqmutex_unlock(&c->btree_trans_lock); |
| 3163 | 3157 | got_trans: |
| 3164 | − trans->ref.closure_get_happened = false; | |
| 3165 | 3158 | trans->c = c; |
| 3166 | 3159 | trans->last_begin_time = local_clock(); |
| 3167 | 3160 | trans->fn_idx = fn_idx; |
| @@ -3200,6 +3193,8 @@ got_trans: · 32 unmodified lines | ||
| 3200 | 3193 | trans->srcu_idx = srcu_read_lock(&c->btree_trans_barrier); |
| 3201 | 3194 | trans->srcu_lock_time = jiffies; |
| 3202 | 3195 | trans->srcu_held = true; |
| 3196 | + | |
| 3197 | + closure_init_stack_release(&trans->ref); | |
| 3203 | 3198 | return trans; |
| 3204 | 3199 | } |
| 3205 | 3200 | |
| @@ -3257,10 +3252,10 @@ void bch2_trans_put(struct btree_trans *trans) · 51 unmodified lines | ||
| 3257 | 3252 | bch2_journal_keys_put(c); |
| 3258 | 3253 | |
| 3259 | 3254 | /* |
| 3260 | − * trans->ref protects trans->locking_wait.task, btree_paths arary; used | |
| 3255 | + * trans->ref protects trans->locking_wait.task, btree_paths array; used | |
| 3261 | 3256 | * by cycle detector |
| 3262 | 3257 | */ |
| 3263 | − closure_sync(&trans->ref); | |
| 3258 | + closure_return_sync(&trans->ref); | |
| 3264 | 3259 | trans->locking_wait.task = NULL; |
| 3265 | 3260 | |
| 3266 | 3261 | unsigned long *paths_allocated = trans->paths_allocated; |
| @@ -3385,8 +3380,6 @@ void bch2_fs_btree_iter_exit(struct bch_fs *c) · 118 unmodified lines | ||
| 3385 | 3380 | per_cpu_ptr(c->btree_trans_bufs, cpu)->trans; |
| 3386 | 3381 | |
| 3387 | 3382 | if (trans) { |
| 3388 | − closure_sync(&trans->ref); | |
| 3389 | − | |
| 3390 | 3383 | seqmutex_lock(&c->btree_trans_lock); |
| 3391 | 3384 | list_del(&trans->list); |
| 3392 | 3385 | seqmutex_unlock(&c->btree_trans_lock); |
| @@ -216,7 +216,8 @@ static long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_a · 215 unmodified lines | ||
| 216 | 216 | |
| 217 | 217 | ret = PTR_ERR_OR_ZERO(optstr) ?: |
| 218 | 218 | bch2_parse_mount_opts(NULL, &thr->opts, optstr); |
| 219 | − kfree(optstr); | |
| 219 | + if (!IS_ERR(optstr)) | |
| 220 | + kfree(optstr); | |
| 220 | 221 | |
| 221 | 222 | if (ret) |
| 222 | 223 | goto err; |
| @@ -319,7 +320,8 @@ static long bch2_ioctl_disk_add(struct bch_fs *c, struct bch_ioctl_disk arg) · 96 unmodified lines | ||
| 319 | 320 | return ret; |
| 320 | 321 | |
| 321 | 322 | ret = bch2_dev_add(c, path); |
| 322 | − kfree(path); | |
| 323 | + if (!IS_ERR(path)) | |
| 324 | + kfree(path); | |
| 323 | 325 | |
| 324 | 326 | return ret; |
| 325 | 327 | } |
| @@ -850,7 +852,8 @@ static long bch2_ioctl_fsck_online(struct bch_fs *c, · 524 unmodified lines | ||
| 850 | 852 | |
| 851 | 853 | ret = PTR_ERR_OR_ZERO(optstr) ?: |
| 852 | 854 | bch2_parse_mount_opts(c, &thr->opts, optstr); |
| 853 | − kfree(optstr); | |
| 855 | + if (!IS_ERR(optstr)) | |
| 856 | + kfree(optstr); | |
| 854 | 857 | |
| 855 | 858 | if (ret) |
| 856 | 859 | goto err; |
| @@ -568,6 +568,32 @@ static const struct file_operations cached_btree_nodes_ops = { · 567 unmodified lines | ||
| 568 | 568 | .read = bch2_cached_btree_nodes_read, |
| 569 | 569 | }; |
| 570 | 570 | |
| 571 | +typedef int (*list_cmp_fn)(const struct list_head *l, const struct list_head *r); | |
| 572 | + | |
| 573 | +static void list_sort(struct list_head *head, list_cmp_fn cmp) | |
| 574 | +{ | |
| 575 | + struct list_head *pos; | |
| 576 | + | |
| 577 | + list_for_each(pos, head) | |
| 578 | + while (!list_is_last(pos, head) && | |
| 579 | + cmp(pos, pos->next) > 0) { | |
| 580 | + struct list_head *pos2, *next = pos->next; | |
| 581 | + | |
| 582 | + list_del(next); | |
| 583 | + list_for_each(pos2, head) | |
| 584 | + if (cmp(next, pos2) < 0) | |
| 585 | + goto pos_found; | |
| 586 | + BUG(); | |
| 587 | +pos_found: | |
| 588 | + list_add_tail(next, pos2); | |
| 589 | + } | |
| 590 | +} | |
| 591 | + | |
| 592 | +static int list_ptr_order_cmp(const struct list_head *l, const struct list_head *r) | |
| 593 | +{ | |
| 594 | + return cmp_int(l, r); | |
| 595 | +} | |
| 596 | + | |
| 571 | 597 | static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf, |
| 572 | 598 | size_t size, loff_t *ppos) |
| 573 | 599 | { |
| @@ -575,41 +601,39 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf, · 1 unmodified line | ||
| 575 | 601 | struct bch_fs *c = i->c; |
| 576 | 602 | struct btree_trans *trans; |
| 577 | 603 | ssize_t ret = 0; |
| 578 | − u32 seq; | |
| 579 | 604 | |
| 580 | 605 | i->ubuf = buf; |
| 581 | 606 | i->size = size; |
| 582 | 607 | i->ret = 0; |
| 583 | 608 | restart: |
| 584 | 609 | seqmutex_lock(&c->btree_trans_lock); |
| 585 | − list_for_each_entry(trans, &c->btree_trans_list, list) { | |
| 586 | − struct task_struct *task = READ_ONCE(trans->locking_wait.task); | |
| 610 | + list_sort(&c->btree_trans_list, list_ptr_order_cmp); | |
| 587 | 611 | |
| 588 | − if (!task || task->pid <= i->iter) | |
| 612 | + list_for_each_entry(trans, &c->btree_trans_list, list) { | |
| 613 | + if ((ulong) trans < i->iter) | |
| 589 | 614 | continue; |
| 590 | 615 | |
| 591 | − closure_get(&trans->ref); | |
| 592 | − seq = seqmutex_seq(&c->btree_trans_lock); | |
| 593 | − seqmutex_unlock(&c->btree_trans_lock); | |
| 616 | + i->iter = (ulong) trans; | |
| 594 | 617 | |
| 595 | − ret = flush_buf(i); | |
| 596 | − if (ret) { | |
| 597 | − closure_put(&trans->ref); | |
| 598 | − goto unlocked; | |
| 599 | − } | |
| 618 | + if (!closure_get_not_zero(&trans->ref)) | |
| 619 | + continue; | |
| 620 | + | |
| 621 | + u32 seq = seqmutex_unlock(&c->btree_trans_lock); | |
| 600 | 622 | |
| 601 | 623 | bch2_btree_trans_to_text(&i->buf, trans); |
| 602 | 624 | |
| 603 | 625 | prt_printf(&i->buf, "backtrace:\n"); |
| 604 | 626 | printbuf_indent_add(&i->buf, 2); |
| 605 | − bch2_prt_task_backtrace(&i->buf, task, 0, GFP_KERNEL); | |
| 627 | + bch2_prt_task_backtrace(&i->buf, trans->locking_wait.task, 0, GFP_KERNEL); | |
| 606 | 628 | printbuf_indent_sub(&i->buf, 2); |
| 607 | 629 | prt_newline(&i->buf); |
| 608 | 630 | |
| 609 | − i->iter = task->pid; | |
| 610 | − | |
| 611 | 631 | closure_put(&trans->ref); |
| 612 | 632 | |
| 633 | + ret = flush_buf(i); | |
| 634 | + if (ret) | |
| 635 | + goto unlocked; | |
| 636 | + | |
| 613 | 637 | if (!seqmutex_relock(&c->btree_trans_lock, seq)) |
| 614 | 638 | goto restart; |
| 615 | 639 | } |
| @@ -804,50 +828,55 @@ static const struct file_operations btree_transaction_stats_op = { · 188 unmodified lines | ||
| 804 | 828 | .read = btree_transaction_stats_read, |
| 805 | 829 | }; |
| 806 | 830 | |
| 807 | −static ssize_t bch2_btree_deadlock_read(struct file *file, char __user *buf, | |
| 808 | − size_t size, loff_t *ppos) | |
| 831 | +/* walk btree transactions until we find a deadlock and print it */ | |
| 832 | +static void btree_deadlock_to_text(struct printbuf *out, struct bch_fs *c) | |
| 809 | 833 | { |
| 810 | − struct dump_iter *i = file->private_data; | |
| 811 | − struct bch_fs *c = i->c; | |
| 812 | 834 | struct btree_trans *trans; |
| 813 | − ssize_t ret = 0; | |
| 814 | − u32 seq; | |
| 815 | − | |
| 816 | − i->ubuf = buf; | |
| 817 | − i->size = size; | |
| 818 | − i->ret = 0; | |
| 819 | − | |
| 820 | − if (i->iter) | |
| 821 | − goto out; | |
| 835 | + pid_t iter = 0; | |
| 822 | 836 | restart: |
| 823 | 837 | seqmutex_lock(&c->btree_trans_lock); |
| 824 | 838 | list_for_each_entry(trans, &c->btree_trans_list, list) { |
| 825 | 839 | struct task_struct *task = READ_ONCE(trans->locking_wait.task); |
| 826 | 840 | |
| 827 | − if (!task || task->pid <= i->iter) | |
| 841 | + if (!task || task->pid <= iter) | |
| 828 | 842 | continue; |
| 829 | 843 | |
| 830 | − closure_get(&trans->ref); | |
| 831 | − seq = seqmutex_seq(&c->btree_trans_lock); | |
| 832 | − seqmutex_unlock(&c->btree_trans_lock); | |
| 844 | + iter = task->pid; | |
| 833 | 845 | |
| 834 | − ret = flush_buf(i); | |
| 835 | − if (ret) { | |
| 836 | − closure_put(&trans->ref); | |
| 837 | − goto out; | |
| 838 | − } | |
| 846 | + if (!closure_get_not_zero(&trans->ref)) | |
| 847 | + continue; | |
| 839 | 848 | |
| 840 | − bch2_check_for_deadlock(trans, &i->buf); | |
| 849 | + u32 seq = seqmutex_unlock(&c->btree_trans_lock); | |
| 841 | 850 | |
| 842 | − i->iter = task->pid; | |
| 851 | + bool found = bch2_check_for_deadlock(trans, out) != 0; | |
| 843 | 852 | |
| 844 | 853 | closure_put(&trans->ref); |
| 845 | 854 | |
| 855 | + if (found) | |
| 856 | + return; | |
| 857 | + | |
| 846 | 858 | if (!seqmutex_relock(&c->btree_trans_lock, seq)) |
| 847 | 859 | goto restart; |
| 848 | 860 | } |
| 849 | 861 | seqmutex_unlock(&c->btree_trans_lock); |
| 850 | −out: | |
| 862 | +} | |
| 863 | + | |
| 864 | +static ssize_t bch2_btree_deadlock_read(struct file *file, char __user *buf, | |
| 865 | + size_t size, loff_t *ppos) | |
| 866 | +{ | |
| 867 | + struct dump_iter *i = file->private_data; | |
| 868 | + struct bch_fs *c = i->c; | |
| 869 | + ssize_t ret = 0; | |
| 870 | + | |
| 871 | + i->ubuf = buf; | |
| 872 | + i->size = size; | |
| 873 | + i->ret = 0; | |
| 874 | + | |
| 875 | + if (!i->iter) { | |
| 876 | + btree_deadlock_to_text(&i->buf, c); | |
| 877 | + i->iter++; | |
| 878 | + } | |
| 879 | + | |
| 851 | 880 | if (i->buf.allocation_failure) |
| 852 | 881 | ret = -ENOMEM; |
| 853 | 882 | |
| @@ -1521,6 +1521,11 @@ bool bch2_journal_seq_pins_to_text(struct printbuf *out, struct journal *j, u64 · 1520 unmodified lines | ||
| 1521 | 1521 | struct journal_entry_pin *pin; |
| 1522 | 1522 | |
| 1523 | 1523 | spin_lock(&j->lock); |
| 1524 | + if (!test_bit(JOURNAL_running, &j->flags)) { | |
| 1525 | + spin_unlock(&j->lock); | |
| 1526 | + return true; | |
| 1527 | + } | |
| 1528 | + | |
| 1524 | 1529 | *seq = max(*seq, j->pin.front); |
| 1525 | 1530 | |
| 1526 | 1531 | if (*seq >= j->pin.back) { |
| @@ -1677,6 +1677,13 @@ static CLOSURE_CALLBACK(journal_write_done) · 1676 unmodified lines | ||
| 1677 | 1677 | mod_delayed_work(j->wq, &j->write_work, max(0L, delta)); |
| 1678 | 1678 | } |
| 1679 | 1679 | |
| 1680 | + /* | |
| 1681 | + * We don't typically trigger journal writes from her - the next journal | |
| 1682 | + * write will be triggered immediately after the previous one is | |
| 1683 | + * allocated, in bch2_journal_write() - but the journal write error path | |
| 1684 | + * is special: | |
| 1685 | + */ | |
| 1686 | + bch2_journal_do_writes(j); | |
| 1680 | 1687 | spin_unlock(&j->lock); |
| 1681 | 1688 | } |
| 1682 | 1689 | |
| @@ -232,7 +232,7 @@ bool bch2_blacklist_entries_gc(struct bch_fs *c) · 231 unmodified lines | ||
| 232 | 232 | BUG_ON(nr != t->nr); |
| 233 | 233 | |
| 234 | 234 | unsigned i; |
| 235 | − for (src = bl->start, i = eytzinger0_first(t->nr); | |
| 235 | + for (src = bl->start, i = t->nr == 0 ? 0 : eytzinger0_first(t->nr); | |
| 236 | 236 | src < bl->start + nr; |
| 237 | 237 | src++, i = eytzinger0_next(i, nr)) { |
| 238 | 238 | BUG_ON(t->entries[i].start != le64_to_cpu(src->start)); |
| @@ -110,19 +110,25 @@ out: · 109 unmodified lines | ||
| 110 | 110 | void bch2_sb_errors_from_cpu(struct bch_fs *c) |
| 111 | 111 | { |
| 112 | 112 | bch_sb_errors_cpu *src = &c->fsck_error_counts; |
| 113 | − struct bch_sb_field_errors *dst = | |
| 114 | − bch2_sb_field_resize(&c->disk_sb, errors, | |
| 115 | − bch2_sb_field_errors_u64s(src->nr)); | |
| 113 | + struct bch_sb_field_errors *dst; | |
| 116 | 114 | unsigned i; |
| 117 | 115 | |
| 116 | + mutex_lock(&c->fsck_error_counts_lock); | |
| 117 | + | |
| 118 | + dst = bch2_sb_field_resize(&c->disk_sb, errors, | |
| 119 | + bch2_sb_field_errors_u64s(src->nr)); | |
| 120 | + | |
| 118 | 121 | if (!dst) |
| 119 | − return; | |
| 122 | + goto err; | |
| 120 | 123 | |
| 121 | 124 | for (i = 0; i < src->nr; i++) { |
| 122 | 125 | SET_BCH_SB_ERROR_ENTRY_ID(&dst->entries[i], src->data[i].id); |
| 123 | 126 | SET_BCH_SB_ERROR_ENTRY_NR(&dst->entries[i], src->data[i].nr); |
| 124 | 127 | dst->entries[i].last_error_time = cpu_to_le64(src->data[i].last_error_time); |
| 125 | 128 | } |
| 129 | + | |
| 130 | +err: | |
| 131 | + mutex_unlock(&c->fsck_error_counts_lock); | |
| 126 | 132 | } |
| 127 | 133 | |
| 128 | 134 | static int bch2_sb_errors_to_cpu(struct bch_fs *c) |
| @@ -19,17 +19,14 @@ static inline bool seqmutex_trylock(struct seqmutex *lock) · 18 unmodified lines | ||
| 19 | 19 | static inline void seqmutex_lock(struct seqmutex *lock) |
| 20 | 20 | { |
| 21 | 21 | mutex_lock(&lock->lock); |
| 22 | −} | |
| 23 | − | |
| 24 | −static inline void seqmutex_unlock(struct seqmutex *lock) | |
| 25 | −{ | |
| 26 | 22 | lock->seq++; |
| 27 | − mutex_unlock(&lock->lock); | |
| 28 | 23 | } |
| 29 | 24 | |
| 30 | −static inline u32 seqmutex_seq(struct seqmutex *lock) | |
| 25 | +static inline u32 seqmutex_unlock(struct seqmutex *lock) | |
| 31 | 26 | { |
| 32 | − return lock->seq; | |
| 27 | + u32 seq = lock->seq; | |
| 28 | + mutex_unlock(&lock->lock); | |
| 29 | + return seq; | |
| 33 | 30 | } |
| 34 | 31 | |
| 35 | 32 | static inline bool seqmutex_relock(struct seqmutex *lock, u32 seq) |
| @@ -168,6 +168,9 @@ static noinline struct snapshot_t *__snapshot_t_mut(struct bch_fs *c, u32 id) · 167 unmodified lines | ||
| 168 | 168 | size_t new_bytes = kmalloc_size_roundup(struct_size(new, s, idx + 1)); |
| 169 | 169 | size_t new_size = (new_bytes - sizeof(*new)) / sizeof(new->s[0]); |
| 170 | 170 | |
| 171 | + if (unlikely(new_bytes > INT_MAX)) | |
| 172 | + return NULL; | |
| 173 | + | |
| 171 | 174 | new = kvzalloc(new_bytes, GFP_KERNEL); |
| 172 | 175 | if (!new) |
| 173 | 176 | return NULL; |
| @@ -536,7 +536,6 @@ static void __bch2_fs_free(struct bch_fs *c) · 535 unmodified lines | ||
| 536 | 536 | |
| 537 | 537 | bch2_find_btree_nodes_exit(&c->found_btree_nodes); |
| 538 | 538 | bch2_free_pending_node_rewrites(c); |
| 539 | − bch2_fs_allocator_background_exit(c); | |
| 540 | 539 | bch2_fs_sb_errors_exit(c); |
| 541 | 540 | bch2_fs_counters_exit(c); |
| 542 | 541 | bch2_fs_snapshots_exit(c); |
| @@ -1195,6 +1194,7 @@ static void bch2_dev_free(struct bch_dev *ca) · 652 unmodified lines | ||
| 1195 | 1194 | |
| 1196 | 1195 | kfree(ca->buckets_nouse); |
| 1197 | 1196 | bch2_free_super(&ca->disk_sb); |
| 1197 | + bch2_dev_allocator_background_exit(ca); | |
| 1198 | 1198 | bch2_dev_journal_exit(ca); |
| 1199 | 1199 | |
| 1200 | 1200 | free_percpu(ca->io_done); |
| @@ -1317,6 +1317,8 @@ static struct bch_dev *__bch2_dev_alloc(struct bch_fs *c, · 116 unmodified lines | ||
| 1317 | 1317 | atomic_long_set(&ca->ref, 1); |
| 1318 | 1318 | #endif |
| 1319 | 1319 | |
| 1320 | + bch2_dev_allocator_background_init(ca); | |
| 1321 | + | |
| 1320 | 1322 | if (percpu_ref_init(&ca->io_ref, bch2_dev_io_ref_complete, |
| 1321 | 1323 | PERCPU_REF_INIT_DEAD, GFP_KERNEL) || |
| 1322 | 1324 | !(ca->sb_read_scratch = (void *) __get_free_page(GFP_KERNEL)) || |
| @@ -1529,6 +1531,7 @@ static void __bch2_dev_read_only(struct bch_fs *c, struct bch_dev *ca) · 206 unmodified lines | ||
| 1529 | 1531 | * The allocator thread itself allocates btree nodes, so stop it first: |
| 1530 | 1532 | */ |
| 1531 | 1533 | bch2_dev_allocator_remove(c, ca); |
| 1534 | + bch2_recalc_capacity(c); | |
| 1532 | 1535 | bch2_dev_journal_stop(&c->journal, ca); |
| 1533 | 1536 | } |
| 1534 | 1537 | |
| @@ -1540,6 +1543,7 @@ static void __bch2_dev_read_write(struct bch_fs *c, struct bch_dev *ca) · 5 unmodified lines | ||
| 1540 | 1543 | |
| 1541 | 1544 | bch2_dev_allocator_add(c, ca); |
| 1542 | 1545 | bch2_recalc_capacity(c); |
| 1546 | + bch2_dev_do_discards(ca); | |
| 1543 | 1547 | } |
| 1544 | 1548 | |
| 1545 | 1549 | int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca, |
| @@ -1924,8 +1924,17 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) · 1923 unmodified lines | ||
| 1924 | 1924 | next: |
| 1925 | 1925 | if (ret) { |
| 1926 | 1926 | /* Refcount held by the reclaim_bgs list after splice. */ |
| 1927 | − btrfs_get_block_group(bg); | |
| 1928 | − list_add_tail(&bg->bg_list, &retry_list); | |
| 1927 | + spin_lock(&fs_info->unused_bgs_lock); | |
| 1928 | + /* | |
| 1929 | + * This block group might be added to the unused list | |
| 1930 | + * during the above process. Move it back to the | |
| 1931 | + * reclaim list otherwise. | |
| 1932 | + */ | |
| 1933 | + if (list_empty(&bg->bg_list)) { | |
| 1934 | + btrfs_get_block_group(bg); | |
| 1935 | + list_add_tail(&bg->bg_list, &retry_list); | |
| 1936 | + } | |
| 1937 | + spin_unlock(&fs_info->unused_bgs_lock); | |
| 1929 | 1938 | } |
| 1930 | 1939 | btrfs_put_block_group(bg); |
| 1931 | 1940 | |
| @@ -2697,7 +2697,7 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group, · 2696 unmodified lines | ||
| 2697 | 2697 | u64 offset = bytenr - block_group->start; |
| 2698 | 2698 | u64 to_free, to_unusable; |
| 2699 | 2699 | int bg_reclaim_threshold = 0; |
| 2700 | − bool initial = (size == block_group->length); | |
| 2700 | + bool initial = ((size == block_group->length) && (block_group->alloc_offset == 0)); | |
| 2701 | 2701 | u64 reclaimable_unusable; |
| 2702 | 2702 | |
| 2703 | 2703 | WARN_ON(!initial && offset + size > block_group->zone_capacity); |
| @@ -1351,7 +1351,7 @@ static int flush_reservations(struct btrfs_fs_info *fs_info) · 1350 unmodified lines | ||
| 1351 | 1351 | |
| 1352 | 1352 | int btrfs_quota_disable(struct btrfs_fs_info *fs_info) |
| 1353 | 1353 | { |
| 1354 | − struct btrfs_root *quota_root; | |
| 1354 | + struct btrfs_root *quota_root = NULL; | |
| 1355 | 1355 | struct btrfs_trans_handle *trans = NULL; |
| 1356 | 1356 | int ret = 0; |
| 1357 | 1357 | |
| @@ -1449,9 +1449,9 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) · 91 unmodified lines | ||
| 1449 | 1449 | btrfs_free_tree_block(trans, btrfs_root_id(quota_root), |
| 1450 | 1450 | quota_root->node, 0, 1); |
| 1451 | 1451 | |
| 1452 | − btrfs_put_root(quota_root); | |
| 1453 | 1452 | |
| 1454 | 1453 | out: |
| 1454 | + btrfs_put_root(quota_root); | |
| 1455 | 1455 | mutex_unlock(&fs_info->qgroup_ioctl_lock); |
| 1456 | 1456 | if (ret && trans) |
| 1457 | 1457 | btrfs_end_transaction(trans); |
| @@ -1688,20 +1688,24 @@ static void scrub_submit_extent_sector_read(struct scrub_ctx *sctx, · 1687 unmodified lines | ||
| 1688 | 1688 | (i << fs_info->sectorsize_bits); |
| 1689 | 1689 | int err; |
| 1690 | 1690 | |
| 1691 | − bbio = btrfs_bio_alloc(stripe->nr_sectors, REQ_OP_READ, | |
| 1692 | − fs_info, scrub_read_endio, stripe); | |
| 1693 | − bbio->bio.bi_iter.bi_sector = logical >> SECTOR_SHIFT; | |
| 1694 | − | |
| 1695 | 1691 | io_stripe.is_scrub = true; |
| 1692 | + stripe_len = (nr_sectors - i) << fs_info->sectorsize_bits; | |
| 1693 | + /* | |
| 1694 | + * For RST cases, we need to manually split the bbio to | |
| 1695 | + * follow the RST boundary. | |
| 1696 | + */ | |
| 1696 | 1697 | err = btrfs_map_block(fs_info, BTRFS_MAP_READ, logical, |
| 1697 | − &stripe_len, &bioc, &io_stripe, | |
| 1698 | − &mirror); | |
| 1698 | + &stripe_len, &bioc, &io_stripe, &mirror); | |
| 1699 | 1699 | btrfs_put_bioc(bioc); |
| 1700 | − if (err) { | |
| 1701 | − btrfs_bio_end_io(bbio, | |
| 1702 | − errno_to_blk_status(err)); | |
| 1703 | − return; | |
| 1700 | + if (err < 0) { | |
| 1701 | + set_bit(i, &stripe->io_error_bitmap); | |
| 1702 | + set_bit(i, &stripe->error_bitmap); | |
| 1703 | + continue; | |
| 1704 | 1704 | } |
| 1705 | + | |
| 1706 | + bbio = btrfs_bio_alloc(stripe->nr_sectors, REQ_OP_READ, | |
| 1707 | + fs_info, scrub_read_endio, stripe); | |
| 1708 | + bbio->bio.bi_iter.bi_sector = logical >> SECTOR_SHIFT; | |
| 1705 | 1709 | } |
| 1706 | 1710 | |
| 1707 | 1711 | __bio_add_page(&bbio->bio, page, fs_info->sectorsize, pgoff); |
| @@ -138,6 +138,25 @@ static void wait_log_commit(struct btrfs_root *root, int transid); · 137 unmodified lines | ||
| 138 | 138 | * and once to do all the other items. |
| 139 | 139 | */ |
| 140 | 140 | |
| 141 | +static struct inode *btrfs_iget_logging(u64 objectid, struct btrfs_root *root) | |
| 142 | +{ | |
| 143 | + unsigned int nofs_flag; | |
| 144 | + struct inode *inode; | |
| 145 | + | |
| 146 | + /* | |
| 147 | + * We're holding a transaction handle whether we are logging or | |
| 148 | + * replaying a log tree, so we must make sure NOFS semantics apply | |
| 149 | + * because btrfs_alloc_inode() may be triggered and it uses GFP_KERNEL | |
| 150 | + * to allocate an inode, which can recurse back into the filesystem and | |
| 151 | + * attempt a transaction commit, resulting in a deadlock. | |
| 152 | + */ | |
| 153 | + nofs_flag = memalloc_nofs_save(); | |
| 154 | + inode = btrfs_iget(root->fs_info->sb, objectid, root); | |
| 155 | + memalloc_nofs_restore(nofs_flag); | |
| 156 | + | |
| 157 | + return inode; | |
| 158 | +} | |
| 159 | + | |
| 141 | 160 | /* |
| 142 | 161 | * start a sub transaction and setup the log tree |
| 143 | 162 | * this increments the log tree writer count to make the people |
| @@ -600,7 +619,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root, · 456 unmodified lines | ||
| 600 | 619 | { |
| 601 | 620 | struct inode *inode; |
| 602 | 621 | |
| 603 | − inode = btrfs_iget(root->fs_info->sb, objectid, root); | |
| 622 | + inode = btrfs_iget_logging(objectid, root); | |
| 604 | 623 | if (IS_ERR(inode)) |
| 605 | 624 | inode = NULL; |
| 606 | 625 | return inode; |
| @@ -5438,7 +5457,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, · 4831 unmodified lines | ||
| 5438 | 5457 | struct btrfs_log_ctx *ctx) |
| 5439 | 5458 | { |
| 5440 | 5459 | struct btrfs_root *root = start_inode->root; |
| 5441 | − struct btrfs_fs_info *fs_info = root->fs_info; | |
| 5442 | 5460 | struct btrfs_path *path; |
| 5443 | 5461 | LIST_HEAD(dir_list); |
| 5444 | 5462 | struct btrfs_dir_list *dir_elem; |
| @@ -5499,7 +5517,7 @@ again: · 54 unmodified lines | ||
| 5499 | 5517 | continue; |
| 5500 | 5518 | |
| 5501 | 5519 | btrfs_release_path(path); |
| 5502 | − di_inode = btrfs_iget(fs_info->sb, di_key.objectid, root); | |
| 5520 | + di_inode = btrfs_iget_logging(di_key.objectid, root); | |
| 5503 | 5521 | if (IS_ERR(di_inode)) { |
| 5504 | 5522 | ret = PTR_ERR(di_inode); |
| 5505 | 5523 | goto out; |
| @@ -5559,7 +5577,7 @@ again: · 53 unmodified lines | ||
| 5559 | 5577 | btrfs_add_delayed_iput(curr_inode); |
| 5560 | 5578 | curr_inode = NULL; |
| 5561 | 5579 | |
| 5562 | − vfs_inode = btrfs_iget(fs_info->sb, ino, root); | |
| 5580 | + vfs_inode = btrfs_iget_logging(ino, root); | |
| 5563 | 5581 | if (IS_ERR(vfs_inode)) { |
| 5564 | 5582 | ret = PTR_ERR(vfs_inode); |
| 5565 | 5583 | break; |
| @@ -5654,7 +5672,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans, · 88 unmodified lines | ||
| 5654 | 5672 | if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES) |
| 5655 | 5673 | return BTRFS_LOG_FORCE_COMMIT; |
| 5656 | 5674 | |
| 5657 | − inode = btrfs_iget(root->fs_info->sb, ino, root); | |
| 5675 | + inode = btrfs_iget_logging(ino, root); | |
| 5658 | 5676 | /* |
| 5659 | 5677 | * If the other inode that had a conflicting dir entry was deleted in |
| 5660 | 5678 | * the current transaction then we either: |
| @@ -5755,7 +5773,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, · 94 unmodified lines | ||
| 5755 | 5773 | struct btrfs_root *root, |
| 5756 | 5774 | struct btrfs_log_ctx *ctx) |
| 5757 | 5775 | { |
| 5758 | − struct btrfs_fs_info *fs_info = root->fs_info; | |
| 5759 | 5776 | int ret = 0; |
| 5760 | 5777 | |
| 5761 | 5778 | /* |
| @@ -5786,7 +5803,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, · 24 unmodified lines | ||
| 5786 | 5803 | list_del(&curr->list); |
| 5787 | 5804 | kfree(curr); |
| 5788 | 5805 | |
| 5789 | − inode = btrfs_iget(fs_info->sb, ino, root); | |
| 5806 | + inode = btrfs_iget_logging(ino, root); | |
| 5790 | 5807 | /* |
| 5791 | 5808 | * If the other inode that had a conflicting dir entry was |
| 5792 | 5809 | * deleted in the current transaction, we need to log its parent |
| @@ -5797,7 +5814,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, · 4 unmodified lines | ||
| 5797 | 5814 | if (ret != -ENOENT) |
| 5798 | 5815 | break; |
| 5799 | 5816 | |
| 5800 | − inode = btrfs_iget(fs_info->sb, parent, root); | |
| 5817 | + inode = btrfs_iget_logging(parent, root); | |
| 5801 | 5818 | if (IS_ERR(inode)) { |
| 5802 | 5819 | ret = PTR_ERR(inode); |
| 5803 | 5820 | break; |
| @@ -6319,7 +6336,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans, · 515 unmodified lines | ||
| 6319 | 6336 | struct btrfs_log_ctx *ctx) |
| 6320 | 6337 | { |
| 6321 | 6338 | const bool orig_log_new_dentries = ctx->log_new_dentries; |
| 6322 | − struct btrfs_fs_info *fs_info = trans->fs_info; | |
| 6323 | 6339 | struct btrfs_delayed_item *item; |
| 6324 | 6340 | int ret = 0; |
| 6325 | 6341 | |
| @@ -6345,7 +6361,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans, · 19 unmodified lines | ||
| 6345 | 6361 | if (key.type == BTRFS_ROOT_ITEM_KEY) |
| 6346 | 6362 | continue; |
| 6347 | 6363 | |
| 6348 | − di_inode = btrfs_iget(fs_info->sb, key.objectid, inode->root); | |
| 6364 | + di_inode = btrfs_iget_logging(key.objectid, inode->root); | |
| 6349 | 6365 | if (IS_ERR(di_inode)) { |
| 6350 | 6366 | ret = PTR_ERR(di_inode); |
| 6351 | 6367 | break; |
| @@ -6729,7 +6745,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans, · 377 unmodified lines | ||
| 6729 | 6745 | struct btrfs_inode *inode, |
| 6730 | 6746 | struct btrfs_log_ctx *ctx) |
| 6731 | 6747 | { |
| 6732 | − struct btrfs_fs_info *fs_info = trans->fs_info; | |
| 6733 | 6748 | int ret; |
| 6734 | 6749 | struct btrfs_path *path; |
| 6735 | 6750 | struct btrfs_key key; |
| @@ -6794,8 +6809,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans, · 58 unmodified lines | ||
| 6794 | 6809 | cur_offset = item_size; |
| 6795 | 6810 | } |
| 6796 | 6811 | |
| 6797 | − dir_inode = btrfs_iget(fs_info->sb, inode_key.objectid, | |
| 6798 | − root); | |
| 6812 | + dir_inode = btrfs_iget_logging(inode_key.objectid, root); | |
| 6799 | 6813 | /* |
| 6800 | 6814 | * If the parent inode was deleted, return an error to |
| 6801 | 6815 | * fallback to a transaction commit. This is to prevent |
| @@ -6857,7 +6871,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans, · 55 unmodified lines | ||
| 6857 | 6871 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); |
| 6858 | 6872 | |
| 6859 | 6873 | while (true) { |
| 6860 | − struct btrfs_fs_info *fs_info = root->fs_info; | |
| 6861 | 6874 | struct extent_buffer *leaf; |
| 6862 | 6875 | int slot; |
| 6863 | 6876 | struct btrfs_key search_key; |
| @@ -6872,7 +6885,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans, · 8 unmodified lines | ||
| 6872 | 6885 | search_key.objectid = found_key.offset; |
| 6873 | 6886 | search_key.type = BTRFS_INODE_ITEM_KEY; |
| 6874 | 6887 | search_key.offset = 0; |
| 6875 | − inode = btrfs_iget(fs_info->sb, ino, root); | |
| 6888 | + inode = btrfs_iget_logging(ino, root); | |
| 6876 | 6889 | if (IS_ERR(inode)) |
| 6877 | 6890 | return PTR_ERR(inode); |
| 6878 | 6891 | |
| @@ -3029,28 +3029,25 @@ EXPORT_SYMBOL(d_splice_alias); · 3028 unmodified lines | ||
| 3029 | 3029 | |
| 3030 | 3030 | bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry) |
| 3031 | 3031 | { |
| 3032 | − bool result; | |
| 3032 | + bool subdir; | |
| 3033 | 3033 | unsigned seq; |
| 3034 | 3034 | |
| 3035 | 3035 | if (new_dentry == old_dentry) |
| 3036 | 3036 | return true; |
| 3037 | 3037 | |
| 3038 | − do { | |
| 3039 | − /* for restarting inner loop in case of seq retry */ | |
| 3040 | − seq = read_seqbegin(&rename_lock); | |
| 3041 | − /* | |
| 3042 | − * Need rcu_readlock to protect against the d_parent trashing | |
| 3043 | − * due to d_move | |
| 3044 | − */ | |
| 3045 | − rcu_read_lock(); | |
| 3046 | − if (d_ancestor(old_dentry, new_dentry)) | |
| 3047 | − result = true; | |
| 3048 | − else | |
| 3049 | − result = false; | |
| 3050 | − rcu_read_unlock(); | |
| 3051 | − } while (read_seqretry(&rename_lock, seq)); | |
| 3052 | − | |
| 3053 | − return result; | |
| 3038 | + /* Access d_parent under rcu as d_move() may change it. */ | |
| 3039 | + rcu_read_lock(); | |
| 3040 | + seq = read_seqbegin(&rename_lock); | |
| 3041 | + subdir = d_ancestor(old_dentry, new_dentry); | |
| 3042 | + /* Try lockless once... */ | |
| 3043 | + if (read_seqretry(&rename_lock, seq)) { | |
| 3044 | + /* ...else acquire lock for progress even on deep chains. */ | |
| 3045 | + read_seqlock_excl(&rename_lock); | |
| 3046 | + subdir = d_ancestor(old_dentry, new_dentry); | |
| 3047 | + read_sequnlock_excl(&rename_lock); | |
| 3048 | + } | |
| 3049 | + rcu_read_unlock(); | |
| 3050 | + return subdir; | |
| 3054 | 3051 | } |
| 3055 | 3052 | EXPORT_SYMBOL(is_subdir); |
| 3056 | 3053 | |
| @@ -343,7 +343,7 @@ static int erofs_read_superblock(struct super_block *sb) · 342 unmodified lines | ||
| 343 | 343 | sbi->build_time = le64_to_cpu(dsb->build_time); |
| 344 | 344 | sbi->build_time_nsec = le32_to_cpu(dsb->build_time_nsec); |
| 345 | 345 | |
| 346 | − memcpy(&sb->s_uuid, dsb->uuid, sizeof(dsb->uuid)); | |
| 346 | + super_set_uuid(sb, (void *)dsb->uuid, sizeof(dsb->uuid)); | |
| 347 | 347 | |
| 348 | 348 | ret = strscpy(sbi->volume_name, dsb->volume_name, |
| 349 | 349 | sizeof(dsb->volume_name)); |
| @@ -711,6 +711,8 @@ int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, · 710 unmodified lines | ||
| 711 | 711 | |
| 712 | 712 | err = z_erofs_do_map_blocks(inode, map, flags); |
| 713 | 713 | out: |
| 714 | + if (err) | |
| 715 | + map->m_llen = 0; | |
| 714 | 716 | trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err); |
| 715 | 717 | return err; |
| 716 | 718 | } |
| @@ -148,7 +148,7 @@ int __init z_erofs_gbuf_init(void) · 147 unmodified lines | ||
| 148 | 148 | |
| 149 | 149 | void z_erofs_gbuf_exit(void) |
| 150 | 150 | { |
| 151 | − int i; | |
| 151 | + int i, j; | |
| 152 | 152 | |
| 153 | 153 | for (i = 0; i < z_erofs_gbuf_count + (!!z_erofs_rsvbuf); ++i) { |
| 154 | 154 | struct z_erofs_gbuf *gbuf = &z_erofs_gbufpool[i]; |
| @@ -161,9 +161,9 @@ void z_erofs_gbuf_exit(void) · 6 unmodified lines | ||
| 161 | 161 | if (!gbuf->pages) |
| 162 | 162 | continue; |
| 163 | 163 | |
| 164 | − for (i = 0; i < gbuf->nrpages; ++i) | |
| 165 | − if (gbuf->pages[i]) | |
| 166 | − put_page(gbuf->pages[i]); | |
| 164 | + for (j = 0; j < gbuf->nrpages; ++j) | |
| 165 | + if (gbuf->pages[j]) | |
| 166 | + put_page(gbuf->pages[j]); | |
| 167 | 167 | kfree(gbuf->pages); |
| 168 | 168 | gbuf->pages = NULL; |
| 169 | 169 | } |
| @@ -2448,8 +2448,9 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, · 2447 unmodified lines | ||
| 2448 | 2448 | error = do_lock_file_wait(filp, cmd, file_lock); |
| 2449 | 2449 | |
| 2450 | 2450 | /* |
| 2451 | − * Attempt to detect a close/fcntl race and recover by releasing the | |
| 2452 | − * lock that was just acquired. There is no need to do that when we're | |
| 2451 | + * Detect close/fcntl races and recover by zapping all POSIX locks | |
| 2452 | + * associated with this file and our files_struct, just like on | |
| 2453 | + * filp_flush(). There is no need to do that when we're | |
| 2453 | 2454 | * unlocking though, or for OFD locks. |
| 2454 | 2455 | */ |
| 2455 | 2456 | if (!error && file_lock->c.flc_type != F_UNLCK && |
| @@ -2464,9 +2465,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, · 8 unmodified lines | ||
| 2464 | 2465 | f = files_lookup_fd_locked(files, fd); |
| 2465 | 2466 | spin_unlock(&files->file_lock); |
| 2466 | 2467 | if (f != filp) { |
| 2467 | − file_lock->c.flc_type = F_UNLCK; | |
| 2468 | − error = do_lock_file_wait(filp, cmd, file_lock); | |
| 2469 | − WARN_ON_ONCE(error); | |
| 2468 | + locks_remove_posix(filp, files); | |
| 2470 | 2469 | error = -EBADF; |
| 2471 | 2470 | } |
| 2472 | 2471 | } |
| @@ -3572,8 +3572,12 @@ static const char *open_last_lookups(struct nameidata *nd, · 3571 unmodified lines | ||
| 3572 | 3572 | else |
| 3573 | 3573 | inode_lock_shared(dir->d_inode); |
| 3574 | 3574 | dentry = lookup_open(nd, file, op, got_write); |
| 3575 | − if (!IS_ERR(dentry) && (file->f_mode & FMODE_CREATED)) | |
| 3576 | − fsnotify_create(dir->d_inode, dentry); | |
| 3575 | + if (!IS_ERR(dentry)) { | |
| 3576 | + if (file->f_mode & FMODE_CREATED) | |
| 3577 | + fsnotify_create(dir->d_inode, dentry); | |
| 3578 | + if (file->f_mode & FMODE_OPENED) | |
| 3579 | + fsnotify_open(file); | |
| 3580 | + } | |
| 3577 | 3581 | if (open_flag & O_CREAT) |
| 3578 | 3582 | inode_unlock(dir->d_inode); |
| 3579 | 3583 | else |
| @@ -3700,6 +3704,8 @@ int vfs_tmpfile(struct mnt_idmap *idmap, · 120 unmodified lines | ||
| 3700 | 3704 | mode = vfs_prepare_mode(idmap, dir, mode, mode, mode); |
| 3701 | 3705 | error = dir->i_op->tmpfile(idmap, dir, file, mode); |
| 3702 | 3706 | dput(child); |
| 3707 | + if (file->f_mode & FMODE_OPENED) | |
| 3708 | + fsnotify_open(file); | |
| 3703 | 3709 | if (error) |
| 3704 | 3710 | return error; |
| 3705 | 3711 | /* Don't check for other permissions, the inode was just created */ |
| @@ -523,6 +523,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr · 522 unmodified lines | ||
| 523 | 523 | struct netfs_group *group; |
| 524 | 524 | struct folio *folio = page_folio(vmf->page); |
| 525 | 525 | struct file *file = vmf->vma->vm_file; |
| 526 | + struct address_space *mapping = file->f_mapping; | |
| 526 | 527 | struct inode *inode = file_inode(file); |
| 527 | 528 | struct netfs_inode *ictx = netfs_inode(inode); |
| 528 | 529 | vm_fault_t ret = VM_FAULT_RETRY; |
| @@ -534,6 +535,11 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr · 5 unmodified lines | ||
| 534 | 535 | |
| 535 | 536 | if (folio_lock_killable(folio) < 0) |
| 536 | 537 | goto out; |
| 538 | + if (folio->mapping != mapping) { | |
| 539 | + folio_unlock(folio); | |
| 540 | + ret = VM_FAULT_NOPAGE; | |
| 541 | + goto out; | |
| 542 | + } | |
| 537 | 543 | |
| 538 | 544 | if (folio_wait_writeback_killable(folio)) { |
| 539 | 545 | ret = VM_FAULT_LOCKED; |
| @@ -549,9 +555,9 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr · 9 unmodified lines | ||
| 549 | 555 | group = netfs_folio_group(folio); |
| 550 | 556 | if (group != netfs_group && group != NETFS_FOLIO_COPY_TO_CACHE) { |
| 551 | 557 | folio_unlock(folio); |
| 552 | − err = filemap_fdatawait_range(inode->i_mapping, | |
| 553 | − folio_pos(folio), | |
| 554 | − folio_pos(folio) + folio_size(folio)); | |
| 558 | + err = filemap_fdatawrite_range(mapping, | |
| 559 | + folio_pos(folio), | |
| 560 | + folio_pos(folio) + folio_size(folio)); | |
| 555 | 561 | switch (err) { |
| 556 | 562 | case 0: |
| 557 | 563 | ret = VM_FAULT_RETRY; |
| @@ -92,8 +92,9 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter * · 91 unmodified lines | ||
| 92 | 92 | __set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags); |
| 93 | 93 | if (async) |
| 94 | 94 | wreq->iocb = iocb; |
| 95 | + wreq->len = iov_iter_count(&wreq->io_iter); | |
| 95 | 96 | wreq->cleanup = netfs_cleanup_dio_write; |
| 96 | − ret = netfs_unbuffered_write(wreq, is_sync_kiocb(iocb), iov_iter_count(&wreq->io_iter)); | |
| 97 | + ret = netfs_unbuffered_write(wreq, is_sync_kiocb(iocb), wreq->len); | |
| 97 | 98 | if (ret < 0) { |
| 98 | 99 | _debug("begin = %zd", ret); |
| 99 | 100 | goto out; |
| @@ -63,15 +63,6 @@ static inline void netfs_proc_del_rreq(struct netfs_io_request *rreq) {} · 62 unmodified lines | ||
| 63 | 63 | /* |
| 64 | 64 | * misc.c |
| 65 | 65 | */ |
| 66 | −#define NETFS_FLAG_PUT_MARK BIT(0) | |
| 67 | −#define NETFS_FLAG_PAGECACHE_MARK BIT(1) | |
| 68 | −int netfs_xa_store_and_mark(struct xarray *xa, unsigned long index, | |
| 69 | − struct folio *folio, unsigned int flags, | |
| 70 | − gfp_t gfp_mask); | |
| 71 | −int netfs_add_folios_to_buffer(struct xarray *buffer, | |
| 72 | − struct address_space *mapping, | |
| 73 | − pgoff_t index, pgoff_t to, gfp_t gfp_mask); | |
| 74 | −void netfs_clear_buffer(struct xarray *buffer); | |
| 75 | 66 | |
| 76 | 67 | /* |
| 77 | 68 | * objects.c |
| @@ -8,87 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/swap.h> |
| 9 | 9 | #include "internal.h" |
| 10 | 10 | |
| 11 | −/* | |
| 12 | − * Attach a folio to the buffer and maybe set marks on it to say that we need | |
| 13 | − * to put the folio later and twiddle the pagecache flags. | |
| 14 | − */ | |
| 15 | −int netfs_xa_store_and_mark(struct xarray *xa, unsigned long index, | |
| 16 | − struct folio *folio, unsigned int flags, | |
| 17 | − gfp_t gfp_mask) | |
| 18 | −{ | |
| 19 | − XA_STATE_ORDER(xas, xa, index, folio_order(folio)); | |
| 20 | − | |
| 21 | −retry: | |
| 22 | − xas_lock(&xas); | |
| 23 | − for (;;) { | |
| 24 | − xas_store(&xas, folio); | |
| 25 | − if (!xas_error(&xas)) | |
| 26 | − break; | |
| 27 | − xas_unlock(&xas); | |
| 28 | − if (!xas_nomem(&xas, gfp_mask)) | |
| 29 | − return xas_error(&xas); | |
| 30 | − goto retry; | |
| 31 | − } | |
| 32 | − | |
| 33 | − if (flags & NETFS_FLAG_PUT_MARK) | |
| 34 | − xas_set_mark(&xas, NETFS_BUF_PUT_MARK); | |
| 35 | − if (flags & NETFS_FLAG_PAGECACHE_MARK) | |
| 36 | − xas_set_mark(&xas, NETFS_BUF_PAGECACHE_MARK); | |
| 37 | − xas_unlock(&xas); | |
| 38 | − return xas_error(&xas); | |
| 39 | −} | |
| 40 | − | |
| 41 | −/* | |
| 42 | − * Create the specified range of folios in the buffer attached to the read | |
| 43 | − * request. The folios are marked with NETFS_BUF_PUT_MARK so that we know that | |
| 44 | − * these need freeing later. | |
| 45 | − */ | |
| 46 | −int netfs_add_folios_to_buffer(struct xarray *buffer, | |
| 47 | − struct address_space *mapping, | |
| 48 | − pgoff_t index, pgoff_t to, gfp_t gfp_mask) | |
| 49 | −{ | |
| 50 | − struct folio *folio; | |
| 51 | − int ret; | |
| 52 | − | |
| 53 | − if (to + 1 == index) /* Page range is inclusive */ | |
| 54 | − return 0; | |
| 55 | − | |
| 56 | − do { | |
| 57 | − /* TODO: Figure out what order folio can be allocated here */ | |
| 58 | − folio = filemap_alloc_folio(readahead_gfp_mask(mapping), 0); | |
| 59 | − if (!folio) | |
| 60 | − return -ENOMEM; | |
| 61 | − folio->index = index; | |
| 62 | − ret = netfs_xa_store_and_mark(buffer, index, folio, | |
| 63 | − NETFS_FLAG_PUT_MARK, gfp_mask); | |
| 64 | − if (ret < 0) { | |
| 65 | − folio_put(folio); | |
| 66 | − return ret; | |
| 67 | − } | |
| 68 | − | |
| 69 | − index += folio_nr_pages(folio); | |
| 70 | − } while (index <= to && index != 0); | |
| 71 | − | |
| 72 | − return 0; | |
| 73 | −} | |
| 74 | − | |
| 75 | −/* | |
| 76 | − * Clear an xarray buffer, putting a ref on the folios that have | |
| 77 | − * NETFS_BUF_PUT_MARK set. | |
| 78 | − */ | |
| 79 | −void netfs_clear_buffer(struct xarray *buffer) | |
| 80 | −{ | |
| 81 | − struct folio *folio; | |
| 82 | − XA_STATE(xas, buffer, 0); | |
| 83 | − | |
| 84 | − rcu_read_lock(); | |
| 85 | − xas_for_each_marked(&xas, folio, ULONG_MAX, NETFS_BUF_PUT_MARK) { | |
| 86 | − folio_put(folio); | |
| 87 | − } | |
| 88 | − rcu_read_unlock(); | |
| 89 | − xa_destroy(buffer); | |
| 90 | −} | |
| 91 | − | |
| 92 | 11 | /** |
| 93 | 12 | * netfs_dirty_folio - Mark folio dirty and pin a cache object for writeback |
| 94 | 13 | * @mapping: The mapping the folio belongs to. |
| @@ -483,7 +483,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq, · 482 unmodified lines | ||
| 483 | 483 | if (!debug) |
| 484 | 484 | kdebug("R=%x: No submit", wreq->debug_id); |
| 485 | 485 | |
| 486 | − if (flen < fsize) | |
| 486 | + if (foff + flen < fsize) | |
| 487 | 487 | for (int s = 0; s < NR_IO_STREAMS; s++) |
| 488 | 488 | netfs_issue_write(wreq, &wreq->io_streams[s]); |
| 489 | 489 | |
| @@ -2169,6 +2169,8 @@ static __net_init int nfsd_net_init(struct net *net) · 2168 unmodified lines | ||
| 2169 | 2169 | nn->nfsd_svcstats.program = &nfsd_program; |
| 2170 | 2170 | nn->nfsd_versions = NULL; |
| 2171 | 2171 | nn->nfsd4_minorversions = NULL; |
| 2172 | + nn->nfsd_info.mutex = &nfsd_mutex; | |
| 2173 | + nn->nfsd_serv = NULL; | |
| 2172 | 2174 | nfsd4_init_leases_net(nn); |
| 2173 | 2175 | get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key)); |
| 2174 | 2176 | seqlock_init(&nn->writeverf_lock); |
| @@ -672,7 +672,6 @@ int nfsd_create_serv(struct net *net) · 671 unmodified lines | ||
| 672 | 672 | return error; |
| 673 | 673 | } |
| 674 | 674 | spin_lock(&nfsd_notifier_lock); |
| 675 | − nn->nfsd_info.mutex = &nfsd_mutex; | |
| 676 | 675 | nn->nfsd_serv = serv; |
| 677 | 676 | spin_unlock(&nfsd_notifier_lock); |
| 678 | 677 | |
| @@ -377,11 +377,12 @@ void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, · 376 unmodified lines | ||
| 377 | 377 | * @target: offset number of an entry in the group (start point) |
| 378 | 378 | * @bsize: size in bits |
| 379 | 379 | * @lock: spin lock protecting @bitmap |
| 380 | + * @wrap: whether to wrap around | |
| 380 | 381 | */ |
| 381 | 382 | static int nilfs_palloc_find_available_slot(unsigned char *bitmap, |
| 382 | 383 | unsigned long target, |
| 383 | 384 | unsigned int bsize, |
| 384 | − spinlock_t *lock) | |
| 385 | + spinlock_t *lock, bool wrap) | |
| 385 | 386 | { |
| 386 | 387 | int pos, end = bsize; |
| 387 | 388 | |
| @@ -397,6 +398,8 @@ static int nilfs_palloc_find_available_slot(unsigned char *bitmap, · 9 unmodified lines | ||
| 397 | 398 | |
| 398 | 399 | end = target; |
| 399 | 400 | } |
| 401 | + if (!wrap) | |
| 402 | + return -ENOSPC; | |
| 400 | 403 | |
| 401 | 404 | /* wrap around */ |
| 402 | 405 | for (pos = 0; pos < end; pos++) { |
| @@ -495,9 +498,10 @@ int nilfs_palloc_count_max_entries(struct inode *inode, u64 nused, u64 *nmaxp) · 92 unmodified lines | ||
| 495 | 498 | * nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object |
| 496 | 499 | * @inode: inode of metadata file using this allocator |
| 497 | 500 | * @req: nilfs_palloc_req structure exchanged for the allocation |
| 501 | + * @wrap: whether to wrap around | |
| 498 | 502 | */ |
| 499 | 503 | int nilfs_palloc_prepare_alloc_entry(struct inode *inode, |
| 500 | − struct nilfs_palloc_req *req) | |
| 504 | + struct nilfs_palloc_req *req, bool wrap) | |
| 501 | 505 | { |
| 502 | 506 | struct buffer_head *desc_bh, *bitmap_bh; |
| 503 | 507 | struct nilfs_palloc_group_desc *desc; |
| @@ -516,7 +520,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, · 12 unmodified lines | ||
| 516 | 520 | entries_per_group = nilfs_palloc_entries_per_group(inode); |
| 517 | 521 | |
| 518 | 522 | for (i = 0; i < ngroups; i += n) { |
| 519 | − if (group >= ngroups) { | |
| 523 | + if (group >= ngroups && wrap) { | |
| 520 | 524 | /* wrap around */ |
| 521 | 525 | group = 0; |
| 522 | 526 | maxgroup = nilfs_palloc_group(inode, req->pr_entry_nr, |
| @@ -550,7 +554,14 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, · 27 unmodified lines | ||
| 550 | 554 | bitmap_kaddr = kmap_local_page(bitmap_bh->b_page); |
| 551 | 555 | bitmap = bitmap_kaddr + bh_offset(bitmap_bh); |
| 552 | 556 | pos = nilfs_palloc_find_available_slot( |
| 553 | − bitmap, group_offset, entries_per_group, lock); | |
| 557 | + bitmap, group_offset, entries_per_group, lock, | |
| 558 | + wrap); | |
| 559 | + /* | |
| 560 | + * Since the search for a free slot in the second and | |
| 561 | + * subsequent bitmap blocks always starts from the | |
| 562 | + * beginning, the wrap flag only has an effect on the | |
| 563 | + * first search. | |
| 564 | + */ | |
| 554 | 565 | kunmap_local(bitmap_kaddr); |
| 555 | 566 | if (pos >= 0) |
| 556 | 567 | goto found; |
| @@ -50,8 +50,8 @@ struct nilfs_palloc_req { · 49 unmodified lines | ||
| 50 | 50 | struct buffer_head *pr_entry_bh; |
| 51 | 51 | }; |
| 52 | 52 | |
| 53 | −int nilfs_palloc_prepare_alloc_entry(struct inode *, | |
| 54 | − struct nilfs_palloc_req *); | |
| 53 | +int nilfs_palloc_prepare_alloc_entry(struct inode *inode, | |
| 54 | + struct nilfs_palloc_req *req, bool wrap); | |
| 55 | 55 | void nilfs_palloc_commit_alloc_entry(struct inode *, |
| 56 | 56 | struct nilfs_palloc_req *); |
| 57 | 57 | void nilfs_palloc_abort_alloc_entry(struct inode *, struct nilfs_palloc_req *); |
| @@ -75,7 +75,7 @@ int nilfs_dat_prepare_alloc(struct inode *dat, struct nilfs_palloc_req *req) · 74 unmodified lines | ||
| 75 | 75 | { |
| 76 | 76 | int ret; |
| 77 | 77 | |
| 78 | − ret = nilfs_palloc_prepare_alloc_entry(dat, req); | |
| 78 | + ret = nilfs_palloc_prepare_alloc_entry(dat, req, true); | |
| 79 | 79 | if (ret < 0) |
| 80 | 80 | return ret; |
| 81 | 81 | |
| @@ -135,6 +135,9 @@ static bool nilfs_check_folio(struct folio *folio, char *kaddr) · 134 unmodified lines | ||
| 135 | 135 | goto Enamelen; |
| 136 | 136 | if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1)) |
| 137 | 137 | goto Espan; |
| 138 | + if (unlikely(p->inode && | |
| 139 | + NILFS_PRIVATE_INODE(le64_to_cpu(p->inode)))) | |
| 140 | + goto Einumber; | |
| 138 | 141 | } |
| 139 | 142 | if (offs != limit) |
| 140 | 143 | goto Eend; |
| @@ -160,6 +163,9 @@ Enamelen: · 19 unmodified lines | ||
| 160 | 163 | goto bad_entry; |
| 161 | 164 | Espan: |
| 162 | 165 | error = "directory entry across blocks"; |
| 166 | + goto bad_entry; | |
| 167 | +Einumber: | |
| 168 | + error = "disallowed inode number"; | |
| 163 | 169 | bad_entry: |
| 164 | 170 | nilfs_error(sb, |
| 165 | 171 | "bad entry in directory #%lu: %s - offset=%lu, inode=%lu, rec_len=%zd, name_len=%d", |
| @@ -56,13 +56,10 @@ int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino, · 55 unmodified lines | ||
| 56 | 56 | struct nilfs_palloc_req req; |
| 57 | 57 | int ret; |
| 58 | 58 | |
| 59 | − req.pr_entry_nr = 0; /* | |
| 60 | − * 0 says find free inode from beginning | |
| 61 | − * of a group. dull code!! | |
| 62 | − */ | |
| 59 | + req.pr_entry_nr = NILFS_FIRST_INO(ifile->i_sb); | |
| 63 | 60 | req.pr_entry_bh = NULL; |
| 64 | 61 | |
| 65 | − ret = nilfs_palloc_prepare_alloc_entry(ifile, &req); | |
| 62 | + ret = nilfs_palloc_prepare_alloc_entry(ifile, &req, false); | |
| 66 | 63 | if (!ret) { |
| 67 | 64 | ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1, |
| 68 | 65 | &req.pr_entry_bh); |
| @@ -116,9 +116,15 @@ enum { · 115 unmodified lines | ||
| 116 | 116 | #define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino) |
| 117 | 117 | |
| 118 | 118 | #define NILFS_MDT_INODE(sb, ino) \ |
| 119 | − ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & BIT(ino))) | |
| 119 | + ((ino) < NILFS_USER_INO && (NILFS_MDT_INO_BITS & BIT(ino))) | |
| 120 | 120 | #define NILFS_VALID_INODE(sb, ino) \ |
| 121 | − ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & BIT(ino))) | |
| 121 | + ((ino) >= NILFS_FIRST_INO(sb) || \ | |
| 122 | + ((ino) < NILFS_USER_INO && (NILFS_SYS_INO_BITS & BIT(ino)))) | |
| 123 | + | |
| 124 | +#define NILFS_PRIVATE_INODE(ino) ({ \ | |
| 125 | + ino_t __ino = (ino); \ | |
| 126 | + ((__ino) < NILFS_USER_INO && (__ino) != NILFS_ROOT_INO && \ | |
| 127 | + (__ino) != NILFS_SKETCH_INO); }) | |
| 122 | 128 | |
| 123 | 129 | /** |
| 124 | 130 | * struct nilfs_transaction_info: context information for synchronization |
| @@ -452,6 +452,12 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs, · 451 unmodified lines | ||
| 452 | 452 | } |
| 453 | 453 | |
| 454 | 454 | nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino); |
| 455 | + if (nilfs->ns_first_ino < NILFS_USER_INO) { | |
| 456 | + nilfs_err(nilfs->ns_sb, | |
| 457 | + "too small lower limit for non-reserved inode numbers: %u", | |
| 458 | + nilfs->ns_first_ino); | |
| 459 | + return -EINVAL; | |
| 460 | + } | |
| 455 | 461 | |
| 456 | 462 | nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment); |
| 457 | 463 | if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) { |
| @@ -182,7 +182,7 @@ struct the_nilfs { · 181 unmodified lines | ||
| 182 | 182 | unsigned long ns_nrsvsegs; |
| 183 | 183 | unsigned long ns_first_data_block; |
| 184 | 184 | int ns_inode_size; |
| 185 | − int ns_first_ino; | |
| 185 | + unsigned int ns_first_ino; | |
| 186 | 186 | u32 ns_crc_seed; |
| 187 | 187 | |
| 188 | 188 | /* /sys/fs/<nilfs>/<device> */ |
| @@ -202,13 +202,13 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) · 201 unmodified lines | ||
| 202 | 202 | return error; |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | −SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) | |
| 205 | +SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length) | |
| 206 | 206 | { |
| 207 | 207 | return do_sys_ftruncate(fd, length, 1); |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | 210 | #ifdef CONFIG_COMPAT |
| 211 | −COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length) | |
| 211 | +COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length) | |
| 212 | 212 | { |
| 213 | 213 | return do_sys_ftruncate(fd, length, 1); |
| 214 | 214 | } |
| @@ -1004,11 +1004,6 @@ static int do_dentry_open(struct file *f, · 789 unmodified lines | ||
| 1004 | 1004 | } |
| 1005 | 1005 | } |
| 1006 | 1006 | |
| 1007 | − /* | |
| 1008 | − * Once we return a file with FMODE_OPENED, __fput() will call | |
| 1009 | − * fsnotify_close(), so we need fsnotify_open() here for symmetry. | |
| 1010 | − */ | |
| 1011 | − fsnotify_open(f); | |
| 1012 | 1007 | return 0; |
| 1013 | 1008 | |
| 1014 | 1009 | cleanup_all: |
| @@ -1085,8 +1080,19 @@ EXPORT_SYMBOL(file_path); · 70 unmodified lines | ||
| 1085 | 1080 | */ |
| 1086 | 1081 | int vfs_open(const struct path *path, struct file *file) |
| 1087 | 1082 | { |
| 1083 | + int ret; | |
| 1084 | + | |
| 1088 | 1085 | file->f_path = *path; |
| 1089 | − return do_dentry_open(file, NULL); | |
| 1086 | + ret = do_dentry_open(file, NULL); | |
| 1087 | + if (!ret) { | |
| 1088 | + /* | |
| 1089 | + * Once we return a file with FMODE_OPENED, __fput() will call | |
| 1090 | + * fsnotify_close(), so we need fsnotify_open() here for | |
| 1091 | + * symmetry. | |
| 1092 | + */ | |
| 1093 | + fsnotify_open(file); | |
| 1094 | + } | |
| 1095 | + return ret; | |
| 1090 | 1096 | } |
| 1091 | 1097 | |
| 1092 | 1098 | struct file *dentry_open(const struct path *path, int flags, |
| @@ -1177,8 +1183,10 @@ struct file *kernel_file_open(const struct path *path, int flags, · 84 unmodified lines | ||
| 1177 | 1183 | error = do_dentry_open(f, NULL); |
| 1178 | 1184 | if (error) { |
| 1179 | 1185 | fput(f); |
| 1180 | − f = ERR_PTR(error); | |
| 1186 | + return ERR_PTR(error); | |
| 1181 | 1187 | } |
| 1188 | + | |
| 1189 | + fsnotify_open(f); | |
| 1182 | 1190 | return f; |
| 1183 | 1191 | } |
| 1184 | 1192 | EXPORT_SYMBOL_GPL(kernel_file_open); |
| @@ -1502,8 +1502,17 @@ static int fs_bdev_thaw(struct block_device *bdev) · 1501 unmodified lines | ||
| 1502 | 1502 | |
| 1503 | 1503 | lockdep_assert_held(&bdev->bd_fsfreeze_mutex); |
| 1504 | 1504 | |
| 1505 | + /* | |
| 1506 | + * The block device may have been frozen before it was claimed by a | |
| 1507 | + * filesystem. Concurrently another process might try to mount that | |
| 1508 | + * frozen block device and has temporarily claimed the block device for | |
| 1509 | + * that purpose causing a concurrent fs_bdev_thaw() to end up here. The | |
| 1510 | + * mounter is already about to abort mounting because they still saw an | |
| 1511 | + * elevanted bdev->bd_fsfreeze_count so get_bdev_super() will return | |
| 1512 | + * NULL in that case. | |
| 1513 | + */ | |
| 1505 | 1514 | sb = get_bdev_super(bdev); |
| 1506 | − if (WARN_ON_ONCE(!sb)) | |
| 1515 | + if (!sb) | |
| 1507 | 1516 | return -EINVAL; |
| 1508 | 1517 | |
| 1509 | 1518 | if (sb->s_op->thaw_super) |
| @@ -4058,20 +4058,32 @@ xfs_bmapi_reserve_delalloc( · 4057 unmodified lines | ||
| 4058 | 4058 | xfs_extlen_t indlen; |
| 4059 | 4059 | uint64_t fdblocks; |
| 4060 | 4060 | int error; |
| 4061 | − xfs_fileoff_t aoff = off; | |
| 4061 | + xfs_fileoff_t aoff; | |
| 4062 | + bool use_cowextszhint = | |
| 4063 | + whichfork == XFS_COW_FORK && !prealloc; | |
| 4062 | 4064 | |
| 4065 | +retry: | |
| 4063 | 4066 | /* |
| 4064 | 4067 | * Cap the alloc length. Keep track of prealloc so we know whether to |
| 4065 | 4068 | * tag the inode before we return. |
| 4066 | 4069 | */ |
| 4070 | + aoff = off; | |
| 4067 | 4071 | alen = XFS_FILBLKS_MIN(len + prealloc, XFS_MAX_BMBT_EXTLEN); |
| 4068 | 4072 | if (!eof) |
| 4069 | 4073 | alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff); |
| 4070 | 4074 | if (prealloc && alen >= len) |
| 4071 | 4075 | prealloc = alen - len; |
| 4072 | 4076 | |
| 4073 | − /* Figure out the extent size, adjust alen */ | |
| 4074 | − if (whichfork == XFS_COW_FORK) { | |
| 4077 | + /* | |
| 4078 | + * If we're targetting the COW fork but aren't creating a speculative | |
| 4079 | + * posteof preallocation, try to expand the reservation to align with | |
| 4080 | + * the COW extent size hint if there's sufficient free space. | |
| 4081 | + * | |
| 4082 | + * Unlike the data fork, the CoW cancellation functions will free all | |
| 4083 | + * the reservations at inactivation, so we don't require that every | |
| 4084 | + * delalloc reservation have a dirty pagecache. | |
| 4085 | + */ | |
| 4086 | + if (use_cowextszhint) { | |
| 4075 | 4087 | struct xfs_bmbt_irec prev; |
| 4076 | 4088 | xfs_extlen_t extsz = xfs_get_cowextsz_hint(ip); |
| 4077 | 4089 | |
| @@ -4090,7 +4102,7 @@ xfs_bmapi_reserve_delalloc( · 12 unmodified lines | ||
| 4090 | 4102 | */ |
| 4091 | 4103 | error = xfs_quota_reserve_blkres(ip, alen); |
| 4092 | 4104 | if (error) |
| 4093 | − return error; | |
| 4105 | + goto out; | |
| 4094 | 4106 | |
| 4095 | 4107 | /* |
| 4096 | 4108 | * Split changing sb for alen and indlen since they could be coming |
| @@ -4140,6 +4152,17 @@ out_unreserve_frextents: · 43 unmodified lines | ||
| 4140 | 4152 | out_unreserve_quota: |
| 4141 | 4153 | if (XFS_IS_QUOTA_ON(mp)) |
| 4142 | 4154 | xfs_quota_unreserve_blkres(ip, alen); |
| 4155 | +out: | |
| 4156 | + if (error == -ENOSPC || error == -EDQUOT) { | |
| 4157 | + trace_xfs_delalloc_enospc(ip, off, len); | |
| 4158 | + | |
| 4159 | + if (prealloc || use_cowextszhint) { | |
| 4160 | + /* retry without any preallocation */ | |
| 4161 | + use_cowextszhint = false; | |
| 4162 | + prealloc = 0; | |
| 4163 | + goto retry; | |
| 4164 | + } | |
| 4165 | + } | |
| 4143 | 4166 | return error; |
| 4144 | 4167 | } |
| 4145 | 4168 | |
| @@ -996,7 +996,7 @@ struct xfs_getparents_by_handle { · 995 unmodified lines | ||
| 996 | 996 | #define XFS_IOC_FSGEOMETRY _IOR ('X', 126, struct xfs_fsop_geom) |
| 997 | 997 | #define XFS_IOC_BULKSTAT _IOR ('X', 127, struct xfs_bulkstat_req) |
| 998 | 998 | #define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req) |
| 999 | −#define XFS_IOC_EXCHANGE_RANGE _IOWR('X', 129, struct xfs_exchange_range) | |
| 999 | +#define XFS_IOC_EXCHANGE_RANGE _IOW ('X', 129, struct xfs_exchange_range) | |
| 1000 | 1000 | /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ |
| 1001 | 1001 | |
| 1002 | 1002 | |
| @@ -379,10 +379,13 @@ xfs_dinode_verify_fork( · 378 unmodified lines | ||
| 379 | 379 | /* |
| 380 | 380 | * A directory small enough to fit in the inode must be stored |
| 381 | 381 | * in local format. The directory sf <-> extents conversion |
| 382 | − * code updates the directory size accordingly. | |
| 382 | + * code updates the directory size accordingly. Directories | |
| 383 | + * being truncated have zero size and are not subject to this | |
| 384 | + * check. | |
| 383 | 385 | */ |
| 384 | 386 | if (S_ISDIR(mode)) { |
| 385 | − if (be64_to_cpu(dip->di_size) <= fork_size && | |
| 387 | + if (dip->di_size && | |
| 388 | + be64_to_cpu(dip->di_size) <= fork_size && | |
| 386 | 389 | fork_format != XFS_DINODE_FMT_LOCAL) |
| 387 | 390 | return __this_address; |
| 388 | 391 | } |
| @@ -528,9 +531,19 @@ xfs_dinode_verify( · 139 unmodified lines | ||
| 528 | 531 | if (mode && xfs_mode_to_ftype(mode) == XFS_DIR3_FT_UNKNOWN) |
| 529 | 532 | return __this_address; |
| 530 | 533 | |
| 531 | − /* No zero-length symlinks/dirs. */ | |
| 532 | − if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0) | |
| 533 | − return __this_address; | |
| 534 | + /* | |
| 535 | + * No zero-length symlinks/dirs unless they're unlinked and hence being | |
| 536 | + * inactivated. | |
| 537 | + */ | |
| 538 | + if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0) { | |
| 539 | + if (dip->di_version > 1) { | |
| 540 | + if (dip->di_nlink) | |
| 541 | + return __this_address; | |
| 542 | + } else { | |
| 543 | + if (dip->di_onlink) | |
| 544 | + return __this_address; | |
| 545 | + } | |
| 546 | + } | |
| 534 | 547 | |
| 535 | 548 | fa = xfs_dinode_verify_nrext64(mp, dip); |
| 536 | 549 | if (fa) |
| @@ -486,13 +486,11 @@ out_unlock: · 485 unmodified lines | ||
| 486 | 486 | |
| 487 | 487 | /* |
| 488 | 488 | * Test whether it is appropriate to check an inode for and free post EOF |
| 489 | − * blocks. The 'force' parameter determines whether we should also consider | |
| 490 | − * regular files that are marked preallocated or append-only. | |
| 489 | + * blocks. | |
| 491 | 490 | */ |
| 492 | 491 | bool |
| 493 | 492 | xfs_can_free_eofblocks( |
| 494 | − struct xfs_inode *ip, | |
| 495 | − bool force) | |
| 493 | + struct xfs_inode *ip) | |
| 496 | 494 | { |
| 497 | 495 | struct xfs_bmbt_irec imap; |
| 498 | 496 | struct xfs_mount *mp = ip->i_mount; |
| @@ -526,11 +524,11 @@ xfs_can_free_eofblocks( · 27 unmodified lines | ||
| 526 | 524 | return false; |
| 527 | 525 | |
| 528 | 526 | /* |
| 529 | − * Do not free real preallocated or append-only files unless the file | |
| 530 | − * has delalloc blocks and we are forced to remove them. | |
| 527 | + * Only free real extents for inodes with persistent preallocations or | |
| 528 | + * the append-only flag. | |
| 531 | 529 | */ |
| 532 | 530 | if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) |
| 533 | − if (!force || ip->i_delayed_blks == 0) | |
| 531 | + if (ip->i_delayed_blks == 0) | |
| 534 | 532 | return false; |
| 535 | 533 | |
| 536 | 534 | /* |
| @@ -584,6 +582,22 @@ xfs_free_eofblocks( · 47 unmodified lines | ||
| 584 | 582 | /* Wait on dio to ensure i_size has settled. */ |
| 585 | 583 | inode_dio_wait(VFS_I(ip)); |
| 586 | 584 | |
| 585 | + /* | |
| 586 | + * For preallocated files only free delayed allocations. | |
| 587 | + * | |
| 588 | + * Note that this means we also leave speculative preallocations in | |
| 589 | + * place for preallocated files. | |
| 590 | + */ | |
| 591 | + if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) { | |
| 592 | + if (ip->i_delayed_blks) { | |
| 593 | + xfs_bmap_punch_delalloc_range(ip, | |
| 594 | + round_up(XFS_ISIZE(ip), mp->m_sb.sb_blocksize), | |
| 595 | + LLONG_MAX); | |
| 596 | + } | |
| 597 | + xfs_inode_clear_eofblocks_tag(ip); | |
| 598 | + return 0; | |
| 599 | + } | |
| 600 | + | |
| 587 | 601 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); |
| 588 | 602 | if (error) { |
| 589 | 603 | ASSERT(xfs_is_shutdown(mp)); |
| @@ -891,7 +905,7 @@ xfs_prepare_shift( · 301 unmodified lines | ||
| 891 | 905 | * Trim eofblocks to avoid shifting uninitialized post-eof preallocation |
| 892 | 906 | * into the accessible region of the file. |
| 893 | 907 | */ |
| 894 | − if (xfs_can_free_eofblocks(ip, true)) { | |
| 908 | + if (xfs_can_free_eofblocks(ip)) { | |
| 895 | 909 | error = xfs_free_eofblocks(ip); |
| 896 | 910 | if (error) |
| 897 | 911 | return error; |
| @@ -63,7 +63,7 @@ int xfs_insert_file_space(struct xfs_inode *, xfs_off_t offset, · 62 unmodified lines | ||
| 63 | 63 | xfs_off_t len); |
| 64 | 64 | |
| 65 | 65 | /* EOF block manipulation functions */ |
| 66 | −bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force); | |
| 66 | +bool xfs_can_free_eofblocks(struct xfs_inode *ip); | |
| 67 | 67 | int xfs_free_eofblocks(struct xfs_inode *ip); |
| 68 | 68 | |
| 69 | 69 | int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, |
| @@ -1155,7 +1155,7 @@ xfs_inode_free_eofblocks( · 1154 unmodified lines | ||
| 1155 | 1155 | } |
| 1156 | 1156 | *lockflags |= XFS_IOLOCK_EXCL; |
| 1157 | 1157 | |
| 1158 | − if (xfs_can_free_eofblocks(ip, false)) | |
| 1158 | + if (xfs_can_free_eofblocks(ip)) | |
| 1159 | 1159 | return xfs_free_eofblocks(ip); |
| 1160 | 1160 | |
| 1161 | 1161 | /* inode could be preallocated or append-only */ |
| @@ -42,6 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #include "xfs_pnfs.h" |
| 43 | 43 | #include "xfs_parent.h" |
| 44 | 44 | #include "xfs_xattr.h" |
| 45 | +#include "xfs_sb.h" | |
| 45 | 46 | |
| 46 | 47 | struct kmem_cache *xfs_inode_cache; |
| 47 | 48 | |
| @@ -870,9 +871,16 @@ xfs_init_new_inode( · 822 unmodified lines | ||
| 870 | 871 | * this saves us from needing to run a separate transaction to set the |
| 871 | 872 | * fork offset in the immediate future. |
| 872 | 873 | */ |
| 873 | − if (init_xattrs && xfs_has_attr(mp)) { | |
| 874 | + if (init_xattrs) { | |
| 874 | 875 | ip->i_forkoff = xfs_default_attroffset(ip) >> 3; |
| 875 | 876 | xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0); |
| 877 | + | |
| 878 | + if (!xfs_has_attr(mp)) { | |
| 879 | + spin_lock(&mp->m_sb_lock); | |
| 880 | + xfs_add_attr(mp); | |
| 881 | + spin_unlock(&mp->m_sb_lock); | |
| 882 | + xfs_log_sb(tp); | |
| 883 | + } | |
| 876 | 884 | } |
| 877 | 885 | |
| 878 | 886 | /* |
| @@ -1595,7 +1603,7 @@ xfs_release( · 716 unmodified lines | ||
| 1595 | 1603 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) |
| 1596 | 1604 | return 0; |
| 1597 | 1605 | |
| 1598 | − if (xfs_can_free_eofblocks(ip, false)) { | |
| 1606 | + if (xfs_can_free_eofblocks(ip)) { | |
| 1599 | 1607 | /* |
| 1600 | 1608 | * Check if the inode is being opened, written and closed |
| 1601 | 1609 | * frequently and we have delayed allocation blocks outstanding |
| @@ -1856,15 +1864,13 @@ xfs_inode_needs_inactive( · 254 unmodified lines | ||
| 1856 | 1864 | |
| 1857 | 1865 | /* |
| 1858 | 1866 | * This file isn't being freed, so check if there are post-eof blocks |
| 1859 | − * to free. @force is true because we are evicting an inode from the | |
| 1860 | − * cache. Post-eof blocks must be freed, lest we end up with broken | |
| 1861 | − * free space accounting. | |
| 1867 | + * to free. | |
| 1862 | 1868 | * |
| 1863 | 1869 | * Note: don't bother with iolock here since lockdep complains about |
| 1864 | 1870 | * acquiring it in reclaim context. We have the only reference to the |
| 1865 | 1871 | * inode at this point anyways. |
| 1866 | 1872 | */ |
| 1867 | − return xfs_can_free_eofblocks(ip, true); | |
| 1873 | + return xfs_can_free_eofblocks(ip); | |
| 1868 | 1874 | } |
| 1869 | 1875 | |
| 1870 | 1876 | /* |
| @@ -1947,15 +1953,11 @@ xfs_inactive( · 76 unmodified lines | ||
| 1947 | 1953 | |
| 1948 | 1954 | if (VFS_I(ip)->i_nlink != 0) { |
| 1949 | 1955 | /* |
| 1950 | − * force is true because we are evicting an inode from the | |
| 1951 | − * cache. Post-eof blocks must be freed, lest we end up with | |
| 1952 | − * broken free space accounting. | |
| 1953 | − * | |
| 1954 | 1956 | * Note: don't bother with iolock here since lockdep complains |
| 1955 | 1957 | * about acquiring it in reclaim context. We have the only |
| 1956 | 1958 | * reference to the inode at this point anyways. |
| 1957 | 1959 | */ |
| 1958 | − if (xfs_can_free_eofblocks(ip, true)) | |
| 1960 | + if (xfs_can_free_eofblocks(ip)) | |
| 1959 | 1961 | error = xfs_free_eofblocks(ip); |
| 1960 | 1962 | |
| 1961 | 1963 | goto out; |
| @@ -1148,33 +1148,23 @@ xfs_buffered_write_iomap_begin( · 1147 unmodified lines | ||
| 1148 | 1148 | } |
| 1149 | 1149 | } |
| 1150 | 1150 | |
| 1151 | −retry: | |
| 1152 | − error = xfs_bmapi_reserve_delalloc(ip, allocfork, offset_fsb, | |
| 1153 | − end_fsb - offset_fsb, prealloc_blocks, | |
| 1154 | − allocfork == XFS_DATA_FORK ? &imap : &cmap, | |
| 1155 | − allocfork == XFS_DATA_FORK ? &icur : &ccur, | |
| 1156 | − allocfork == XFS_DATA_FORK ? eof : cow_eof); | |
| 1157 | − switch (error) { | |
| 1158 | − case 0: | |
| 1159 | − break; | |
| 1160 | − case -ENOSPC: | |
| 1161 | − case -EDQUOT: | |
| 1162 | − /* retry without any preallocation */ | |
| 1163 | − trace_xfs_delalloc_enospc(ip, offset, count); | |
| 1164 | − if (prealloc_blocks) { | |
| 1165 | − prealloc_blocks = 0; | |
| 1166 | − goto retry; | |
| 1167 | − } | |
| 1168 | − fallthrough; | |
| 1169 | − default: | |
| 1170 | − goto out_unlock; | |
| 1171 | − } | |
| 1172 | − | |
| 1173 | 1151 | if (allocfork == XFS_COW_FORK) { |
| 1152 | + error = xfs_bmapi_reserve_delalloc(ip, allocfork, offset_fsb, | |
| 1153 | + end_fsb - offset_fsb, prealloc_blocks, &cmap, | |
| 1154 | + &ccur, cow_eof); | |
| 1155 | + if (error) | |
| 1156 | + goto out_unlock; | |
| 1157 | + | |
| 1174 | 1158 | trace_xfs_iomap_alloc(ip, offset, count, allocfork, &cmap); |
| 1175 | 1159 | goto found_cow; |
| 1176 | 1160 | } |
| 1177 | 1161 | |
| 1162 | + error = xfs_bmapi_reserve_delalloc(ip, allocfork, offset_fsb, | |
| 1163 | + end_fsb - offset_fsb, prealloc_blocks, &imap, &icur, | |
| 1164 | + eof); | |
| 1165 | + if (error) | |
| 1166 | + goto out_unlock; | |
| 1167 | + | |
| 1178 | 1168 | /* |
| 1179 | 1169 | * Flag newly allocated delalloc blocks with IOMAP_F_NEW so we punch |
| 1180 | 1170 | * them out if the write happens to fail. |
| @@ -19,7 +19,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, · 18 unmodified lines | ||
| 19 | 19 | #ifndef sys_mmap |
| 20 | 20 | asmlinkage long sys_mmap(unsigned long addr, unsigned long len, |
| 21 | 21 | unsigned long prot, unsigned long flags, |
| 22 | − unsigned long fd, off_t pgoff); | |
| 22 | + unsigned long fd, unsigned long off); | |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | 25 | #ifndef sys_rt_sigreturn |
| @@ -284,6 +284,21 @@ static inline void closure_get(struct closure *cl) · 283 unmodified lines | ||
| 284 | 284 | #endif |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | +/** | |
| 288 | + * closure_get_not_zero | |
| 289 | + */ | |
| 290 | +static inline bool closure_get_not_zero(struct closure *cl) | |
| 291 | +{ | |
| 292 | + unsigned old = atomic_read(&cl->remaining); | |
| 293 | + do { | |
| 294 | + if (!(old & CLOSURE_REMAINING_MASK)) | |
| 295 | + return false; | |
| 296 | + | |
| 297 | + } while (!atomic_try_cmpxchg_acquire(&cl->remaining, &old, old + 1)); | |
| 298 | + | |
| 299 | + return true; | |
| 300 | +} | |
| 301 | + | |
| 287 | 302 | /** |
| 288 | 303 | * closure_init - Initialize a closure, setting the refcount to 1 |
| 289 | 304 | * @cl: closure to initialize |
| @@ -310,6 +325,12 @@ static inline void closure_init_stack(struct closure *cl) · 20 unmodified lines | ||
| 310 | 325 | atomic_set(&cl->remaining, CLOSURE_REMAINING_INITIALIZER); |
| 311 | 326 | } |
| 312 | 327 | |
| 328 | +static inline void closure_init_stack_release(struct closure *cl) | |
| 329 | +{ | |
| 330 | + memset(cl, 0, sizeof(struct closure)); | |
| 331 | + atomic_set_release(&cl->remaining, CLOSURE_REMAINING_INITIALIZER); | |
| 332 | +} | |
| 333 | + | |
| 313 | 334 | /** |
| 314 | 335 | * closure_wake_up - wake up all closures on a wait list, |
| 315 | 336 | * with memory barrier |
| @@ -355,6 +376,8 @@ do { \ · 39 unmodified lines | ||
| 355 | 376 | */ |
| 356 | 377 | #define closure_return(_cl) continue_at((_cl), NULL, NULL) |
| 357 | 378 | |
| 379 | +void closure_return_sync(struct closure *cl); | |
| 380 | + | |
| 358 | 381 | /** |
| 359 | 382 | * continue_at_nobarrier - jump to another function without barrier |
| 360 | 383 | * |
| @@ -608,7 +608,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, · 607 unmodified lines | ||
| 608 | 608 | asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, |
| 609 | 609 | struct compat_statfs64 __user *buf); |
| 610 | 610 | asmlinkage long compat_sys_truncate(const char __user *, compat_off_t); |
| 611 | −asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t); | |
| 611 | +asmlinkage long compat_sys_ftruncate(unsigned int, compat_off_t); | |
| 612 | 612 | /* No generic prototype for truncate64, ftruncate64, fallocate */ |
| 613 | 613 | asmlinkage long compat_sys_openat(int dfd, const char __user *filename, |
| 614 | 614 | int flags, umode_t mode); |
| @@ -1313,18 +1313,18 @@ static inline bool bpf_jit_kallsyms_enabled(void) · 1312 unmodified lines | ||
| 1313 | 1313 | return false; |
| 1314 | 1314 | } |
| 1315 | 1315 | |
| 1316 | −const char *__bpf_address_lookup(unsigned long addr, unsigned long *size, | |
| 1316 | +int __bpf_address_lookup(unsigned long addr, unsigned long *size, | |
| 1317 | 1317 | unsigned long *off, char *sym); |
| 1318 | 1318 | bool is_bpf_text_address(unsigned long addr); |
| 1319 | 1319 | int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type, |
| 1320 | 1320 | char *sym); |
| 1321 | 1321 | struct bpf_prog *bpf_prog_ksym_find(unsigned long addr); |
| 1322 | 1322 | |
| 1323 | −static inline const char * | |
| 1323 | +static inline int | |
| 1324 | 1324 | bpf_address_lookup(unsigned long addr, unsigned long *size, |
| 1325 | 1325 | unsigned long *off, char **modname, char *sym) |
| 1326 | 1326 | { |
| 1327 | − const char *ret = __bpf_address_lookup(addr, size, off, sym); | |
| 1327 | + int ret = __bpf_address_lookup(addr, size, off, sym); | |
| 1328 | 1328 | |
| 1329 | 1329 | if (ret && modname) |
| 1330 | 1330 | *modname = NULL; |
| @@ -1368,11 +1368,11 @@ static inline bool bpf_jit_kallsyms_enabled(void) · 37 unmodified lines | ||
| 1368 | 1368 | return false; |
| 1369 | 1369 | } |
| 1370 | 1370 | |
| 1371 | −static inline const char * | |
| 1371 | +static inline int | |
| 1372 | 1372 | __bpf_address_lookup(unsigned long addr, unsigned long *size, |
| 1373 | 1373 | unsigned long *off, char *sym) |
| 1374 | 1374 | { |
| 1375 | − return NULL; | |
| 1375 | + return 0; | |
| 1376 | 1376 | } |
| 1377 | 1377 | |
| 1378 | 1378 | static inline bool is_bpf_text_address(unsigned long addr) |
| @@ -1391,11 +1391,11 @@ static inline struct bpf_prog *bpf_prog_ksym_find(unsigned long addr) · 12 unmodified lines | ||
| 1391 | 1391 | return NULL; |
| 1392 | 1392 | } |
| 1393 | 1393 | |
| 1394 | −static inline const char * | |
| 1394 | +static inline int | |
| 1395 | 1395 | bpf_address_lookup(unsigned long addr, unsigned long *size, |
| 1396 | 1396 | unsigned long *off, char **modname, char *sym) |
| 1397 | 1397 | { |
| 1398 | − return NULL; | |
| 1398 | + return 0; | |
| 1399 | 1399 | } |
| 1400 | 1400 | |
| 1401 | 1401 | static inline void bpf_prog_kallsyms_add(struct bpf_prog *fp) |
| @@ -112,7 +112,13 @@ static inline int fsnotify_file(struct file *file, __u32 mask) · 111 unmodified lines | ||
| 112 | 112 | { |
| 113 | 113 | const struct path *path; |
| 114 | 114 | |
| 115 | − if (file->f_mode & FMODE_NONOTIFY) | |
| 115 | + /* | |
| 116 | + * FMODE_NONOTIFY are fds generated by fanotify itself which should not | |
| 117 | + * generate new events. We also don't want to generate events for | |
| 118 | + * FMODE_PATH fds (involves open & close events) as they are just | |
| 119 | + * handle creation / destruction events and not "real" file events. | |
| 120 | + */ | |
| 121 | + if (file->f_mode & (FMODE_NONOTIFY | FMODE_PATH)) | |
| 116 | 122 | return 0; |
| 117 | 123 | |
| 118 | 124 | path = &file->f_path; |
| @@ -86,15 +86,15 @@ struct ftrace_hash; · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | #if defined(CONFIG_FUNCTION_TRACER) && defined(CONFIG_MODULES) && \ |
| 88 | 88 | defined(CONFIG_DYNAMIC_FTRACE) |
| 89 | −const char * | |
| 89 | +int | |
| 90 | 90 | ftrace_mod_address_lookup(unsigned long addr, unsigned long *size, |
| 91 | 91 | unsigned long *off, char **modname, char *sym); |
| 92 | 92 | #else |
| 93 | −static inline const char * | |
| 93 | +static inline int | |
| 94 | 94 | ftrace_mod_address_lookup(unsigned long addr, unsigned long *size, |
| 95 | 95 | unsigned long *off, char **modname, char *sym) |
| 96 | 96 | { |
| 97 | − return NULL; | |
| 97 | + return 0; | |
| 98 | 98 | } |
| 99 | 99 | #endif |
| 100 | 100 | |
| @@ -207,7 +207,6 @@ struct io_submit_state { · 206 unmodified lines | ||
| 207 | 207 | bool need_plug; |
| 208 | 208 | bool cq_flush; |
| 209 | 209 | unsigned short submit_nr; |
| 210 | − unsigned int cqes_count; | |
| 211 | 210 | struct blk_plug plug; |
| 212 | 211 | }; |
| 213 | 212 | |
| @@ -1249,6 +1249,7 @@ extern int ata_slave_link_init(struct ata_port *ap); · 1248 unmodified lines | ||
| 1249 | 1249 | extern struct ata_port *ata_sas_port_alloc(struct ata_host *, |
| 1250 | 1250 | struct ata_port_info *, struct Scsi_Host *); |
| 1251 | 1251 | extern void ata_port_probe(struct ata_port *ap); |
| 1252 | +extern void ata_port_free(struct ata_port *ap); | |
| 1252 | 1253 | extern int ata_sas_tport_add(struct device *parent, struct ata_port *ap); |
| 1253 | 1254 | extern void ata_sas_tport_delete(struct ata_port *ap); |
| 1254 | 1255 | int ata_sas_device_configure(struct scsi_device *sdev, struct queue_limits *lim, |
| @@ -2036,7 +2036,11 @@ struct mlx5_ifc_cmd_hca_cap_2_bits { · 2035 unmodified lines | ||
| 2036 | 2036 | u8 min_mkey_log_entity_size_fixed_buffer_valid[0x1]; |
| 2037 | 2037 | u8 reserved_at_402[0x1e]; |
| 2038 | 2038 | |
| 2039 | − u8 reserved_at_420[0x3e0]; | |
| 2039 | + u8 reserved_at_420[0x20]; | |
| 2040 | + | |
| 2041 | + u8 reserved_at_440[0x8]; | |
| 2042 | + u8 max_num_eqs_24b[0x18]; | |
| 2043 | + u8 reserved_at_460[0x3a0]; | |
| 2040 | 2044 | }; |
| 2041 | 2045 | |
| 2042 | 2046 | enum mlx5_ifc_flow_destination_type { |
| @@ -931,11 +931,11 @@ int module_kallsyms_on_each_symbol(const char *modname, · 930 unmodified lines | ||
| 931 | 931 | * least KSYM_NAME_LEN long: a pointer to namebuf is returned if |
| 932 | 932 | * found, otherwise NULL. |
| 933 | 933 | */ |
| 934 | −const char *module_address_lookup(unsigned long addr, | |
| 935 | − unsigned long *symbolsize, | |
| 936 | − unsigned long *offset, | |
| 937 | − char **modname, const unsigned char **modbuildid, | |
| 938 | − char *namebuf); | |
| 934 | +int module_address_lookup(unsigned long addr, | |
| 935 | + unsigned long *symbolsize, | |
| 936 | + unsigned long *offset, | |
| 937 | + char **modname, const unsigned char **modbuildid, | |
| 938 | + char *namebuf); | |
| 939 | 939 | int lookup_module_symbol_name(unsigned long addr, char *symname); |
| 940 | 940 | int lookup_module_symbol_attrs(unsigned long addr, |
| 941 | 941 | unsigned long *size, |
| @@ -964,14 +964,14 @@ static inline int module_kallsyms_on_each_symbol(const char *modname, · 22 unmodified lines | ||
| 964 | 964 | } |
| 965 | 965 | |
| 966 | 966 | /* For kallsyms to ask for address resolution. NULL means not found. */ |
| 967 | −static inline const char *module_address_lookup(unsigned long addr, | |
| 967 | +static inline int module_address_lookup(unsigned long addr, | |
| 968 | 968 | unsigned long *symbolsize, |
| 969 | 969 | unsigned long *offset, |
| 970 | 970 | char **modname, |
| 971 | 971 | const unsigned char **modbuildid, |
| 972 | 972 | char *namebuf) |
| 973 | 973 | { |
| 974 | − return NULL; | |
| 974 | + return 0; | |
| 975 | 975 | } |
| 976 | 976 | |
| 977 | 977 | static inline int lookup_module_symbol_name(unsigned long addr, char *symname) |
| @@ -85,10 +85,11 @@ enum { · 84 unmodified lines | ||
| 85 | 85 | enum { |
| 86 | 86 | NVMF_RDMA_QPTYPE_CONNECTED = 1, /* Reliable Connected */ |
| 87 | 87 | NVMF_RDMA_QPTYPE_DATAGRAM = 2, /* Reliable Datagram */ |
| 88 | + NVMF_RDMA_QPTYPE_INVALID = 0xff, | |
| 88 | 89 | }; |
| 89 | 90 | |
| 90 | −/* RDMA QP Service Type codes for Discovery Log Page entry TSAS | |
| 91 | − * RDMA_QPTYPE field | |
| 91 | +/* RDMA Provider Type codes for Discovery Log Page entry TSAS | |
| 92 | + * RDMA_PRTYPE field | |
| 92 | 93 | */ |
| 93 | 94 | enum { |
| 94 | 95 | NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 1, /* No Provider Specified */ |
| @@ -110,6 +111,7 @@ enum { · 15 unmodified lines | ||
| 110 | 111 | NVMF_TCP_SECTYPE_NONE = 0, /* No Security */ |
| 111 | 112 | NVMF_TCP_SECTYPE_TLS12 = 1, /* TLSv1.2, NVMe-oF 1.1 and NVMe-TCP 3.6.1.1 */ |
| 112 | 113 | NVMF_TCP_SECTYPE_TLS13 = 2, /* TLSv1.3, NVMe-oF 1.1 and NVMe-TCP 3.6.1.1 */ |
| 114 | + NVMF_TCP_SECTYPE_INVALID = 0xff, | |
| 113 | 115 | }; |
| 114 | 116 | |
| 115 | 117 | #define NVME_AQ_DEPTH 32 |
| @@ -1126,7 +1126,7 @@ struct phy_driver { · 1125 unmodified lines | ||
| 1126 | 1126 | u8 index, enum led_brightness value); |
| 1127 | 1127 | |
| 1128 | 1128 | /** |
| 1129 | − * @led_blink_set: Set a PHY LED brightness. Index indicates | |
| 1129 | + * @led_blink_set: Set a PHY LED blinking. Index indicates | |
| 1130 | 1130 | * which of the PHYs led should be configured to blink. Delays |
| 1131 | 1131 | * are in milliseconds and if both are zero then a sensible |
| 1132 | 1132 | * default should be chosen. The call should adjust the |
| @@ -60,9 +60,6 @@ static inline const char *printk_skip_headers(const char *buffer) · 59 unmodified lines | ||
| 60 | 60 | #define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT |
| 61 | 61 | #define CONSOLE_LOGLEVEL_QUIET CONFIG_CONSOLE_LOGLEVEL_QUIET |
| 62 | 62 | |
| 63 | −int add_preferred_console_match(const char *match, const char *name, | |
| 64 | − const short idx); | |
| 65 | − | |
| 66 | 63 | extern int console_printk[]; |
| 67 | 64 | |
| 68 | 65 | #define console_loglevel (console_printk[0]) |
| @@ -811,8 +811,7 @@ enum UART_TX_FLAGS { · 810 unmodified lines | ||
| 811 | 811 | if (pending < WAKEUP_CHARS) { \ |
| 812 | 812 | uart_write_wakeup(__port); \ |
| 813 | 813 | \ |
| 814 | − if (!((flags) & UART_TX_NOSTOP) && pending == 0 && \ | |
| 815 | − __port->ops->tx_empty(__port)) \ | |
| 814 | + if (!((flags) & UART_TX_NOSTOP) && pending == 0) \ | |
| 816 | 815 | __port->ops->stop_tx(__port); \ |
| 817 | 816 | } \ |
| 818 | 817 | \ |
| @@ -851,6 +850,24 @@ enum UART_TX_FLAGS { · 32 unmodified lines | ||
| 851 | 850 | __count--); \ |
| 852 | 851 | }) |
| 853 | 852 | |
| 853 | +/** | |
| 854 | + * uart_port_tx_limited_flags -- transmit helper for uart_port with count limiting with flags | |
| 855 | + * @port: uart port | |
| 856 | + * @ch: variable to store a character to be written to the HW | |
| 857 | + * @flags: %UART_TX_NOSTOP or similar | |
| 858 | + * @count: a limit of characters to send | |
| 859 | + * @tx_ready: can HW accept more data function | |
| 860 | + * @put_char: function to write a character | |
| 861 | + * @tx_done: function to call after the loop is done | |
| 862 | + * | |
| 863 | + * See uart_port_tx_limited() for more details. | |
| 864 | + */ | |
| 865 | +#define uart_port_tx_limited_flags(port, ch, flags, count, tx_ready, put_char, tx_done) ({ \ | |
| 866 | + unsigned int __count = (count); \ | |
| 867 | + __uart_port_tx(port, ch, flags, tx_ready, put_char, tx_done, __count, \ | |
| 868 | + __count--); \ | |
| 869 | +}) | |
| 870 | + | |
| 854 | 871 | /** |
| 855 | 872 | * uart_port_tx -- transmit helper for uart_port |
| 856 | 873 | * @port: uart port |
| @@ -322,13 +322,13 @@ asmlinkage long sys_io_pgetevents(aio_context_t ctx_id, · 321 unmodified lines | ||
| 322 | 322 | long nr, |
| 323 | 323 | struct io_event __user *events, |
| 324 | 324 | struct __kernel_timespec __user *timeout, |
| 325 | − const struct __aio_sigset *sig); | |
| 325 | + const struct __aio_sigset __user *sig); | |
| 326 | 326 | asmlinkage long sys_io_pgetevents_time32(aio_context_t ctx_id, |
| 327 | 327 | long min_nr, |
| 328 | 328 | long nr, |
| 329 | 329 | struct io_event __user *events, |
| 330 | 330 | struct old_timespec32 __user *timeout, |
| 331 | − const struct __aio_sigset *sig); | |
| 331 | + const struct __aio_sigset __user *sig); | |
| 332 | 332 | asmlinkage long sys_io_uring_setup(u32 entries, |
| 333 | 333 | struct io_uring_params __user *p); |
| 334 | 334 | asmlinkage long sys_io_uring_enter(unsigned int fd, u32 to_submit, |
| @@ -418,7 +418,7 @@ asmlinkage long sys_listmount(const struct mnt_id_req __user *req, · 83 unmodified lines | ||
| 418 | 418 | u64 __user *mnt_ids, size_t nr_mnt_ids, |
| 419 | 419 | unsigned int flags); |
| 420 | 420 | asmlinkage long sys_truncate(const char __user *path, long length); |
| 421 | −asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); | |
| 421 | +asmlinkage long sys_ftruncate(unsigned int fd, off_t length); | |
| 422 | 422 | #if BITS_PER_LONG == 32 |
| 423 | 423 | asmlinkage long sys_truncate64(const char __user *path, loff_t length); |
| 424 | 424 | asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); |
| @@ -441,7 +441,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group); · 16 unmodified lines | ||
| 441 | 441 | asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, |
| 442 | 442 | umode_t mode); |
| 443 | 443 | asmlinkage long sys_openat2(int dfd, const char __user *filename, |
| 444 | − struct open_how *how, size_t size); | |
| 444 | + struct open_how __user *how, size_t size); | |
| 445 | 445 | asmlinkage long sys_close(unsigned int fd); |
| 446 | 446 | asmlinkage long sys_close_range(unsigned int fd, unsigned int max_fd, |
| 447 | 447 | unsigned int flags); |
| @@ -555,7 +555,7 @@ asmlinkage long sys_get_robust_list(int pid, · 107 unmodified lines | ||
| 555 | 555 | asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, |
| 556 | 556 | size_t len); |
| 557 | 557 | |
| 558 | −asmlinkage long sys_futex_waitv(struct futex_waitv *waiters, | |
| 558 | +asmlinkage long sys_futex_waitv(struct futex_waitv __user *waiters, | |
| 559 | 559 | unsigned int nr_futexes, unsigned int flags, |
| 560 | 560 | struct __kernel_timespec __user *timeout, clockid_t clockid); |
| 561 | 561 | |
| @@ -859,9 +859,15 @@ asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource, · 297 unmodified lines | ||
| 859 | 859 | const struct rlimit64 __user *new_rlim, |
| 860 | 860 | struct rlimit64 __user *old_rlim); |
| 861 | 861 | asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags); |
| 862 | +#if defined(CONFIG_ARCH_SPLIT_ARG64) | |
| 863 | +asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, | |
| 864 | + unsigned int mask_1, unsigned int mask_2, | |
| 865 | + int dfd, const char __user * pathname); | |
| 866 | +#else | |
| 862 | 867 | asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, |
| 863 | 868 | u64 mask, int fd, |
| 864 | 869 | const char __user *pathname); |
| 870 | +#endif | |
| 865 | 871 | asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name, |
| 866 | 872 | struct file_handle __user *handle, |
| 867 | 873 | int __user *mnt_id, int flag); |
| @@ -907,7 +913,7 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int flags, · 39 unmodified lines | ||
| 907 | 913 | asmlinkage long sys_getrandom(char __user *buf, size_t count, |
| 908 | 914 | unsigned int flags); |
| 909 | 915 | asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags); |
| 910 | −asmlinkage long sys_bpf(int cmd, union bpf_attr *attr, unsigned int size); | |
| 916 | +asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size); | |
| 911 | 917 | asmlinkage long sys_execveat(int dfd, const char __user *filename, |
| 912 | 918 | const char __user *const __user *argv, |
| 913 | 919 | const char __user *const __user *envp, int flags); |
| @@ -960,11 +966,11 @@ asmlinkage long sys_cachestat(unsigned int fd, · 46 unmodified lines | ||
| 960 | 966 | struct cachestat_range __user *cstat_range, |
| 961 | 967 | struct cachestat __user *cstat, unsigned int flags); |
| 962 | 968 | asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags); |
| 963 | −asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, | |
| 964 | − u32 *size, u32 flags); | |
| 965 | −asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, | |
| 969 | +asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx __user *ctx, | |
| 970 | + u32 __user *size, u32 flags); | |
| 971 | +asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx __user *ctx, | |
| 966 | 972 | u32 size, u32 flags); |
| 967 | −asmlinkage long sys_lsm_list_modules(u64 *ids, u32 *size, u32 flags); | |
| 973 | +asmlinkage long sys_lsm_list_modules(u64 __user *ids, u32 __user *size, u32 flags); | |
| 968 | 974 | |
| 969 | 975 | /* |
| 970 | 976 | * Architecture-specific system calls |
| @@ -324,6 +324,17 @@ enum { · 323 unmodified lines | ||
| 324 | 324 | * claim to support it. |
| 325 | 325 | */ |
| 326 | 326 | HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, |
| 327 | + | |
| 328 | + /* | |
| 329 | + * When this quirk is set, the reserved bits of Primary/Secondary_PHY | |
| 330 | + * inside the LE Extended Advertising Report events are discarded. | |
| 331 | + * This is required for some Apple/Broadcom controllers which | |
| 332 | + * abuse these reserved bits for unrelated flags. | |
| 333 | + * | |
| 334 | + * This quirk can be set before hci_register_dev is called or | |
| 335 | + * during the hdev->setup vendor callback. | |
| 336 | + */ | |
| 337 | + HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, | |
| 327 | 338 | }; |
| 328 | 339 | |
| 329 | 340 | /* HCI device flags */ |
| @@ -38,6 +38,8 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen, · 37 unmodified lines | ||
| 38 | 38 | int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen, |
| 39 | 39 | const void *param, u8 event, u32 timeout, |
| 40 | 40 | struct sock *sk); |
| 41 | +int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen, | |
| 42 | + const void *param, u32 timeout); | |
| 41 | 43 | |
| 42 | 44 | void hci_cmd_sync_init(struct hci_dev *hdev); |
| 43 | 45 | void hci_cmd_sync_clear(struct hci_dev *hdev); |
| @@ -396,7 +396,7 @@ enum ieee80211_bss_change { · 395 unmodified lines | ||
| 396 | 396 | BSS_CHANGED_HE_OBSS_PD = 1<<28, |
| 397 | 397 | BSS_CHANGED_HE_BSS_COLOR = 1<<29, |
| 398 | 398 | BSS_CHANGED_FILS_DISCOVERY = 1<<30, |
| 399 | − BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = 1<<31, | |
| 399 | + BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = BIT_ULL(31), | |
| 400 | 400 | BSS_CHANGED_MLD_VALID_LINKS = BIT_ULL(33), |
| 401 | 401 | BSS_CHANGED_MLD_TTLM = BIT_ULL(34), |
| 402 | 402 | BSS_CHANGED_TPE = BIT_ULL(35), |
| @@ -737,7 +737,7 @@ __SC_COMP(__NR_pselect6_time64, sys_pselect6, compat_sys_pselect6_time64) · 736 unmodified lines | ||
| 737 | 737 | #define __NR_ppoll_time64 414 |
| 738 | 738 | __SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64) |
| 739 | 739 | #define __NR_io_pgetevents_time64 416 |
| 740 | −__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) | |
| 740 | +__SC_COMP(__NR_io_pgetevents_time64, sys_io_pgetevents, compat_sys_io_pgetevents_time64) | |
| 741 | 741 | #define __NR_recvmmsg_time64 417 |
| 742 | 742 | __SC_COMP(__NR_recvmmsg_time64, sys_recvmmsg, compat_sys_recvmmsg_time64) |
| 743 | 743 | #define __NR_mq_timedsend_time64 418 |
| @@ -43,6 +43,6 @@ struct trace_buffer_meta { · 42 unmodified lines | ||
| 43 | 43 | __u64 Reserved2; |
| 44 | 44 | }; |
| 45 | 45 | |
| 46 | −#define TRACE_MMAP_IOCTL_GET_READER _IO('T', 0x1) | |
| 46 | +#define TRACE_MMAP_IOCTL_GET_READER _IO('R', 0x20) | |
| 47 | 47 | |
| 48 | 48 | #endif /* _TRACE_MMAP_H_ */ |
| @@ -1259,8 +1259,8 @@ static void io_req_normal_work_add(struct io_kiocb *req) · 1258 unmodified lines | ||
| 1259 | 1259 | if (ctx->flags & IORING_SETUP_SQPOLL) { |
| 1260 | 1260 | struct io_sq_data *sqd = ctx->sq_data; |
| 1261 | 1261 | |
| 1262 | − if (wq_has_sleeper(&sqd->wait)) | |
| 1263 | − wake_up(&sqd->wait); | |
| 1262 | + if (sqd->thread) | |
| 1263 | + __set_notify_signal(sqd->thread); | |
| 1264 | 1264 | return; |
| 1265 | 1265 | } |
| 1266 | 1266 | |
| @@ -1127,16 +1127,18 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags) · 1126 unmodified lines | ||
| 1127 | 1127 | flags |= MSG_DONTWAIT; |
| 1128 | 1128 | |
| 1129 | 1129 | retry_multishot: |
| 1130 | − kmsg->msg.msg_inq = -1; | |
| 1131 | − kmsg->msg.msg_flags = 0; | |
| 1132 | − | |
| 1133 | 1130 | if (io_do_buffer_select(req)) { |
| 1134 | 1131 | ret = io_recv_buf_select(req, kmsg, &len, issue_flags); |
| 1135 | − if (unlikely(ret)) | |
| 1132 | + if (unlikely(ret)) { | |
| 1133 | + kmsg->msg.msg_inq = -1; | |
| 1136 | 1134 | goto out_free; |
| 1135 | + } | |
| 1137 | 1136 | sr->buf = NULL; |
| 1138 | 1137 | } |
| 1139 | 1138 | |
| 1139 | + kmsg->msg.msg_flags = 0; | |
| 1140 | + kmsg->msg.msg_inq = -1; | |
| 1141 | + | |
| 1140 | 1142 | if (flags & MSG_WAITALL) |
| 1141 | 1143 | min_ret = iov_iter_count(&kmsg->msg.msg_iter); |
| 1142 | 1144 | |
| @@ -736,11 +736,11 @@ static struct bpf_ksym *bpf_ksym_find(unsigned long addr) · 735 unmodified lines | ||
| 736 | 736 | return n ? container_of(n, struct bpf_ksym, tnode) : NULL; |
| 737 | 737 | } |
| 738 | 738 | |
| 739 | −const char *__bpf_address_lookup(unsigned long addr, unsigned long *size, | |
| 739 | +int __bpf_address_lookup(unsigned long addr, unsigned long *size, | |
| 740 | 740 | unsigned long *off, char *sym) |
| 741 | 741 | { |
| 742 | 742 | struct bpf_ksym *ksym; |
| 743 | − char *ret = NULL; | |
| 743 | + int ret = 0; | |
| 744 | 744 | |
| 745 | 745 | rcu_read_lock(); |
| 746 | 746 | ksym = bpf_ksym_find(addr); |
| @@ -748,9 +748,8 @@ const char *__bpf_address_lookup(unsigned long addr, unsigned long *size, · 1 unmodified line | ||
| 748 | 748 | unsigned long symbol_start = ksym->start; |
| 749 | 749 | unsigned long symbol_end = ksym->end; |
| 750 | 750 | |
| 751 | − strscpy(sym, ksym->name, KSYM_NAME_LEN); | |
| 751 | + ret = strscpy(sym, ksym->name, KSYM_NAME_LEN); | |
| 752 | 752 | |
| 753 | − ret = sym; | |
| 754 | 753 | if (size) |
| 755 | 754 | *size = symbol_end - symbol_start; |
| 756 | 755 | if (off) |
| @@ -1859,6 +1859,9 @@ static inline bool cpuhp_bringup_cpus_parallel(unsigned int ncpus) { return fals · 1858 unmodified lines | ||
| 1859 | 1859 | |
| 1860 | 1860 | void __init bringup_nonboot_cpus(unsigned int max_cpus) |
| 1861 | 1861 | { |
| 1862 | + if (!max_cpus) | |
| 1863 | + return; | |
| 1864 | + | |
| 1862 | 1865 | /* Try parallel bringup optimization if enabled */ |
| 1863 | 1866 | if (cpuhp_bringup_cpus_parallel(max_cpus)) |
| 1864 | 1867 | return; |
| @@ -2446,7 +2449,7 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance); · 581 unmodified lines | ||
| 2446 | 2449 | * The caller needs to hold cpus read locked while calling this function. |
| 2447 | 2450 | * Return: |
| 2448 | 2451 | * On success: |
| 2449 | − * Positive state number if @state is CPUHP_AP_ONLINE_DYN; | |
| 2452 | + * Positive state number if @state is CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN; | |
| 2450 | 2453 | * 0 for all other states |
| 2451 | 2454 | * On failure: proper (negative) error code |
| 2452 | 2455 | */ |
| @@ -2469,7 +2472,7 @@ int __cpuhp_setup_state_cpuslocked(enum cpuhp_state state, · 16 unmodified lines | ||
| 2469 | 2472 | ret = cpuhp_store_callbacks(state, name, startup, teardown, |
| 2470 | 2473 | multi_instance); |
| 2471 | 2474 | |
| 2472 | − dynstate = state == CPUHP_AP_ONLINE_DYN; | |
| 2475 | + dynstate = state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN; | |
| 2473 | 2476 | if (ret > 0 && dynstate) { |
| 2474 | 2477 | state = ret; |
| 2475 | 2478 | ret = 0; |
| @@ -2500,8 +2503,8 @@ int __cpuhp_setup_state_cpuslocked(enum cpuhp_state state, · 24 unmodified lines | ||
| 2500 | 2503 | out: |
| 2501 | 2504 | mutex_unlock(&cpuhp_state_mutex); |
| 2502 | 2505 | /* |
| 2503 | − * If the requested state is CPUHP_AP_ONLINE_DYN, return the | |
| 2504 | − * dynamically allocated state in case of success. | |
| 2506 | + * If the requested state is CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN, | |
| 2507 | + * return the dynamically allocated state in case of success. | |
| 2505 | 2508 | */ |
| 2506 | 2509 | if (!ret && dynstate) |
| 2507 | 2510 | return state; |
| @@ -484,6 +484,8 @@ retry: · 483 unmodified lines | ||
| 484 | 484 | * Search through everything else, we should not get here often. |
| 485 | 485 | */ |
| 486 | 486 | for_each_process(g) { |
| 487 | + if (atomic_read(&mm->mm_users) <= 1) | |
| 488 | + break; | |
| 487 | 489 | if (g->flags & PF_KTHREAD) |
| 488 | 490 | continue; |
| 489 | 491 | for_each_thread(g, c) { |
| @@ -388,12 +388,12 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, · 387 unmodified lines | ||
| 388 | 388 | !!__bpf_address_lookup(addr, symbolsize, offset, namebuf); |
| 389 | 389 | } |
| 390 | 390 | |
| 391 | −static const char *kallsyms_lookup_buildid(unsigned long addr, | |
| 391 | +static int kallsyms_lookup_buildid(unsigned long addr, | |
| 392 | 392 | unsigned long *symbolsize, |
| 393 | 393 | unsigned long *offset, char **modname, |
| 394 | 394 | const unsigned char **modbuildid, char *namebuf) |
| 395 | 395 | { |
| 396 | − const char *ret; | |
| 396 | + int ret; | |
| 397 | 397 | |
| 398 | 398 | namebuf[KSYM_NAME_LEN - 1] = 0; |
| 399 | 399 | namebuf[0] = 0; |
| @@ -410,7 +410,7 @@ static const char *kallsyms_lookup_buildid(unsigned long addr, · 10 unmodified lines | ||
| 410 | 410 | if (modbuildid) |
| 411 | 411 | *modbuildid = NULL; |
| 412 | 412 | |
| 413 | − ret = namebuf; | |
| 413 | + ret = strlen(namebuf); | |
| 414 | 414 | goto found; |
| 415 | 415 | } |
| 416 | 416 | |
| @@ -442,8 +442,13 @@ const char *kallsyms_lookup(unsigned long addr, · 25 unmodified lines | ||
| 442 | 442 | unsigned long *offset, |
| 443 | 443 | char **modname, char *namebuf) |
| 444 | 444 | { |
| 445 | − return kallsyms_lookup_buildid(addr, symbolsize, offset, modname, | |
| 446 | − NULL, namebuf); | |
| 445 | + int ret = kallsyms_lookup_buildid(addr, symbolsize, offset, modname, | |
| 446 | + NULL, namebuf); | |
| 447 | + | |
| 448 | + if (!ret) | |
| 449 | + return NULL; | |
| 450 | + | |
| 451 | + return namebuf; | |
| 447 | 452 | } |
| 448 | 453 | |
| 449 | 454 | int lookup_symbol_name(unsigned long addr, char *symname) |
| @@ -478,19 +483,15 @@ static int __sprint_symbol(char *buffer, unsigned long address, · 28 unmodified lines | ||
| 478 | 483 | { |
| 479 | 484 | char *modname; |
| 480 | 485 | const unsigned char *buildid; |
| 481 | − const char *name; | |
| 482 | 486 | unsigned long offset, size; |
| 483 | 487 | int len; |
| 484 | 488 | |
| 485 | 489 | address += symbol_offset; |
| 486 | − name = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid, | |
| 490 | + len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid, | |
| 487 | 491 | buffer); |
| 488 | − if (!name) | |
| 492 | + if (!len) | |
| 489 | 493 | return sprintf(buffer, "0x%lx", address - symbol_offset); |
| 490 | 494 | |
| 491 | − if (name != buffer) | |
| 492 | − strcpy(buffer, name); | |
| 493 | − len = strlen(buffer); | |
| 494 | 495 | offset -= symbol_offset; |
| 495 | 496 | |
| 496 | 497 | if (add_offset) |
| @@ -321,14 +321,15 @@ void * __weak dereference_module_function_descriptor(struct module *mod, · 320 unmodified lines | ||
| 321 | 321 | * For kallsyms to ask for address resolution. NULL means not found. Careful |
| 322 | 322 | * not to lock to avoid deadlock on oopses, simply disable preemption. |
| 323 | 323 | */ |
| 324 | −const char *module_address_lookup(unsigned long addr, | |
| 325 | − unsigned long *size, | |
| 326 | − unsigned long *offset, | |
| 327 | − char **modname, | |
| 328 | − const unsigned char **modbuildid, | |
| 329 | − char *namebuf) | |
| 324 | +int module_address_lookup(unsigned long addr, | |
| 325 | + unsigned long *size, | |
| 326 | + unsigned long *offset, | |
| 327 | + char **modname, | |
| 328 | + const unsigned char **modbuildid, | |
| 329 | + char *namebuf) | |
| 330 | 330 | { |
| 331 | − const char *ret = NULL; | |
| 331 | + const char *sym; | |
| 332 | + int ret = 0; | |
| 332 | 333 | struct module *mod; |
| 333 | 334 | |
| 334 | 335 | preempt_disable(); |
| @@ -344,12 +345,10 @@ const char *module_address_lookup(unsigned long addr, · 9 unmodified lines | ||
| 344 | 345 | #endif |
| 345 | 346 | } |
| 346 | 347 | |
| 347 | − ret = find_kallsyms_symbol(mod, addr, size, offset); | |
| 348 | − } | |
| 349 | − /* Make a copy in here where it's safe */ | |
| 350 | − if (ret) { | |
| 351 | − strscpy(namebuf, ret, KSYM_NAME_LEN); | |
| 352 | − ret = namebuf; | |
| 348 | + sym = find_kallsyms_symbol(mod, addr, size, offset); | |
| 349 | + | |
| 350 | + if (sym) | |
| 351 | + ret = strscpy(namebuf, sym, KSYM_NAME_LEN); | |
| 353 | 352 | } |
| 354 | 353 | preempt_enable(); |
| 355 | 354 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | −obj-y = printk.o conopt.o | |
| 2 | +obj-y = printk.o | |
| 3 | 3 | obj-$(CONFIG_PRINTK) += printk_safe.o nbcon.o |
| 4 | 4 | obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o |
| 5 | 5 | obj-$(CONFIG_PRINTK_INDEX) += index.o |
| @@ -1,146 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 2 | −/* | |
| 3 | − * Kernel command line console options for hardware based addressing | |
| 4 | − * | |
| 5 | − * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ | |
| 6 | − * Author: Tony Lindgren <tony@atomide.com> | |
| 7 | − */ | |
| 8 | − | |
| 9 | −#include <linux/console.h> | |
| 10 | −#include <linux/init.h> | |
| 11 | −#include <linux/string.h> | |
| 12 | −#include <linux/types.h> | |
| 13 | − | |
| 14 | −#include <asm/errno.h> | |
| 15 | − | |
| 16 | −#include "console_cmdline.h" | |
| 17 | − | |
| 18 | −/* | |
| 19 | − * Allow longer DEVNAME:0.0 style console naming such as abcd0000.serial:0.0 | |
| 20 | − * in addition to the legacy ttyS0 style naming. | |
| 21 | − */ | |
| 22 | −#define CONSOLE_NAME_MAX 32 | |
| 23 | − | |
| 24 | −#define CONSOLE_OPT_MAX 16 | |
| 25 | −#define CONSOLE_BRL_OPT_MAX 16 | |
| 26 | − | |
| 27 | −struct console_option { | |
| 28 | − char name[CONSOLE_NAME_MAX]; | |
| 29 | − char opt[CONSOLE_OPT_MAX]; | |
| 30 | − char brl_opt[CONSOLE_BRL_OPT_MAX]; | |
| 31 | − u8 has_brl_opt:1; | |
| 32 | −}; | |
| 33 | − | |
| 34 | −/* Updated only at console_setup() time, no locking needed */ | |
| 35 | −static struct console_option conopt[MAX_CMDLINECONSOLES]; | |
| 36 | − | |
| 37 | −/** | |
| 38 | − * console_opt_save - Saves kernel command line console option for driver use | |
| 39 | − * @str: Kernel command line console name and option | |
| 40 | − * @brl_opt: Braille console options | |
| 41 | − * | |
| 42 | − * Saves a kernel command line console option for driver subsystems to use for | |
| 43 | − * adding a preferred console during init. Called from console_setup() only. | |
| 44 | − * | |
| 45 | − * Return: 0 on success, negative error code on failure. | |
| 46 | − */ | |
| 47 | −int __init console_opt_save(const char *str, const char *brl_opt) | |
| 48 | −{ | |
| 49 | − struct console_option *con; | |
| 50 | − size_t namelen, optlen; | |
| 51 | − const char *opt; | |
| 52 | − int i; | |
| 53 | − | |
| 54 | − namelen = strcspn(str, ","); | |
| 55 | − if (namelen == 0 || namelen >= CONSOLE_NAME_MAX) | |
| 56 | − return -EINVAL; | |
| 57 | − | |
| 58 | − opt = str + namelen; | |
| 59 | − if (*opt == ',') | |
| 60 | − opt++; | |
| 61 | − | |
| 62 | − optlen = strlen(opt); | |
| 63 | − if (optlen >= CONSOLE_OPT_MAX) | |
| 64 | − return -EINVAL; | |
| 65 | − | |
| 66 | − for (i = 0; i < MAX_CMDLINECONSOLES; i++) { | |
| 67 | − con = &conopt[i]; | |
| 68 | − | |
| 69 | − if (con->name[0]) { | |
| 70 | − if (!strncmp(str, con->name, namelen)) | |
| 71 | − return 0; | |
| 72 | − continue; | |
| 73 | − } | |
| 74 | − | |
| 75 | − /* | |
| 76 | − * The name isn't terminated, only opt is. Empty opt is fine, | |
| 77 | − * but brl_opt can be either empty or NULL. For more info, see | |
| 78 | − * _braille_console_setup(). | |
| 79 | − */ | |
| 80 | − strscpy(con->name, str, namelen + 1); | |
| 81 | − strscpy(con->opt, opt, CONSOLE_OPT_MAX); | |
| 82 | − if (brl_opt) { | |
| 83 | − strscpy(con->brl_opt, brl_opt, CONSOLE_BRL_OPT_MAX); | |
| 84 | − con->has_brl_opt = 1; | |
| 85 | − } | |
| 86 | − | |
| 87 | − return 0; | |
| 88 | − } | |
| 89 | − | |
| 90 | − return -ENOMEM; | |
| 91 | −} | |
| 92 | − | |
| 93 | −static struct console_option *console_opt_find(const char *name) | |
| 94 | −{ | |
| 95 | − struct console_option *con; | |
| 96 | − int i; | |
| 97 | − | |
| 98 | − for (i = 0; i < MAX_CMDLINECONSOLES; i++) { | |
| 99 | − con = &conopt[i]; | |
| 100 | − if (!strcmp(name, con->name)) | |
| 101 | − return con; | |
| 102 | − } | |
| 103 | − | |
| 104 | − return NULL; | |
| 105 | −} | |
| 106 | − | |
| 107 | −/** | |
| 108 | − * add_preferred_console_match - Adds a preferred console if a match is found | |
| 109 | − * @match: Expected console on kernel command line, such as console=DEVNAME:0.0 | |
| 110 | − * @name: Name of the console character device to add such as ttyS | |
| 111 | − * @idx: Index for the console | |
| 112 | − * | |
| 113 | − * Allows driver subsystems to add a console after translating the command | |
| 114 | − * line name to the character device name used for the console. Options are | |
| 115 | − * added automatically based on the kernel command line. Duplicate preferred | |
| 116 | − * consoles are ignored by __add_preferred_console(). | |
| 117 | − * | |
| 118 | − * Return: 0 on success, negative error code on failure. | |
| 119 | − */ | |
| 120 | −int add_preferred_console_match(const char *match, const char *name, | |
| 121 | − const short idx) | |
| 122 | −{ | |
| 123 | − struct console_option *con; | |
| 124 | − char *brl_opt = NULL; | |
| 125 | − | |
| 126 | − if (!match || !strlen(match) || !name || !strlen(name) || | |
| 127 | − idx < 0) | |
| 128 | − return -EINVAL; | |
| 129 | − | |
| 130 | − con = console_opt_find(match); | |
| 131 | − if (!con) | |
| 132 | − return -ENOENT; | |
| 133 | − | |
| 134 | − /* | |
| 135 | − * See __add_preferred_console(). It checks for NULL brl_options to set | |
| 136 | − * the preferred_console flag. Empty brl_opt instead of NULL leads into | |
| 137 | − * the preferred_console flag not set, and CON_CONSDEV not being set, | |
| 138 | − * and the boot console won't get disabled at the end of console_setup(). | |
| 139 | − */ | |
| 140 | − if (con->has_brl_opt) | |
| 141 | − brl_opt = con->brl_opt; | |
| 142 | − | |
| 143 | − console_opt_add_preferred_console(name, idx, con->opt, brl_opt); | |
| 144 | − | |
| 145 | − return 0; | |
| 146 | −} | |
| @@ -2,12 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _CONSOLE_CMDLINE_H |
| 3 | 3 | #define _CONSOLE_CMDLINE_H |
| 4 | 4 | |
| 5 | −#define MAX_CMDLINECONSOLES 8 | |
| 6 | − | |
| 7 | −int console_opt_save(const char *str, const char *brl_opt); | |
| 8 | −int console_opt_add_preferred_console(const char *name, const short idx, | |
| 9 | − char *options, char *brl_options); | |
| 10 | − | |
| 11 | 5 | struct console_cmdline |
| 12 | 6 | { |
| 13 | 7 | char name[16]; /* Name of the driver */ |
| @@ -383,6 +383,9 @@ static int console_locked; · 382 unmodified lines | ||
| 383 | 383 | /* |
| 384 | 384 | * Array of consoles built from command line options (console=) |
| 385 | 385 | */ |
| 386 | + | |
| 387 | +#define MAX_CMDLINECONSOLES 8 | |
| 388 | + | |
| 386 | 389 | static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; |
| 387 | 390 | |
| 388 | 391 | static int preferred_console = -1; |
| @@ -2500,17 +2503,6 @@ static int __init console_setup(char *str) · 2111 unmodified lines | ||
| 2500 | 2503 | if (_braille_console_setup(&str, &brl_options)) |
| 2501 | 2504 | return 1; |
| 2502 | 2505 | |
| 2503 | − /* Save the console for driver subsystem use */ | |
| 2504 | − if (console_opt_save(str, brl_options)) | |
| 2505 | − return 1; | |
| 2506 | − | |
| 2507 | − /* Flag register_console() to not call try_enable_default_console() */ | |
| 2508 | − console_set_on_cmdline = 1; | |
| 2509 | − | |
| 2510 | − /* Don't attempt to parse a DEVNAME:0.0 style console */ | |
| 2511 | − if (strchr(str, ':')) | |
| 2512 | − return 1; | |
| 2513 | − | |
| 2514 | 2506 | /* |
| 2515 | 2507 | * Decode str into name, index, options. |
| 2516 | 2508 | */ |
| @@ -2541,13 +2533,6 @@ static int __init console_setup(char *str) · 24 unmodified lines | ||
| 2541 | 2533 | } |
| 2542 | 2534 | __setup("console=", console_setup); |
| 2543 | 2535 | |
| 2544 | −/* Only called from add_preferred_console_match() */ | |
| 2545 | −int console_opt_add_preferred_console(const char *name, const short idx, | |
| 2546 | − char *options, char *brl_options) | |
| 2547 | −{ | |
| 2548 | − return __add_preferred_console(name, idx, options, brl_options, true); | |
| 2549 | −} | |
| 2550 | − | |
| 2551 | 2536 | /** |
| 2552 | 2537 | * add_preferred_console - add a device to the list of preferred consoles. |
| 2553 | 2538 | * @name: device name |
| @@ -3522,7 +3507,7 @@ void register_console(struct console *newcon) · 968 unmodified lines | ||
| 3522 | 3507 | * Note that a console with tty binding will have CON_CONSDEV |
| 3523 | 3508 | * flag set and will be first in the list. |
| 3524 | 3509 | */ |
| 3525 | − if (preferred_console < 0 && !console_set_on_cmdline) { | |
| 3510 | + if (preferred_console < 0) { | |
| 3526 | 3511 | if (hlist_empty(&console_list) || !console_first()->device || |
| 3527 | 3512 | console_first()->flags & CON_BOOT) { |
| 3528 | 3513 | try_enable_default_console(newcon); |
| @@ -46,8 +46,8 @@ COND_SYSCALL(io_getevents_time32); · 45 unmodified lines | ||
| 46 | 46 | COND_SYSCALL(io_getevents); |
| 47 | 47 | COND_SYSCALL(io_pgetevents_time32); |
| 48 | 48 | COND_SYSCALL(io_pgetevents); |
| 49 | −COND_SYSCALL_COMPAT(io_pgetevents_time32); | |
| 50 | 49 | COND_SYSCALL_COMPAT(io_pgetevents); |
| 50 | +COND_SYSCALL_COMPAT(io_pgetevents_time64); | |
| 51 | 51 | COND_SYSCALL(io_uring_setup); |
| 52 | 52 | COND_SYSCALL(io_uring_enter); |
| 53 | 53 | COND_SYSCALL(io_uring_register); |
| @@ -1285,6 +1285,8 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, · 1284 unmodified lines | ||
| 1285 | 1285 | struct hrtimer_clock_base *base; |
| 1286 | 1286 | unsigned long flags; |
| 1287 | 1287 | |
| 1288 | + if (WARN_ON_ONCE(!timer->function)) | |
| 1289 | + return; | |
| 1288 | 1290 | /* |
| 1289 | 1291 | * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft |
| 1290 | 1292 | * match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard |
| @@ -6969,7 +6969,7 @@ allocate_ftrace_mod_map(struct module *mod, · 6968 unmodified lines | ||
| 6969 | 6969 | return mod_map; |
| 6970 | 6970 | } |
| 6971 | 6971 | |
| 6972 | −static const char * | |
| 6972 | +static int | |
| 6973 | 6973 | ftrace_func_address_lookup(struct ftrace_mod_map *mod_map, |
| 6974 | 6974 | unsigned long addr, unsigned long *size, |
| 6975 | 6975 | unsigned long *off, char *sym) |
| @@ -6990,21 +6990,18 @@ ftrace_func_address_lookup(struct ftrace_mod_map *mod_map, · 14 unmodified lines | ||
| 6990 | 6990 | *size = found_func->size; |
| 6991 | 6991 | if (off) |
| 6992 | 6992 | *off = addr - found_func->ip; |
| 6993 | − if (sym) | |
| 6994 | − strscpy(sym, found_func->name, KSYM_NAME_LEN); | |
| 6995 | − | |
| 6996 | − return found_func->name; | |
| 6993 | + return strscpy(sym, found_func->name, KSYM_NAME_LEN); | |
| 6997 | 6994 | } |
| 6998 | 6995 | |
| 6999 | − return NULL; | |
| 6996 | + return 0; | |
| 7000 | 6997 | } |
| 7001 | 6998 | |
| 7002 | −const char * | |
| 6999 | +int | |
| 7003 | 7000 | ftrace_mod_address_lookup(unsigned long addr, unsigned long *size, |
| 7004 | 7001 | unsigned long *off, char **modname, char *sym) |
| 7005 | 7002 | { |
| 7006 | 7003 | struct ftrace_mod_map *mod_map; |
| 7007 | − const char *ret = NULL; | |
| 7004 | + int ret = 0; | |
| 7008 | 7005 | |
| 7009 | 7006 | /* mod_map is freed via call_rcu() */ |
| 7010 | 7007 | preempt_disable(); |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/seq_file.h> |
| 14 | 14 | #include <linux/sched/debug.h> |
| 15 | 15 | |
| 16 | −static inline void closure_put_after_sub(struct closure *cl, int flags) | |
| 16 | +static inline void closure_put_after_sub_checks(int flags) | |
| 17 | 17 | { |
| 18 | 18 | int r = flags & CLOSURE_REMAINING_MASK; |
| 19 | 19 | |
| @@ -22,12 +22,17 @@ static inline void closure_put_after_sub(struct closure *cl, int flags) · 2 unmodified lines | ||
| 22 | 22 | flags & CLOSURE_GUARD_MASK, (unsigned) __fls(r))) |
| 23 | 23 | r &= ~CLOSURE_GUARD_MASK; |
| 24 | 24 | |
| 25 | − if (!r) { | |
| 26 | − smp_acquire__after_ctrl_dep(); | |
| 25 | + WARN(!r && (flags & ~CLOSURE_DESTRUCTOR), | |
| 26 | + "closure ref hit 0 with incorrect flags set: %x (%u)", | |
| 27 | + flags & ~CLOSURE_DESTRUCTOR, (unsigned) __fls(flags)); | |
| 28 | +} | |
| 29 | + | |
| 30 | +static inline void closure_put_after_sub(struct closure *cl, int flags) | |
| 31 | +{ | |
| 32 | + closure_put_after_sub_checks(flags); | |
| 27 | 33 | |
| 28 | − WARN(flags & ~CLOSURE_DESTRUCTOR, | |
| 29 | − "closure ref hit 0 with incorrect flags set: %x (%u)", | |
| 30 | − flags & ~CLOSURE_DESTRUCTOR, (unsigned) __fls(flags)); | |
| 34 | + if (!(flags & CLOSURE_REMAINING_MASK)) { | |
| 35 | + smp_acquire__after_ctrl_dep(); | |
| 31 | 36 | |
| 32 | 37 | cl->closure_get_happened = false; |
| 33 | 38 | |
| @@ -145,6 +150,41 @@ void __sched __closure_sync(struct closure *cl) · 111 unmodified lines | ||
| 145 | 150 | } |
| 146 | 151 | EXPORT_SYMBOL(__closure_sync); |
| 147 | 152 | |
| 153 | +/* | |
| 154 | + * closure_return_sync - finish running a closure, synchronously (i.e. waiting | |
| 155 | + * for outstanding get()s to finish) and returning once closure refcount is 0. | |
| 156 | + * | |
| 157 | + * Unlike closure_sync() this doesn't reinit the ref to 1; subsequent | |
| 158 | + * closure_get_not_zero() calls waill fail. | |
| 159 | + */ | |
| 160 | +void __sched closure_return_sync(struct closure *cl) | |
| 161 | +{ | |
| 162 | + struct closure_syncer s = { .task = current }; | |
| 163 | + | |
| 164 | + cl->s = &s; | |
| 165 | + set_closure_fn(cl, closure_sync_fn, NULL); | |
| 166 | + | |
| 167 | + unsigned flags = atomic_sub_return_release(1 + CLOSURE_RUNNING - CLOSURE_DESTRUCTOR, | |
| 168 | + &cl->remaining); | |
| 169 | + | |
| 170 | + closure_put_after_sub_checks(flags); | |
| 171 | + | |
| 172 | + if (unlikely(flags & CLOSURE_REMAINING_MASK)) { | |
| 173 | + while (1) { | |
| 174 | + set_current_state(TASK_UNINTERRUPTIBLE); | |
| 175 | + if (s.done) | |
| 176 | + break; | |
| 177 | + schedule(); | |
| 178 | + } | |
| 179 | + | |
| 180 | + __set_current_state(TASK_RUNNING); | |
| 181 | + } | |
| 182 | + | |
| 183 | + if (cl->parent) | |
| 184 | + closure_put(cl->parent); | |
| 185 | +} | |
| 186 | +EXPORT_SYMBOL(closure_return_sync); | |
| 187 | + | |
| 148 | 188 | int __sched __closure_sync_timeout(struct closure *cl, unsigned long timeout) |
| 149 | 189 | { |
| 150 | 190 | struct closure_syncer s = { .task = current }; |
| @@ -625,4 +625,5 @@ static struct kunit_suite string_helpers_test_suite = { · 624 unmodified lines | ||
| 625 | 625 | |
| 626 | 626 | kunit_test_suites(&string_helpers_test_suite); |
| 627 | 627 | |
| 628 | +MODULE_DESCRIPTION("Test cases for string helpers module"); | |
| 628 | 629 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -633,4 +633,5 @@ static struct kunit_suite string_test_suite = { · 632 unmodified lines | ||
| 633 | 633 | |
| 634 | 634 | kunit_test_suites(&string_test_suite); |
| 635 | 635 | |
| 636 | +MODULE_DESCRIPTION("Test cases for string functions"); | |
| 636 | 637 | MODULE_LICENSE("GPL v2"); |
| @@ -415,13 +415,20 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc) · 414 unmodified lines | ||
| 415 | 415 | else |
| 416 | 416 | bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE; |
| 417 | 417 | |
| 418 | − if (bg_thresh >= thresh) | |
| 419 | − bg_thresh = thresh / 2; | |
| 420 | 418 | tsk = current; |
| 421 | 419 | if (rt_task(tsk)) { |
| 422 | 420 | bg_thresh += bg_thresh / 4 + global_wb_domain.dirty_limit / 32; |
| 423 | 421 | thresh += thresh / 4 + global_wb_domain.dirty_limit / 32; |
| 424 | 422 | } |
| 423 | + /* | |
| 424 | + * Dirty throttling logic assumes the limits in page units fit into | |
| 425 | + * 32-bits. This gives 16TB dirty limits max which is hopefully enough. | |
| 426 | + */ | |
| 427 | + if (thresh > UINT_MAX) | |
| 428 | + thresh = UINT_MAX; | |
| 429 | + /* This makes sure bg_thresh is within 32-bits as well */ | |
| 430 | + if (bg_thresh >= thresh) | |
| 431 | + bg_thresh = thresh / 2; | |
| 425 | 432 | dtc->thresh = thresh; |
| 426 | 433 | dtc->bg_thresh = bg_thresh; |
| 427 | 434 | |
| @@ -471,7 +478,11 @@ static unsigned long node_dirty_limit(struct pglist_data *pgdat) · 43 unmodified lines | ||
| 471 | 478 | if (rt_task(tsk)) |
| 472 | 479 | dirty += dirty / 4; |
| 473 | 480 | |
| 474 | − return dirty; | |
| 481 | + /* | |
| 482 | + * Dirty throttling logic assumes the limits in page units fit into | |
| 483 | + * 32-bits. This gives 16TB dirty limits max which is hopefully enough. | |
| 484 | + */ | |
| 485 | + return min_t(unsigned long, dirty, UINT_MAX); | |
| 475 | 486 | } |
| 476 | 487 | |
| 477 | 488 | /** |
| @@ -508,10 +519,17 @@ static int dirty_background_bytes_handler(struct ctl_table *table, int write, · 30 unmodified lines | ||
| 508 | 519 | void *buffer, size_t *lenp, loff_t *ppos) |
| 509 | 520 | { |
| 510 | 521 | int ret; |
| 522 | + unsigned long old_bytes = dirty_background_bytes; | |
| 511 | 523 | |
| 512 | 524 | ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); |
| 513 | − if (ret == 0 && write) | |
| 525 | + if (ret == 0 && write) { | |
| 526 | + if (DIV_ROUND_UP(dirty_background_bytes, PAGE_SIZE) > | |
| 527 | + UINT_MAX) { | |
| 528 | + dirty_background_bytes = old_bytes; | |
| 529 | + return -ERANGE; | |
| 530 | + } | |
| 514 | 531 | dirty_background_ratio = 0; |
| 532 | + } | |
| 515 | 533 | return ret; |
| 516 | 534 | } |
| 517 | 535 | |
| @@ -537,6 +555,10 @@ static int dirty_bytes_handler(struct ctl_table *table, int write, · 19 unmodified lines | ||
| 537 | 555 | |
| 538 | 556 | ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); |
| 539 | 557 | if (ret == 0 && write && vm_dirty_bytes != old_bytes) { |
| 558 | + if (DIV_ROUND_UP(vm_dirty_bytes, PAGE_SIZE) > UINT_MAX) { | |
| 559 | + vm_dirty_bytes = old_bytes; | |
| 560 | + return -ERANGE; | |
| 561 | + } | |
| 540 | 562 | writeback_set_ratelimit(); |
| 541 | 563 | vm_dirty_ratio = 0; |
| 542 | 564 | } |
| @@ -1660,7 +1682,7 @@ static inline void wb_dirty_limits(struct dirty_throttle_control *dtc) · 1117 unmodified lines | ||
| 1660 | 1682 | */ |
| 1661 | 1683 | dtc->wb_thresh = __wb_calc_thresh(dtc, dtc->thresh); |
| 1662 | 1684 | dtc->wb_bg_thresh = dtc->thresh ? |
| 1663 | − div64_u64(dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0; | |
| 1685 | + div_u64((u64)dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0; | |
| 1664 | 1686 | |
| 1665 | 1687 | /* |
| 1666 | 1688 | * In order to avoid the stacked BDI deadlock we need |
| @@ -899,8 +899,8 @@ static int hci_conn_hash_alloc_unset(struct hci_dev *hdev) · 898 unmodified lines | ||
| 899 | 899 | U16_MAX, GFP_ATOMIC); |
| 900 | 900 | } |
| 901 | 901 | |
| 902 | −struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, | |
| 903 | − u8 role, u16 handle) | |
| 902 | +static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, | |
| 903 | + u8 role, u16 handle) | |
| 904 | 904 | { |
| 905 | 905 | struct hci_conn *conn; |
| 906 | 906 | |
| @@ -1041,7 +1041,16 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type, · 134 unmodified lines | ||
| 1041 | 1041 | if (unlikely(handle < 0)) |
| 1042 | 1042 | return ERR_PTR(-ECONNREFUSED); |
| 1043 | 1043 | |
| 1044 | − return hci_conn_add(hdev, type, dst, role, handle); | |
| 1044 | + return __hci_conn_add(hdev, type, dst, role, handle); | |
| 1045 | +} | |
| 1046 | + | |
| 1047 | +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, | |
| 1048 | + u8 role, u16 handle) | |
| 1049 | +{ | |
| 1050 | + if (handle > HCI_CONN_HANDLE_MAX) | |
| 1051 | + return ERR_PTR(-EINVAL); | |
| 1052 | + | |
| 1053 | + return __hci_conn_add(hdev, type, dst, role, handle); | |
| 1045 | 1054 | } |
| 1046 | 1055 | |
| 1047 | 1056 | static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason) |
| @@ -63,50 +63,6 @@ DEFINE_MUTEX(hci_cb_list_lock); · 62 unmodified lines | ||
| 63 | 63 | /* HCI ID Numbering */ |
| 64 | 64 | static DEFINE_IDA(hci_index_ida); |
| 65 | 65 | |
| 66 | −static int hci_scan_req(struct hci_request *req, unsigned long opt) | |
| 67 | −{ | |
| 68 | − __u8 scan = opt; | |
| 69 | − | |
| 70 | − BT_DBG("%s %x", req->hdev->name, scan); | |
| 71 | − | |
| 72 | − /* Inquiry and Page scans */ | |
| 73 | − hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | |
| 74 | − return 0; | |
| 75 | −} | |
| 76 | − | |
| 77 | −static int hci_auth_req(struct hci_request *req, unsigned long opt) | |
| 78 | −{ | |
| 79 | − __u8 auth = opt; | |
| 80 | − | |
| 81 | − BT_DBG("%s %x", req->hdev->name, auth); | |
| 82 | − | |
| 83 | − /* Authentication */ | |
| 84 | − hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); | |
| 85 | − return 0; | |
| 86 | −} | |
| 87 | − | |
| 88 | −static int hci_encrypt_req(struct hci_request *req, unsigned long opt) | |
| 89 | −{ | |
| 90 | − __u8 encrypt = opt; | |
| 91 | − | |
| 92 | − BT_DBG("%s %x", req->hdev->name, encrypt); | |
| 93 | − | |
| 94 | − /* Encryption */ | |
| 95 | − hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); | |
| 96 | − return 0; | |
| 97 | −} | |
| 98 | − | |
| 99 | −static int hci_linkpol_req(struct hci_request *req, unsigned long opt) | |
| 100 | −{ | |
| 101 | − __le16 policy = cpu_to_le16(opt); | |
| 102 | − | |
| 103 | − BT_DBG("%s %x", req->hdev->name, policy); | |
| 104 | − | |
| 105 | − /* Default link policy */ | |
| 106 | − hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); | |
| 107 | − return 0; | |
| 108 | −} | |
| 109 | − | |
| 110 | 66 | /* Get HCI device by index. |
| 111 | 67 | * Device is held on return. */ |
| 112 | 68 | struct hci_dev *hci_dev_get(int index) |
| @@ -735,6 +691,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) · 622 unmodified lines | ||
| 735 | 691 | { |
| 736 | 692 | struct hci_dev *hdev; |
| 737 | 693 | struct hci_dev_req dr; |
| 694 | + __le16 policy; | |
| 738 | 695 | int err = 0; |
| 739 | 696 | |
| 740 | 697 | if (copy_from_user(&dr, arg, sizeof(dr))) |
| @@ -761,8 +718,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) · 20 unmodified lines | ||
| 761 | 718 | |
| 762 | 719 | switch (cmd) { |
| 763 | 720 | case HCISETAUTH: |
| 764 | − err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, | |
| 765 | − HCI_INIT_TIMEOUT, NULL); | |
| 721 | + err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE, | |
| 722 | + 1, &dr.dev_opt, HCI_CMD_TIMEOUT); | |
| 766 | 723 | break; |
| 767 | 724 | |
| 768 | 725 | case HCISETENCRYPT: |
| @@ -773,19 +730,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) · 4 unmodified lines | ||
| 773 | 730 | |
| 774 | 731 | if (!test_bit(HCI_AUTH, &hdev->flags)) { |
| 775 | 732 | /* Auth must be enabled first */ |
| 776 | − err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, | |
| 777 | − HCI_INIT_TIMEOUT, NULL); | |
| 733 | + err = __hci_cmd_sync_status(hdev, | |
| 734 | + HCI_OP_WRITE_AUTH_ENABLE, | |
| 735 | + 1, &dr.dev_opt, | |
| 736 | + HCI_CMD_TIMEOUT); | |
| 778 | 737 | if (err) |
| 779 | 738 | break; |
| 780 | 739 | } |
| 781 | 740 | |
| 782 | − err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, | |
| 783 | − HCI_INIT_TIMEOUT, NULL); | |
| 741 | + err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_ENCRYPT_MODE, | |
| 742 | + 1, &dr.dev_opt, | |
| 743 | + HCI_CMD_TIMEOUT); | |
| 784 | 744 | break; |
| 785 | 745 | |
| 786 | 746 | case HCISETSCAN: |
| 787 | − err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, | |
| 788 | − HCI_INIT_TIMEOUT, NULL); | |
| 747 | + err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE, | |
| 748 | + 1, &dr.dev_opt, | |
| 749 | + HCI_CMD_TIMEOUT); | |
| 789 | 750 | |
| 790 | 751 | /* Ensure that the connectable and discoverable states |
| 791 | 752 | * get correctly modified as this was a non-mgmt change. |
| @@ -795,8 +756,11 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) · 3 unmodified lines | ||
| 795 | 756 | break; |
| 796 | 757 | |
| 797 | 758 | case HCISETLINKPOL: |
| 798 | − err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, | |
| 799 | − HCI_INIT_TIMEOUT, NULL); | |
| 759 | + policy = cpu_to_le16(dr.dev_opt); | |
| 760 | + | |
| 761 | + err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, | |
| 762 | + 2, &policy, | |
| 763 | + HCI_CMD_TIMEOUT); | |
| 800 | 764 | break; |
| 801 | 765 | |
| 802 | 766 | case HCISETLINKMODE: |
| @@ -2751,7 +2715,11 @@ void hci_unregister_dev(struct hci_dev *hdev) · 1948 unmodified lines | ||
| 2751 | 2715 | list_del(&hdev->list); |
| 2752 | 2716 | write_unlock(&hci_dev_list_lock); |
| 2753 | 2717 | |
| 2718 | + cancel_work_sync(&hdev->rx_work); | |
| 2719 | + cancel_work_sync(&hdev->cmd_work); | |
| 2720 | + cancel_work_sync(&hdev->tx_work); | |
| 2754 | 2721 | cancel_work_sync(&hdev->power_on); |
| 2722 | + cancel_work_sync(&hdev->error_reset); | |
| 2755 | 2723 | |
| 2756 | 2724 | hci_cmd_sync_clear(hdev); |
| 2757 | 2725 | |
| @@ -6311,6 +6311,13 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data, · 6310 unmodified lines | ||
| 6311 | 6311 | |
| 6312 | 6312 | evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK; |
| 6313 | 6313 | legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type); |
| 6314 | + | |
| 6315 | + if (test_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, | |
| 6316 | + &hdev->quirks)) { | |
| 6317 | + info->primary_phy &= 0x1f; | |
| 6318 | + info->secondary_phy &= 0x1f; | |
| 6319 | + } | |
| 6320 | + | |
| 6314 | 6321 | if (legacy_evt_type != LE_ADV_INVALID) { |
| 6315 | 6322 | process_adv_report(hdev, legacy_evt_type, &info->bdaddr, |
| 6316 | 6323 | info->bdaddr_type, NULL, 0, |
| @@ -6660,6 +6667,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, · 343 unmodified lines | ||
| 6660 | 6667 | struct bt_iso_qos *qos; |
| 6661 | 6668 | bool pending = false; |
| 6662 | 6669 | u16 handle = __le16_to_cpu(ev->handle); |
| 6670 | + u32 c_sdu_interval, p_sdu_interval; | |
| 6663 | 6671 | |
| 6664 | 6672 | bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); |
| 6665 | 6673 | |
| @@ -6684,12 +6692,25 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, · 18 unmodified lines | ||
| 6684 | 6692 | |
| 6685 | 6693 | pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags); |
| 6686 | 6694 | |
| 6687 | − /* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */ | |
| 6688 | − qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250; | |
| 6689 | − qos->ucast.out.interval = qos->ucast.in.interval; | |
| 6695 | + /* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 6, Part G | |
| 6696 | + * page 3075: | |
| 6697 | + * Transport_Latency_C_To_P = CIG_Sync_Delay + (FT_C_To_P) × | |
| 6698 | + * ISO_Interval + SDU_Interval_C_To_P | |
| 6699 | + * ... | |
| 6700 | + * SDU_Interval = (CIG_Sync_Delay + (FT) x ISO_Interval) - | |
| 6701 | + * Transport_Latency | |
| 6702 | + */ | |
| 6703 | + c_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) + | |
| 6704 | + (ev->c_ft * le16_to_cpu(ev->interval) * 1250)) - | |
| 6705 | + get_unaligned_le24(ev->c_latency); | |
| 6706 | + p_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) + | |
| 6707 | + (ev->p_ft * le16_to_cpu(ev->interval) * 1250)) - | |
| 6708 | + get_unaligned_le24(ev->p_latency); | |
| 6690 | 6709 | |
| 6691 | 6710 | switch (conn->role) { |
| 6692 | 6711 | case HCI_ROLE_SLAVE: |
| 6712 | + qos->ucast.in.interval = c_sdu_interval; | |
| 6713 | + qos->ucast.out.interval = p_sdu_interval; | |
| 6693 | 6714 | /* Convert Transport Latency (us) to Latency (msec) */ |
| 6694 | 6715 | qos->ucast.in.latency = |
| 6695 | 6716 | DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency), |
| @@ -6703,6 +6724,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, · 7 unmodified lines | ||
| 6703 | 6724 | qos->ucast.out.phy = ev->p_phy; |
| 6704 | 6725 | break; |
| 6705 | 6726 | case HCI_ROLE_MASTER: |
| 6727 | + qos->ucast.in.interval = p_sdu_interval; | |
| 6728 | + qos->ucast.out.interval = c_sdu_interval; | |
| 6706 | 6729 | /* Convert Transport Latency (us) to Latency (msec) */ |
| 6707 | 6730 | qos->ucast.out.latency = |
| 6708 | 6731 | DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency), |
| @@ -6893,6 +6916,10 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, · 184 unmodified lines | ||
| 6893 | 6916 | |
| 6894 | 6917 | bis = hci_conn_hash_lookup_handle(hdev, handle); |
| 6895 | 6918 | if (!bis) { |
| 6919 | + if (handle > HCI_CONN_HANDLE_MAX) { | |
| 6920 | + bt_dev_dbg(hdev, "ignore too large handle %u", handle); | |
| 6921 | + continue; | |
| 6922 | + } | |
| 6896 | 6923 | bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, |
| 6897 | 6924 | HCI_ROLE_SLAVE, handle); |
| 6898 | 6925 | if (IS_ERR(bis)) |
| @@ -280,6 +280,19 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen, · 279 unmodified lines | ||
| 280 | 280 | } |
| 281 | 281 | EXPORT_SYMBOL(__hci_cmd_sync_status); |
| 282 | 282 | |
| 283 | +int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen, | |
| 284 | + const void *param, u32 timeout) | |
| 285 | +{ | |
| 286 | + int err; | |
| 287 | + | |
| 288 | + hci_req_sync_lock(hdev); | |
| 289 | + err = __hci_cmd_sync_status(hdev, opcode, plen, param, timeout); | |
| 290 | + hci_req_sync_unlock(hdev); | |
| 291 | + | |
| 292 | + return err; | |
| 293 | +} | |
| 294 | +EXPORT_SYMBOL(hci_cmd_sync_status); | |
| 295 | + | |
| 283 | 296 | static void hci_cmd_sync_work(struct work_struct *work) |
| 284 | 297 | { |
| 285 | 298 | struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work); |
| @@ -1356,8 +1356,7 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg, · 1355 unmodified lines | ||
| 1356 | 1356 | lock_sock(sk); |
| 1357 | 1357 | switch (sk->sk_state) { |
| 1358 | 1358 | case BT_CONNECT2: |
| 1359 | − if (pi->conn->hcon && | |
| 1360 | − test_bit(HCI_CONN_PA_SYNC, &pi->conn->hcon->flags)) { | |
| 1359 | + if (test_bit(BT_SK_PA_SYNC, &pi->flags)) { | |
| 1361 | 1360 | iso_conn_big_sync(sk); |
| 1362 | 1361 | sk->sk_state = BT_LISTEN; |
| 1363 | 1362 | } else { |
| @@ -6761,6 +6761,8 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, · 6760 unmodified lines | ||
| 6761 | 6761 | |
| 6762 | 6762 | BT_DBG("chan %p, len %d", chan, skb->len); |
| 6763 | 6763 | |
| 6764 | + l2cap_chan_lock(chan); | |
| 6765 | + | |
| 6764 | 6766 | if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) |
| 6765 | 6767 | goto drop; |
| 6766 | 6768 | |
| @@ -6777,6 +6779,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, · 10 unmodified lines | ||
| 6777 | 6779 | } |
| 6778 | 6780 | |
| 6779 | 6781 | drop: |
| 6782 | + l2cap_chan_unlock(chan); | |
| 6780 | 6783 | l2cap_chan_put(chan); |
| 6781 | 6784 | free_skb: |
| 6782 | 6785 | kfree_skb(skb); |
| @@ -1239,6 +1239,10 @@ static void l2cap_sock_kill(struct sock *sk) · 1238 unmodified lines | ||
| 1239 | 1239 | |
| 1240 | 1240 | BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); |
| 1241 | 1241 | |
| 1242 | + /* Sock is dead, so set chan data to NULL, avoid other task use invalid | |
| 1243 | + * sock pointer. | |
| 1244 | + */ | |
| 1245 | + l2cap_pi(sk)->chan->data = NULL; | |
| 1242 | 1246 | /* Kill poor orphan */ |
| 1243 | 1247 | |
| 1244 | 1248 | l2cap_chan_put(l2cap_pi(sk)->chan); |
| @@ -1481,12 +1485,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) · 236 unmodified lines | ||
| 1481 | 1485 | |
| 1482 | 1486 | static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) |
| 1483 | 1487 | { |
| 1484 | − struct sock *sk = chan->data; | |
| 1485 | − struct l2cap_pinfo *pi = l2cap_pi(sk); | |
| 1488 | + struct sock *sk; | |
| 1489 | + struct l2cap_pinfo *pi; | |
| 1486 | 1490 | int err; |
| 1487 | 1491 | |
| 1488 | − lock_sock(sk); | |
| 1492 | + sk = chan->data; | |
| 1493 | + if (!sk) | |
| 1494 | + return -ENXIO; | |
| 1489 | 1495 | |
| 1496 | + pi = l2cap_pi(sk); | |
| 1497 | + lock_sock(sk); | |
| 1490 | 1498 | if (chan->mode == L2CAP_MODE_ERTM && !list_empty(&pi->rx_busy)) { |
| 1491 | 1499 | err = -ENOMEM; |
| 1492 | 1500 | goto done; |
| @@ -416,15 +416,22 @@ static int __skb_datagram_iter(const struct sk_buff *skb, int offset, · 415 unmodified lines | ||
| 416 | 416 | |
| 417 | 417 | end = start + skb_frag_size(frag); |
| 418 | 418 | if ((copy = end - offset) > 0) { |
| 419 | − struct page *page = skb_frag_page(frag); | |
| 420 | − u8 *vaddr = kmap(page); | |
| 419 | + u32 p_off, p_len, copied; | |
| 420 | + struct page *p; | |
| 421 | + u8 *vaddr; | |
| 421 | 422 | |
| 422 | 423 | if (copy > len) |
| 423 | 424 | copy = len; |
| 424 | − n = INDIRECT_CALL_1(cb, simple_copy_to_iter, | |
| 425 | − vaddr + skb_frag_off(frag) + offset - start, | |
| 426 | − copy, data, to); | |
| 427 | − kunmap(page); | |
| 425 | + | |
| 426 | + skb_frag_foreach_page(frag, | |
| 427 | + skb_frag_off(frag) + offset - start, | |
| 428 | + copy, p, p_off, p_len, copied) { | |
| 429 | + vaddr = kmap_local_page(p); | |
| 430 | + n = INDIRECT_CALL_1(cb, simple_copy_to_iter, | |
| 431 | + vaddr + p_off, p_len, data, to); | |
| 432 | + kunmap_local(vaddr); | |
| 433 | + } | |
| 434 | + | |
| 428 | 435 | offset += n; |
| 429 | 436 | if (n != copy) |
| 430 | 437 | goto short_copy; |
| @@ -1383,6 +1383,7 @@ static int inet_diag_dump_compat(struct sk_buff *skb, · 1382 unmodified lines | ||
| 1383 | 1383 | req.sdiag_family = AF_UNSPEC; /* compatibility */ |
| 1384 | 1384 | req.sdiag_protocol = inet_diag_type2proto(cb->nlh->nlmsg_type); |
| 1385 | 1385 | req.idiag_ext = rc->idiag_ext; |
| 1386 | + req.pad = 0; | |
| 1386 | 1387 | req.idiag_states = rc->idiag_states; |
| 1387 | 1388 | req.id = rc->id; |
| 1388 | 1389 | |
| @@ -1398,6 +1399,7 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb, · 9 unmodified lines | ||
| 1398 | 1399 | req.sdiag_family = rc->idiag_family; |
| 1399 | 1400 | req.sdiag_protocol = inet_diag_type2proto(nlh->nlmsg_type); |
| 1400 | 1401 | req.idiag_ext = rc->idiag_ext; |
| 1402 | + req.pad = 0; | |
| 1401 | 1403 | req.idiag_states = rc->idiag_states; |
| 1402 | 1404 | req.id = rc->id; |
| 1403 | 1405 | |
| @@ -3077,7 +3077,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una, · 3076 unmodified lines | ||
| 3077 | 3077 | return; |
| 3078 | 3078 | |
| 3079 | 3079 | if (tcp_try_undo_dsack(sk)) |
| 3080 | − tcp_try_keep_open(sk); | |
| 3080 | + tcp_try_to_open(sk, flag); | |
| 3081 | 3081 | |
| 3082 | 3082 | tcp_identify_packet_loss(sk, ack_flag); |
| 3083 | 3083 | if (icsk->icsk_ca_state != TCP_CA_Recovery) { |
| @@ -4227,6 +4227,13 @@ void tcp_parse_options(const struct net *net, · 1143 unmodified lines | ||
| 4227 | 4227 | * checked (see tcp_v{4,6}_rcv()). |
| 4228 | 4228 | */ |
| 4229 | 4229 | break; |
| 4230 | +#endif | |
| 4231 | +#ifdef CONFIG_TCP_AO | |
| 4232 | + case TCPOPT_AO: | |
| 4233 | + /* TCP AO has already been checked | |
| 4234 | + * (see tcp_inbound_ao_hash()). | |
| 4235 | + */ | |
| 4236 | + break; | |
| 4230 | 4237 | #endif |
| 4231 | 4238 | case TCPOPT_FASTOPEN: |
| 4232 | 4239 | tcp_parse_fastopen_option( |
| @@ -619,6 +619,7 @@ static const struct nla_policy tcp_metrics_nl_policy[TCP_METRICS_ATTR_MAX + 1] = · 618 unmodified lines | ||
| 619 | 619 | [TCP_METRICS_ATTR_ADDR_IPV4] = { .type = NLA_U32, }, |
| 620 | 620 | [TCP_METRICS_ATTR_ADDR_IPV6] = { .type = NLA_BINARY, |
| 621 | 621 | .len = sizeof(struct in6_addr), }, |
| 622 | + [TCP_METRICS_ATTR_SADDR_IPV4] = { .type = NLA_U32, }, | |
| 622 | 623 | /* Following attributes are not received for GET/DEL, |
| 623 | 624 | * we keep them for reference |
| 624 | 625 | */ |
| @@ -161,8 +161,10 @@ void ieee802154_configure_durations(struct wpan_phy *phy, · 160 unmodified lines | ||
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | phy->symbol_duration = duration; |
| 164 | − phy->lifs_period = (IEEE802154_LIFS_PERIOD * phy->symbol_duration) / NSEC_PER_SEC; | |
| 165 | − phy->sifs_period = (IEEE802154_SIFS_PERIOD * phy->symbol_duration) / NSEC_PER_SEC; | |
| 164 | + phy->lifs_period = | |
| 165 | + (IEEE802154_LIFS_PERIOD * phy->symbol_duration) / NSEC_PER_USEC; | |
| 166 | + phy->sifs_period = | |
| 167 | + (IEEE802154_SIFS_PERIOD * phy->symbol_duration) / NSEC_PER_USEC; | |
| 166 | 168 | } |
| 167 | 169 | EXPORT_SYMBOL(ieee802154_configure_durations); |
| 168 | 170 | |
| @@ -184,10 +186,10 @@ static void ieee802154_setup_wpan_phy_pib(struct wpan_phy *wpan_phy) · 15 unmodified lines | ||
| 184 | 186 | * Should be done when all drivers sets this value. |
| 185 | 187 | */ |
| 186 | 188 | |
| 187 | − wpan_phy->lifs_period = | |
| 188 | − (IEEE802154_LIFS_PERIOD * wpan_phy->symbol_duration) / 1000; | |
| 189 | − wpan_phy->sifs_period = | |
| 190 | − (IEEE802154_SIFS_PERIOD * wpan_phy->symbol_duration) / 1000; | |
| 189 | + wpan_phy->lifs_period = (IEEE802154_LIFS_PERIOD * | |
| 190 | + wpan_phy->symbol_duration) / NSEC_PER_USEC; | |
| 191 | + wpan_phy->sifs_period = (IEEE802154_SIFS_PERIOD * | |
| 192 | + wpan_phy->symbol_duration) / NSEC_PER_USEC; | |
| 191 | 193 | } |
| 192 | 194 | |
| 193 | 195 | int ieee802154_register_hw(struct ieee802154_hw *hw) |
| @@ -34,8 +34,8 @@ void ieee802154_xmit_sync_worker(struct work_struct *work) · 33 unmodified lines | ||
| 34 | 34 | if (res) |
| 35 | 35 | goto err_tx; |
| 36 | 36 | |
| 37 | − dev->stats.tx_packets++; | |
| 38 | − dev->stats.tx_bytes += skb->len; | |
| 37 | + DEV_STATS_INC(dev, tx_packets); | |
| 38 | + DEV_STATS_ADD(dev, tx_bytes, skb->len); | |
| 39 | 39 | |
| 40 | 40 | ieee802154_xmit_complete(&local->hw, skb, false); |
| 41 | 41 | |
| @@ -90,8 +90,8 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) · 48 unmodified lines | ||
| 90 | 90 | if (ret) |
| 91 | 91 | goto err_wake_netif_queue; |
| 92 | 92 | |
| 93 | − dev->stats.tx_packets++; | |
| 94 | − dev->stats.tx_bytes += len; | |
| 93 | + DEV_STATS_INC(dev, tx_packets); | |
| 94 | + DEV_STATS_ADD(dev, tx_bytes, len); | |
| 95 | 95 | } else { |
| 96 | 96 | local->tx_skb = skb; |
| 97 | 97 | queue_work(local->workqueue, &local->sync_tx_work); |
| @@ -11552,8 +11552,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, · 11551 unmodified lines | ||
| 11552 | 11552 | |
| 11553 | 11553 | gc_seq = nft_gc_seq_begin(nft_net); |
| 11554 | 11554 | |
| 11555 | − if (!list_empty(&nf_tables_destroy_list)) | |
| 11556 | − nf_tables_trans_destroy_flush_work(); | |
| 11555 | + nf_tables_trans_destroy_flush_work(); | |
| 11557 | 11556 | again: |
| 11558 | 11557 | list_for_each_entry(table, &nft_net->tables, list) { |
| 11559 | 11558 | if (nft_table_has_owner(table) && |
| @@ -1557,9 +1557,11 @@ out_drop: · 1556 unmodified lines | ||
| 1557 | 1557 | */ |
| 1558 | 1558 | void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp) |
| 1559 | 1559 | { |
| 1560 | + struct rpc_timeout timeout = { | |
| 1561 | + .to_increment = 0, | |
| 1562 | + }; | |
| 1560 | 1563 | struct rpc_task *task; |
| 1561 | 1564 | int proc_error; |
| 1562 | − struct rpc_timeout timeout; | |
| 1563 | 1565 | |
| 1564 | 1566 | /* Build the svc_rqst used by the common processing routine */ |
| 1565 | 1567 | rqstp->rq_xid = req->rq_xid; |
| @@ -1612,6 +1614,7 @@ void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp) · 46 unmodified lines | ||
| 1612 | 1614 | timeout.to_initval = req->rq_xprt->timeout->to_initval; |
| 1613 | 1615 | timeout.to_retries = req->rq_xprt->timeout->to_retries; |
| 1614 | 1616 | } |
| 1617 | + timeout.to_maxval = timeout.to_initval; | |
| 1615 | 1618 | memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf)); |
| 1616 | 1619 | task = rpc_run_bc_task(req, &timeout); |
| 1617 | 1620 | |
| @@ -1421,13 +1421,12 @@ static void *svc_pool_stats_start(struct seq_file *m, loff_t *pos) · 1420 unmodified lines | ||
| 1421 | 1421 | |
| 1422 | 1422 | dprintk("svc_pool_stats_start, *pidx=%u\n", pidx); |
| 1423 | 1423 | |
| 1424 | − if (!si->serv) | |
| 1425 | − return NULL; | |
| 1426 | − | |
| 1427 | 1424 | mutex_lock(si->mutex); |
| 1428 | 1425 | |
| 1429 | 1426 | if (!pidx) |
| 1430 | 1427 | return SEQ_START_TOKEN; |
| 1428 | + if (!si->serv) | |
| 1429 | + return NULL; | |
| 1431 | 1430 | return pidx > si->serv->sv_nrpools ? NULL |
| 1432 | 1431 | : &si->serv->sv_pools[pidx - 1]; |
| 1433 | 1432 | } |
| @@ -1459,8 +1458,7 @@ static void svc_pool_stats_stop(struct seq_file *m, void *p) · 25 unmodified lines | ||
| 1459 | 1458 | { |
| 1460 | 1459 | struct svc_info *si = m->private; |
| 1461 | 1460 | |
| 1462 | − if (si->serv) | |
| 1463 | − mutex_unlock(si->mutex); | |
| 1461 | + mutex_unlock(si->mutex); | |
| 1464 | 1462 | } |
| 1465 | 1463 | |
| 1466 | 1464 | static int svc_pool_stats_show(struct seq_file *m, void *p) |
| @@ -470,6 +470,7 @@ prev_vertex: · 469 unmodified lines | ||
| 470 | 470 | } |
| 471 | 471 | |
| 472 | 472 | if (vertex->index == vertex->scc_index) { |
| 473 | + struct unix_vertex *v; | |
| 473 | 474 | struct list_head scc; |
| 474 | 475 | bool scc_dead = true; |
| 475 | 476 | |
| @@ -480,15 +481,15 @@ prev_vertex: · 4 unmodified lines | ||
| 480 | 481 | */ |
| 481 | 482 | __list_cut_position(&scc, &vertex_stack, &vertex->scc_entry); |
| 482 | 483 | |
| 483 | − list_for_each_entry_reverse(vertex, &scc, scc_entry) { | |
| 484 | + list_for_each_entry_reverse(v, &scc, scc_entry) { | |
| 484 | 485 | /* Don't restart DFS from this vertex in unix_walk_scc(). */ |
| 485 | − list_move_tail(&vertex->entry, &unix_visited_vertices); | |
| 486 | + list_move_tail(&v->entry, &unix_visited_vertices); | |
| 486 | 487 | |
| 487 | 488 | /* Mark vertex as off-stack. */ |
| 488 | − vertex->index = unix_vertex_grouped_index; | |
| 489 | + v->index = unix_vertex_grouped_index; | |
| 489 | 490 | |
| 490 | 491 | if (scc_dead) |
| 491 | − scc_dead = unix_vertex_dead(vertex); | |
| 492 | + scc_dead = unix_vertex_dead(v); | |
| 492 | 493 | } |
| 493 | 494 | |
| 494 | 495 | if (scc_dead) |
| @@ -17,7 +17,7 @@ include $(srctree)/scripts/Kbuild.include · 16 unmodified lines | ||
| 17 | 17 | dst := $(INSTALL_DTBS_PATH) |
| 18 | 18 | |
| 19 | 19 | quiet_cmd_dtb_install = INSTALL $@ |
| 20 | − cmd_dtb_install = install -D $< $@ | |
| 20 | + cmd_dtb_install = install -D -m 0644 $< $@ | |
| 21 | 21 | |
| 22 | 22 | $(dst)/%: $(obj)/% |
| 23 | 23 | $(call cmd,dtb_install) |
| @@ -146,7 +146,7 @@ $(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs) · 145 unmodified lines | ||
| 146 | 146 | # Create .o file from a single .cc (C++) file |
| 147 | 147 | quiet_cmd_host-cxxobjs = HOSTCXX $@ |
| 148 | 148 | cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $< |
| 149 | −$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE | |
| 149 | +$(host-cxxobjs): $(obj)/%.o: $(obj)/%.cc FORCE | |
| 150 | 150 | $(call if_changed_dep,host-cxxobjs) |
| 151 | 151 | |
| 152 | 152 | # Create executable from a single Rust crate (which may consist of |
| @@ -103,7 +103,7 @@ debian-orig: private version = $(shell dpkg-parsechangelog -S Version | sed 's/- · 102 unmodified lines | ||
| 103 | 103 | debian-orig: private orig-name = $(source)_$(version).orig.tar$(debian-orig-suffix) |
| 104 | 104 | debian-orig: mkdebian-opts = --need-source |
| 105 | 105 | debian-orig: linux.tar$(debian-orig-suffix) debian |
| 106 | − $(Q)if [ "$(df --output=target .. 2>/dev/null)" = "$(df --output=target $< 2>/dev/null)" ]; then \ | |
| 106 | + $(Q)if [ "$$(df --output=target .. 2>/dev/null)" = "$$(df --output=target $< 2>/dev/null)" ]; then \ | |
| 107 | 107 | ln -f $< ../$(orig-name); \ |
| 108 | 108 | else \ |
| 109 | 109 | cp $< ../$(orig-name); \ |
| @@ -5,7 +5,7 @@ ifdef building_out_of_srctree · 4 unmodified lines | ||
| 5 | 5 | symlinks := $(patsubst $(src)/%,%,$(wildcard $(src)/*.py)) |
| 6 | 6 | |
| 7 | 7 | quiet_cmd_symlink = SYMLINK $@ |
| 8 | − cmd_symlink = ln -fsn $(patsubst $(obj)/%,$(src)/%,$@) $@ | |
| 8 | + cmd_symlink = ln -fsn $(patsubst $(obj)/%,$(abspath $(src))/%,$@) $@ | |
| 9 | 9 | |
| 10 | 10 | always-y += $(symlinks) |
| 11 | 11 | $(addprefix $(obj)/, $(symlinks)): FORCE |
| @@ -57,7 +57,8 @@ patch -p1 < %{SOURCE2} · 56 unmodified lines | ||
| 57 | 57 | %install |
| 58 | 58 | mkdir -p %{buildroot}/lib/modules/%{KERNELRELEASE} |
| 59 | 59 | cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEASE}/vmlinuz |
| 60 | −%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} modules_install | |
| 60 | +# DEPMOD=true makes depmod no-op. We do not package depmod-generated files. | |
| 61 | +%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} DEPMOD=true modules_install | |
| 61 | 62 | %{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install |
| 62 | 63 | cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE} |
| 63 | 64 | cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config |
| @@ -70,10 +71,7 @@ ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEA · 6 unmodified lines | ||
| 70 | 71 | %endif |
| 71 | 72 | |
| 72 | 73 | { |
| 73 | − for x in System.map config kernel modules.builtin \ | |
| 74 | − modules.builtin.modinfo modules.order vmlinuz; do | |
| 75 | − echo "/lib/modules/%{KERNELRELEASE}/${x}" | |
| 76 | − done | |
| 74 | + echo "/lib/modules/%{KERNELRELEASE}" | |
| 77 | 75 | |
| 78 | 76 | for x in alias alias.bin builtin.alias.bin builtin.bin dep dep.bin \ |
| 79 | 77 | devname softdep symbols symbols.bin; do |
| @@ -14,6 +14,7 @@ turbostat : turbostat.c · 13 unmodified lines | ||
| 14 | 14 | override CFLAGS += -O2 -Wall -Wextra -I../../../include |
| 15 | 15 | override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' |
| 16 | 16 | override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' |
| 17 | +override CFLAGS += -DBUILD_BUG_HEADER='"../../../../include/linux/build_bug.h"' | |
| 17 | 18 | override CFLAGS += -D_FILE_OFFSET_BITS=64 |
| 18 | 19 | override CFLAGS += -D_FORTIFY_SOURCE=2 |
| 19 | 20 | |
| @@ -44,10 +45,13 @@ snapshot: turbostat · 24 unmodified lines | ||
| 44 | 45 | @echo "#define GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (sizeof(long) * 8 - 1 - (h))))" >> $(SNAPSHOT)/bits.h |
| 45 | 46 | @echo "#define GENMASK_ULL(h, l) (((~0ULL) << (l)) & (~0ULL >> (sizeof(long long) * 8 - 1 - (h))))" >> $(SNAPSHOT)/bits.h |
| 46 | 47 | |
| 48 | + @echo '#define BUILD_BUG_ON(cond) do { enum { compile_time_check ## __COUNTER__ = 1/(!(cond)) }; } while (0)' > $(SNAPSHOT)/build_bug.h | |
| 49 | + | |
| 47 | 50 | @echo PWD=. > $(SNAPSHOT)/Makefile |
| 48 | 51 | @echo "CFLAGS += -DMSRHEADER='\"msr-index.h\"'" >> $(SNAPSHOT)/Makefile |
| 49 | 52 | @echo "CFLAGS += -DINTEL_FAMILY_HEADER='\"intel-family.h\"'" >> $(SNAPSHOT)/Makefile |
| 50 | − @sed -e's/.*MSRHEADER.*//' -e's/.*INTEL_FAMILY_HEADER.*//' Makefile >> $(SNAPSHOT)/Makefile | |
| 53 | + @echo "CFLAGS += -DBUILD_BUG_HEADER='\"build_bug.h\"'" >> $(SNAPSHOT)/Makefile | |
| 54 | + @sed -e's/.*MSRHEADER.*//' -e's/.*INTEL_FAMILY_HEADER.*//' -e's/.*BUILD_BUG_HEADER.*//' Makefile >> $(SNAPSHOT)/Makefile | |
| 51 | 55 | |
| 52 | 56 | @rm -f $(SNAPSHOT).tar.gz |
| 53 | 57 | tar cvzf $(SNAPSHOT).tar.gz $(SNAPSHOT) |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #define _GNU_SOURCE |
| 11 | 11 | #include MSRHEADER |
| 12 | 12 | #include INTEL_FAMILY_HEADER |
| 13 | +#include BUILD_BUG_HEADER | |
| 13 | 14 | #include <stdarg.h> |
| 14 | 15 | #include <stdio.h> |
| 15 | 16 | #include <err.h> |
| @@ -38,7 +39,6 @@ · 22 unmodified lines | ||
| 38 | 39 | #include <stdbool.h> |
| 39 | 40 | #include <assert.h> |
| 40 | 41 | #include <linux/kernel.h> |
| 41 | −#include <linux/build_bug.h> | |
| 42 | 42 | |
| 43 | 43 | #define UNUSED(x) (void)(x) |
| 44 | 44 | |
| @@ -5695,9 +5695,6 @@ static void probe_intel_uncore_frequency_cluster(void) · 5650 unmodified lines | ||
| 5695 | 5695 | if (access("/sys/devices/system/cpu/intel_uncore_frequency/uncore00/current_freq_khz", R_OK)) |
| 5696 | 5696 | return; |
| 5697 | 5697 | |
| 5698 | − if (quiet) | |
| 5699 | − return; | |
| 5700 | − | |
| 5701 | 5698 | for (uncore_max_id = 0;; ++uncore_max_id) { |
| 5702 | 5699 | |
| 5703 | 5700 | sprintf(path_base, "/sys/devices/system/cpu/intel_uncore_frequency/uncore%02d", uncore_max_id); |
| @@ -5727,6 +5724,14 @@ static void probe_intel_uncore_frequency_cluster(void) · 23 unmodified lines | ||
| 5727 | 5724 | sprintf(path, "%s/fabric_cluster_id", path_base); |
| 5728 | 5725 | cluster_id = read_sysfs_int(path); |
| 5729 | 5726 | |
| 5727 | + sprintf(path, "%s/current_freq_khz", path_base); | |
| 5728 | + sprintf(name_buf, "UMHz%d.%d", domain_id, cluster_id); | |
| 5729 | + | |
| 5730 | + add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id); | |
| 5731 | + | |
| 5732 | + if (quiet) | |
| 5733 | + continue; | |
| 5734 | + | |
| 5730 | 5735 | sprintf(path, "%s/min_freq_khz", path_base); |
| 5731 | 5736 | k = read_sysfs_int(path); |
| 5732 | 5737 | sprintf(path, "%s/max_freq_khz", path_base); |
| @@ -5743,11 +5748,6 @@ static void probe_intel_uncore_frequency_cluster(void) · 10 unmodified lines | ||
| 5743 | 5748 | sprintf(path, "%s/current_freq_khz", path_base); |
| 5744 | 5749 | k = read_sysfs_int(path); |
| 5745 | 5750 | fprintf(outf, " %d MHz\n", k / 1000); |
| 5746 | − | |
| 5747 | − sprintf(path, "%s/current_freq_khz", path_base); | |
| 5748 | − sprintf(name_buf, "UMHz%d.%d", domain_id, cluster_id); | |
| 5749 | − | |
| 5750 | − add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id); | |
| 5751 | 5751 | } |
| 5752 | 5752 | } |
| 5753 | 5753 | |
| @@ -8424,7 +8424,7 @@ void cmdline(int argc, char **argv) · 2670 unmodified lines | ||
| 8424 | 8424 | * Parse some options early, because they may make other options invalid, |
| 8425 | 8425 | * like adding the MSR counter with --add and at the same time using --no-msr. |
| 8426 | 8426 | */ |
| 8427 | − while ((opt = getopt_long_only(argc, argv, "MP", long_options, &option_index)) != -1) { | |
| 8427 | + while ((opt = getopt_long_only(argc, argv, "MPn:", long_options, &option_index)) != -1) { | |
| 8428 | 8428 | switch (opt) { |
| 8429 | 8429 | case 'M': |
| 8430 | 8430 | no_msr = 1; |
| @@ -630,11 +630,15 @@ static struct cxl_hdm *mock_cxl_setup_hdm(struct cxl_port *port, · 629 unmodified lines | ||
| 630 | 630 | struct cxl_endpoint_dvsec_info *info) |
| 631 | 631 | { |
| 632 | 632 | struct cxl_hdm *cxlhdm = devm_kzalloc(&port->dev, sizeof(*cxlhdm), GFP_KERNEL); |
| 633 | + struct device *dev = &port->dev; | |
| 633 | 634 | |
| 634 | 635 | if (!cxlhdm) |
| 635 | 636 | return ERR_PTR(-ENOMEM); |
| 636 | 637 | |
| 637 | 638 | cxlhdm->port = port; |
| 639 | + cxlhdm->interleave_mask = ~0U; | |
| 640 | + cxlhdm->iw_cap_mask = ~0UL; | |
| 641 | + dev_set_drvdata(dev, cxlhdm); | |
| 638 | 642 | return cxlhdm; |
| 639 | 643 | } |
| 640 | 644 | |
| @@ -66,8 +66,6 @@ · 65 unmodified lines | ||
| 66 | 66 | #include <sys/wait.h> |
| 67 | 67 | #include <unistd.h> |
| 68 | 68 | #include <setjmp.h> |
| 69 | −#include <syscall.h> | |
| 70 | −#include <linux/sched.h> | |
| 71 | 69 | |
| 72 | 70 | #include "kselftest.h" |
| 73 | 71 | |
| @@ -82,17 +80,6 @@ · 8 unmodified lines | ||
| 82 | 80 | # define TH_LOG_ENABLED 1 |
| 83 | 81 | #endif |
| 84 | 82 | |
| 85 | −/* Wait for the child process to end but without sharing memory mapping. */ | |
| 86 | −static inline pid_t clone3_vfork(void) | |
| 87 | −{ | |
| 88 | − struct clone_args args = { | |
| 89 | − .flags = CLONE_VFORK, | |
| 90 | − .exit_signal = SIGCHLD, | |
| 91 | − }; | |
| 92 | − | |
| 93 | − return syscall(__NR_clone3, &args, sizeof(args)); | |
| 94 | −} | |
| 95 | − | |
| 96 | 83 | /** |
| 97 | 84 | * TH_LOG() |
| 98 | 85 | * |
| @@ -437,7 +424,7 @@ static inline pid_t clone3_vfork(void) · 338 unmodified lines | ||
| 437 | 424 | } \ |
| 438 | 425 | if (setjmp(_metadata->env) == 0) { \ |
| 439 | 426 | /* _metadata and potentially self are shared with all forks. */ \ |
| 440 | − child = clone3_vfork(); \ | |
| 427 | + child = fork(); \ | |
| 441 | 428 | if (child == 0) { \ |
| 442 | 429 | fixture_name##_setup(_metadata, self, variant->data); \ |
| 443 | 430 | /* Let setup failure terminate early. */ \ |
| @@ -1016,7 +1003,14 @@ void __wait_for_test(struct __test_metadata *t) · 572 unmodified lines | ||
| 1016 | 1003 | .sa_flags = SA_SIGINFO, |
| 1017 | 1004 | }; |
| 1018 | 1005 | struct sigaction saved_action; |
| 1019 | − int status; | |
| 1006 | + /* | |
| 1007 | + * Sets status so that WIFEXITED(status) returns true and | |
| 1008 | + * WEXITSTATUS(status) returns KSFT_FAIL. This safe default value | |
| 1009 | + * should never be evaluated because of the waitpid(2) check and | |
| 1010 | + * SIGALRM handling. | |
| 1011 | + */ | |
| 1012 | + int status = KSFT_FAIL << 8; | |
| 1013 | + int child; | |
| 1020 | 1014 | |
| 1021 | 1015 | if (sigaction(SIGALRM, &action, &saved_action)) { |
| 1022 | 1016 | t->exit_code = KSFT_FAIL; |
| @@ -1028,7 +1022,15 @@ void __wait_for_test(struct __test_metadata *t) · 5 unmodified lines | ||
| 1028 | 1022 | __active_test = t; |
| 1029 | 1023 | t->timed_out = false; |
| 1030 | 1024 | alarm(t->timeout); |
| 1031 | − waitpid(t->pid, &status, 0); | |
| 1025 | + child = waitpid(t->pid, &status, 0); | |
| 1026 | + if (child == -1 && errno != EINTR) { | |
| 1027 | + t->exit_code = KSFT_FAIL; | |
| 1028 | + fprintf(TH_LOG_STREAM, | |
| 1029 | + "# %s: Failed to wait for PID %d (errno: %d)\n", | |
| 1030 | + t->name, t->pid, errno); | |
| 1031 | + return; | |
| 1032 | + } | |
| 1033 | + | |
| 1032 | 1034 | alarm(0); |
| 1033 | 1035 | if (sigaction(SIGALRM, &saved_action, NULL)) { |
| 1034 | 1036 | t->exit_code = KSFT_FAIL; |
| @@ -1083,6 +1085,7 @@ void __wait_for_test(struct __test_metadata *t) · 48 unmodified lines | ||
| 1083 | 1085 | WTERMSIG(status)); |
| 1084 | 1086 | } |
| 1085 | 1087 | } else { |
| 1088 | + t->exit_code = KSFT_FAIL; | |
| 1086 | 1089 | fprintf(TH_LOG_STREAM, |
| 1087 | 1090 | "# %s: Test ended in some other way [%u]\n", |
| 1088 | 1091 | t->name, |
| @@ -1218,6 +1221,7 @@ void __run_test(struct __fixture_metadata *f, · 129 unmodified lines | ||
| 1218 | 1221 | struct __test_xfail *xfail; |
| 1219 | 1222 | char test_name[1024]; |
| 1220 | 1223 | const char *diagnostic; |
| 1224 | + int child; | |
| 1221 | 1225 | |
| 1222 | 1226 | /* reset test struct */ |
| 1223 | 1227 | t->exit_code = KSFT_PASS; |
| @@ -1236,15 +1240,16 @@ void __run_test(struct __fixture_metadata *f, · 12 unmodified lines | ||
| 1236 | 1240 | fflush(stdout); |
| 1237 | 1241 | fflush(stderr); |
| 1238 | 1242 | |
| 1239 | − t->pid = clone3_vfork(); | |
| 1240 | − if (t->pid < 0) { | |
| 1243 | + child = fork(); | |
| 1244 | + if (child < 0) { | |
| 1241 | 1245 | ksft_print_msg("ERROR SPAWNING TEST CHILD\n"); |
| 1242 | 1246 | t->exit_code = KSFT_FAIL; |
| 1243 | − } else if (t->pid == 0) { | |
| 1247 | + } else if (child == 0) { | |
| 1244 | 1248 | setpgrp(); |
| 1245 | 1249 | t->fn(t, variant); |
| 1246 | 1250 | _exit(t->exit_code); |
| 1247 | 1251 | } else { |
| 1252 | + t->pid = child; | |
| 1248 | 1253 | __wait_for_test(t); |
| 1249 | 1254 | } |
| 1250 | 1255 | ksft_print_msg(" %4s %s\n", |
| @@ -14,12 +14,12 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | FIXTURE(scm_rights) |
| 16 | 16 | { |
| 17 | − int fd[16]; | |
| 17 | + int fd[32]; | |
| 18 | 18 | }; |
| 19 | 19 | |
| 20 | 20 | FIXTURE_VARIANT(scm_rights) |
| 21 | 21 | { |
| 22 | − char name[16]; | |
| 22 | + char name[32]; | |
| 23 | 23 | int type; |
| 24 | 24 | int flags; |
| 25 | 25 | bool test_listener; |
| @@ -172,6 +172,8 @@ static void __create_sockets(struct __test_metadata *_metadata, · 146 unmodified lines | ||
| 172 | 172 | const FIXTURE_VARIANT(scm_rights) *variant, |
| 173 | 173 | int n) |
| 174 | 174 | { |
| 175 | + ASSERT_LE(n * 2, sizeof(self->fd) / sizeof(self->fd[0])); | |
| 176 | + | |
| 175 | 177 | if (variant->test_listener) |
| 176 | 178 | create_listeners(_metadata, self, n); |
| 177 | 179 | else |
| @@ -283,4 +285,23 @@ TEST_F(scm_rights, cross_edge) · 105 unmodified lines | ||
| 283 | 285 | close_sockets(8); |
| 284 | 286 | } |
| 285 | 287 | |
| 288 | +TEST_F(scm_rights, backtrack_from_scc) | |
| 289 | +{ | |
| 290 | + create_sockets(10); | |
| 291 | + | |
| 292 | + send_fd(0, 1); | |
| 293 | + send_fd(0, 4); | |
| 294 | + send_fd(1, 2); | |
| 295 | + send_fd(2, 3); | |
| 296 | + send_fd(3, 1); | |
| 297 | + | |
| 298 | + send_fd(5, 6); | |
| 299 | + send_fd(5, 9); | |
| 300 | + send_fd(6, 7); | |
| 301 | + send_fd(7, 8); | |
| 302 | + send_fd(8, 6); | |
| 303 | + | |
| 304 | + close_sockets(10); | |
| 305 | +} | |
| 306 | + | |
| 286 | 307 | TEST_HARNESS_MAIN |
| @@ -85,6 +85,7 @@ static bool cfg_rx; · 84 unmodified lines | ||
| 85 | 85 | static int cfg_runtime_ms = 4200; |
| 86 | 86 | static int cfg_verbose; |
| 87 | 87 | static int cfg_waittime_ms = 500; |
| 88 | +static int cfg_notification_limit = 32; | |
| 88 | 89 | static bool cfg_zerocopy; |
| 89 | 90 | |
| 90 | 91 | static socklen_t cfg_alen; |
| @@ -95,6 +96,7 @@ static char payload[IP_MAXPACKET]; · 4 unmodified lines | ||
| 95 | 96 | static long packets, bytes, completions, expected_completions; |
| 96 | 97 | static int zerocopied = -1; |
| 97 | 98 | static uint32_t next_completion; |
| 99 | +static uint32_t sends_since_notify; | |
| 98 | 100 | |
| 99 | 101 | static unsigned long gettimeofday_ms(void) |
| 100 | 102 | { |
| @@ -208,6 +210,7 @@ static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy, int domain) · 107 unmodified lines | ||
| 208 | 210 | error(1, errno, "send"); |
| 209 | 211 | if (cfg_verbose && ret != len) |
| 210 | 212 | fprintf(stderr, "send: ret=%u != %u\n", ret, len); |
| 213 | + sends_since_notify++; | |
| 211 | 214 | |
| 212 | 215 | if (len) { |
| 213 | 216 | packets++; |
| @@ -435,7 +438,7 @@ static bool do_recv_completion(int fd, int domain) · 221 unmodified lines | ||
| 435 | 438 | /* Detect notification gaps. These should not happen often, if at all. |
| 436 | 439 | * Gaps can occur due to drops, reordering and retransmissions. |
| 437 | 440 | */ |
| 438 | − if (lo != next_completion) | |
| 441 | + if (cfg_verbose && lo != next_completion) | |
| 439 | 442 | fprintf(stderr, "gap: %u..%u does not append to %u\n", |
| 440 | 443 | lo, hi, next_completion); |
| 441 | 444 | next_completion = hi + 1; |
| @@ -460,6 +463,7 @@ static bool do_recv_completion(int fd, int domain) · 18 unmodified lines | ||
| 460 | 463 | static void do_recv_completions(int fd, int domain) |
| 461 | 464 | { |
| 462 | 465 | while (do_recv_completion(fd, domain)) {} |
| 466 | + sends_since_notify = 0; | |
| 463 | 467 | } |
| 464 | 468 | |
| 465 | 469 | /* Wait for all remaining completions on the errqueue */ |
| @@ -549,6 +553,9 @@ static void do_tx(int domain, int type, int protocol) · 83 unmodified lines | ||
| 549 | 553 | else |
| 550 | 554 | do_sendmsg(fd, &msg, cfg_zerocopy, domain); |
| 551 | 555 | |
| 556 | + if (cfg_zerocopy && sends_since_notify >= cfg_notification_limit) | |
| 557 | + do_recv_completions(fd, domain); | |
| 558 | + | |
| 552 | 559 | while (!do_poll(fd, POLLOUT)) { |
| 553 | 560 | if (cfg_zerocopy) |
| 554 | 561 | do_recv_completions(fd, domain); |
| @@ -708,7 +715,7 @@ static void parse_opts(int argc, char **argv) · 153 unmodified lines | ||
| 708 | 715 | |
| 709 | 716 | cfg_payload_len = max_payload_len; |
| 710 | 717 | |
| 711 | − while ((c = getopt(argc, argv, "46c:C:D:i:mp:rs:S:t:vz")) != -1) { | |
| 718 | + while ((c = getopt(argc, argv, "46c:C:D:i:l:mp:rs:S:t:vz")) != -1) { | |
| 712 | 719 | switch (c) { |
| 713 | 720 | case '4': |
| 714 | 721 | if (cfg_family != PF_UNSPEC) |
| @@ -736,6 +743,9 @@ static void parse_opts(int argc, char **argv) · 21 unmodified lines | ||
| 736 | 743 | if (cfg_ifindex == 0) |
| 737 | 744 | error(1, errno, "invalid iface: %s", optarg); |
| 738 | 745 | break; |
| 746 | + case 'l': | |
| 747 | + cfg_notification_limit = strtoul(optarg, NULL, 0); | |
| 748 | + break; | |
| 739 | 749 | case 'm': |
| 740 | 750 | cfg_cork_mixed = true; |
| 741 | 751 | break; |
| @@ -291,11 +291,30 @@ static int cat_run_test(const struct resctrl_test *test, const struct user_param · 290 unmodified lines | ||
| 291 | 291 | return ret; |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | +static bool arch_supports_noncont_cat(const struct resctrl_test *test) | |
| 295 | +{ | |
| 296 | + unsigned int eax, ebx, ecx, edx; | |
| 297 | + | |
| 298 | + /* AMD always supports non-contiguous CBM. */ | |
| 299 | + if (get_vendor() == ARCH_AMD) | |
| 300 | + return true; | |
| 301 | + | |
| 302 | + /* Intel support for non-contiguous CBM needs to be discovered. */ | |
| 303 | + if (!strcmp(test->resource, "L3")) | |
| 304 | + __cpuid_count(0x10, 1, eax, ebx, ecx, edx); | |
| 305 | + else if (!strcmp(test->resource, "L2")) | |
| 306 | + __cpuid_count(0x10, 2, eax, ebx, ecx, edx); | |
| 307 | + else | |
| 308 | + return false; | |
| 309 | + | |
| 310 | + return ((ecx >> 3) & 1); | |
| 311 | +} | |
| 312 | + | |
| 294 | 313 | static int noncont_cat_run_test(const struct resctrl_test *test, |
| 295 | 314 | const struct user_params *uparams) |
| 296 | 315 | { |
| 297 | 316 | unsigned long full_cache_mask, cont_mask, noncont_mask; |
| 298 | − unsigned int eax, ebx, ecx, edx, sparse_masks; | |
| 317 | + unsigned int sparse_masks; | |
| 299 | 318 | int bit_center, ret; |
| 300 | 319 | char schemata[64]; |
| 301 | 320 | |
| @@ -304,15 +323,8 @@ static int noncont_cat_run_test(const struct resctrl_test *test, · 2 unmodified lines | ||
| 304 | 323 | if (ret) |
| 305 | 324 | return ret; |
| 306 | 325 | |
| 307 | − if (!strcmp(test->resource, "L3")) | |
| 308 | − __cpuid_count(0x10, 1, eax, ebx, ecx, edx); | |
| 309 | − else if (!strcmp(test->resource, "L2")) | |
| 310 | − __cpuid_count(0x10, 2, eax, ebx, ecx, edx); | |
| 311 | − else | |
| 312 | − return -EINVAL; | |
| 313 | − | |
| 314 | − if (sparse_masks != ((ecx >> 3) & 1)) { | |
| 315 | − ksft_print_msg("CPUID output doesn't match 'sparse_masks' file content!\n"); | |
| 326 | + if (arch_supports_noncont_cat(test) != sparse_masks) { | |
| 327 | + ksft_print_msg("Hardware and kernel differ on non-contiguous CBM support!\n"); | |
| 316 | 328 | return 1; |
| 317 | 329 | } |
| 318 | 330 | |