diff options
author | David S. Miller <davem@davemloft.net> | 2014-08-23 14:12:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-23 14:12:08 -0400 |
commit | f9474ddfaa009ead12bba44fa8fd49dc4536a124 (patch) | |
tree | a1738a74ac909d84cc80af674d7c0b78af10a413 | |
parent | 989e04c5bc3ff77d65e1f0d87bf7904dfa30d41c (diff) | |
parent | a45e92a599e77ee6a850eabdd0141633fde03915 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pulling to get some TIPC fixes that a net-next series depends
upon.
Signed-off-by: David S. Miller <davem@davemloft.net>
230 files changed, 4691 insertions, 1852 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 1d3756d3176c..bacefc5b222e 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
@@ -315,7 +315,7 @@ char *date;</synopsis> | |||
315 | <function>drm_dev_unregister()</function> followed by a call to | 315 | <function>drm_dev_unregister()</function> followed by a call to |
316 | <function>drm_dev_unref()</function>. | 316 | <function>drm_dev_unref()</function>. |
317 | </para> | 317 | </para> |
318 | !Edrivers/gpu/drm/drm_stub.c | 318 | !Edrivers/gpu/drm/drm_drv.c |
319 | </sect2> | 319 | </sect2> |
320 | <sect2> | 320 | <sect2> |
321 | <title>Driver Load</title> | 321 | <title>Driver Load</title> |
diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt index 1486497a24c1..ce6a1a072028 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | |||
@@ -4,11 +4,13 @@ Specifying interrupt information for devices | |||
4 | 1) Interrupt client nodes | 4 | 1) Interrupt client nodes |
5 | ------------------------- | 5 | ------------------------- |
6 | 6 | ||
7 | Nodes that describe devices which generate interrupts must contain an either an | 7 | Nodes that describe devices which generate interrupts must contain an |
8 | "interrupts" property or an "interrupts-extended" property. These properties | 8 | "interrupts" property, an "interrupts-extended" property, or both. If both are |
9 | contain a list of interrupt specifiers, one per output interrupt. The format of | 9 | present, the latter should take precedence; the former may be provided simply |
10 | the interrupt specifier is determined by the interrupt controller to which the | 10 | for compatibility with software that does not recognize the latter. These |
11 | interrupts are routed; see section 2 below for details. | 11 | properties contain a list of interrupt specifiers, one per output interrupt. The |
12 | format of the interrupt specifier is determined by the interrupt controller to | ||
13 | which the interrupts are routed; see section 2 below for details. | ||
12 | 14 | ||
13 | Example: | 15 | Example: |
14 | interrupt-parent = <&intc1>; | 16 | interrupt-parent = <&intc1>; |
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index d0d15ee42834..ed0d9b9fff2b 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt | |||
@@ -2,6 +2,10 @@ | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: should contain "snps,dw-pcie" to identify the core. | 4 | - compatible: should contain "snps,dw-pcie" to identify the core. |
5 | - reg: Should contain the configuration address space. | ||
6 | - reg-names: Must be "config" for the PCIe configuration space. | ||
7 | (The old way of getting the configuration address space from "ranges" | ||
8 | is deprecated and should be avoided.) | ||
5 | - #address-cells: set to <3> | 9 | - #address-cells: set to <3> |
6 | - #size-cells: set to <2> | 10 | - #size-cells: set to <2> |
7 | - device_type: set to "pci" | 11 | - device_type: set to "pci" |
diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt new file mode 100644 index 000000000000..3d217911b313 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/ti-pci.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | TI PCI Controllers | ||
2 | |||
3 | PCIe Designware Controller | ||
4 | - compatible: Should be "ti,dra7-pcie"" | ||
5 | - reg : Two register ranges as listed in the reg-names property | ||
6 | - reg-names : The first entry must be "ti-conf" for the TI specific registers | ||
7 | The second entry must be "rc-dbics" for the designware pcie | ||
8 | registers | ||
9 | The third entry must be "config" for the PCIe configuration space | ||
10 | - phys : list of PHY specifiers (used by generic PHY framework) | ||
11 | - phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the | ||
12 | number of PHYs as specified in *phys* property. | ||
13 | - ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>", | ||
14 | where <X> is the instance number of the pcie from the HW spec. | ||
15 | - interrupts : Two interrupt entries must be specified. The first one is for | ||
16 | main interrupt line and the second for MSI interrupt line. | ||
17 | - #address-cells, | ||
18 | #size-cells, | ||
19 | #interrupt-cells, | ||
20 | device_type, | ||
21 | ranges, | ||
22 | num-lanes, | ||
23 | interrupt-map-mask, | ||
24 | interrupt-map : as specified in ../designware-pcie.txt | ||
25 | |||
26 | Example: | ||
27 | axi { | ||
28 | compatible = "simple-bus"; | ||
29 | #size-cells = <1>; | ||
30 | #address-cells = <1>; | ||
31 | ranges = <0x51000000 0x51000000 0x3000 | ||
32 | 0x0 0x20000000 0x10000000>; | ||
33 | pcie@51000000 { | ||
34 | compatible = "ti,dra7-pcie"; | ||
35 | reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>; | ||
36 | reg-names = "rc_dbics", "ti_conf", "config"; | ||
37 | interrupts = <0 232 0x4>, <0 233 0x4>; | ||
38 | #address-cells = <3>; | ||
39 | #size-cells = <2>; | ||
40 | device_type = "pci"; | ||
41 | ranges = <0x81000000 0 0 0x03000 0 0x00010000 | ||
42 | 0x82000000 0 0x20013000 0x13000 0 0xffed000>; | ||
43 | #interrupt-cells = <1>; | ||
44 | num-lanes = <1>; | ||
45 | ti,hwmods = "pcie1"; | ||
46 | phys = <&pcie1_phy>; | ||
47 | phy-names = "pcie-phy0"; | ||
48 | interrupt-map-mask = <0 0 0 7>; | ||
49 | interrupt-map = <0 0 0 1 &pcie_intc 1>, | ||
50 | <0 0 0 2 &pcie_intc 2>, | ||
51 | <0 0 0 3 &pcie_intc 3>, | ||
52 | <0 0 0 4 &pcie_intc 4>; | ||
53 | pcie_intc: interrupt-controller { | ||
54 | interrupt-controller; | ||
55 | #address-cells = <0>; | ||
56 | #interrupt-cells = <1>; | ||
57 | }; | ||
58 | }; | ||
59 | }; | ||
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index b18dd1779029..f1997e9da61f 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -349,7 +349,11 @@ prototypes: | |||
349 | locking rules: | 349 | locking rules: |
350 | inode->i_lock may block | 350 | inode->i_lock may block |
351 | fl_copy_lock: yes no | 351 | fl_copy_lock: yes no |
352 | fl_release_private: maybe no | 352 | fl_release_private: maybe maybe[1] |
353 | |||
354 | [1]: ->fl_release_private for flock or POSIX locks is currently allowed | ||
355 | to block. Leases however can still be freed while the i_lock is held and | ||
356 | so fl_release_private called on a lease should not block. | ||
353 | 357 | ||
354 | ----------------------- lock_manager_operations --------------------------- | 358 | ----------------------- lock_manager_operations --------------------------- |
355 | prototypes: | 359 | prototypes: |
diff --git a/Documentation/laptops/00-INDEX b/Documentation/laptops/00-INDEX index d399ae1fc724..a3b4f209e562 100644 --- a/Documentation/laptops/00-INDEX +++ b/Documentation/laptops/00-INDEX | |||
@@ -18,3 +18,5 @@ sonypi.txt | |||
18 | - info on Linux Sony Programmable I/O Device support. | 18 | - info on Linux Sony Programmable I/O Device support. |
19 | thinkpad-acpi.txt | 19 | thinkpad-acpi.txt |
20 | - information on the (IBM and Lenovo) ThinkPad ACPI Extras driver. | 20 | - information on the (IBM and Lenovo) ThinkPad ACPI Extras driver. |
21 | toshiba_haps.txt | ||
22 | - information on the Toshiba HDD Active Protection Sensor driver. | ||
diff --git a/Documentation/laptops/toshiba_haps.txt b/Documentation/laptops/toshiba_haps.txt new file mode 100644 index 000000000000..11dbcfdc9e7a --- /dev/null +++ b/Documentation/laptops/toshiba_haps.txt | |||
@@ -0,0 +1,76 @@ | |||
1 | Kernel driver toshiba_haps | ||
2 | Toshiba HDD Active Protection Sensor | ||
3 | ==================================== | ||
4 | |||
5 | Author: Azael Avalos <coproscefalo@gmail.com> | ||
6 | |||
7 | |||
8 | 0. Contents | ||
9 | ----------- | ||
10 | |||
11 | 1. Description | ||
12 | 2. Interface | ||
13 | 3. Accelerometer axes | ||
14 | 4. Supported devices | ||
15 | 5. Usage | ||
16 | |||
17 | |||
18 | 1. Description | ||
19 | -------------- | ||
20 | |||
21 | This driver provides support for the accelerometer found in various Toshiba | ||
22 | laptops, being called "Toshiba HDD Protection - Shock Sensor" officialy, | ||
23 | and detects laptops automatically with this device. | ||
24 | On Windows, Toshiba provided software monitors this device and provides | ||
25 | automatic HDD protection (head unload) on sudden moves or harsh vibrations, | ||
26 | however, this driver only provides a notification via a sysfs file to let | ||
27 | userspace tools or daemons act accordingly, as well as providing a sysfs | ||
28 | file to set the desired protection level or sensor sensibility. | ||
29 | |||
30 | |||
31 | 2. Interface | ||
32 | ------------ | ||
33 | |||
34 | This device comes with 3 methods: | ||
35 | _STA - Checks existence of the device, returning Zero if the device does not | ||
36 | exists or is not supported. | ||
37 | PTLV - Sets the desired protection level. | ||
38 | RSSS - Shuts down the HDD protection interface for a few seconds, | ||
39 | then restores normal operation. | ||
40 | |||
41 | Note: | ||
42 | The presence of Solid State Drives (SSD) can make this driver to fail loading, | ||
43 | given the fact that such drives have no movable parts, and thus, not requiring | ||
44 | any "protection" as well as failing during the evaluation of the _STA method | ||
45 | found under this device. | ||
46 | |||
47 | |||
48 | 3. Accelerometer axes | ||
49 | --------------------- | ||
50 | |||
51 | This device does not report any axes, however, to query the sensor position | ||
52 | a couple HCI (Hardware Configuration Interface) calls (0x6D and 0xA6) are | ||
53 | provided to query such information, handled by the kernel module toshiba_acpi | ||
54 | since kernel version 3.15. | ||
55 | |||
56 | |||
57 | 4. Supported devices | ||
58 | -------------------- | ||
59 | |||
60 | This driver binds itself to the ACPI device TOS620A, and any Toshiba laptop | ||
61 | with this device is supported, given the fact that they have the presence of | ||
62 | conventional HDD and not only SSD, or a combination of both HDD and SSD. | ||
63 | |||
64 | |||
65 | 5. Usage | ||
66 | -------- | ||
67 | |||
68 | The sysfs files under /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS620A:00/ are: | ||
69 | protection_level - The protection_level is readable and writeable, and | ||
70 | provides a way to let userspace query the current protection | ||
71 | level, as well as set the desired protection level, the | ||
72 | available protection levels are: | ||
73 | 0 - Disabled | 1 - Low | 2 - Medium | 3 - High | ||
74 | reset_protection - The reset_protection entry is writeable only, being "1" | ||
75 | the only parameter it accepts, it is used to trigger | ||
76 | a reset of the protection interface. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 2f85f55c8fb8..f01f54f27750 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1843,6 +1843,12 @@ S: Orphan | |||
1843 | F: Documentation/filesystems/befs.txt | 1843 | F: Documentation/filesystems/befs.txt |
1844 | F: fs/befs/ | 1844 | F: fs/befs/ |
1845 | 1845 | ||
1846 | BECKHOFF CX5020 ETHERCAT MASTER DRIVER | ||
1847 | M: Dariusz Marcinkiewicz <reksio@newterm.pl> | ||
1848 | L: netdev@vger.kernel.org | ||
1849 | S: Maintained | ||
1850 | F: drivers/net/ethernet/ec_bhf.c | ||
1851 | |||
1846 | BFS FILE SYSTEM | 1852 | BFS FILE SYSTEM |
1847 | M: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk> | 1853 | M: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk> |
1848 | S: Maintained | 1854 | S: Maintained |
@@ -3843,10 +3849,13 @@ F: drivers/tty/serial/ucc_uart.c | |||
3843 | 3849 | ||
3844 | FREESCALE SOC SOUND DRIVERS | 3850 | FREESCALE SOC SOUND DRIVERS |
3845 | M: Timur Tabi <timur@tabi.org> | 3851 | M: Timur Tabi <timur@tabi.org> |
3852 | M: Nicolin Chen <nicoleotsuka@gmail.com> | ||
3853 | M: Xiubo Li <Li.Xiubo@freescale.com> | ||
3846 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 3854 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
3847 | L: linuxppc-dev@lists.ozlabs.org | 3855 | L: linuxppc-dev@lists.ozlabs.org |
3848 | S: Maintained | 3856 | S: Maintained |
3849 | F: sound/soc/fsl/fsl* | 3857 | F: sound/soc/fsl/fsl* |
3858 | F: sound/soc/fsl/imx* | ||
3850 | F: sound/soc/fsl/mpc8610_hpcd.c | 3859 | F: sound/soc/fsl/mpc8610_hpcd.c |
3851 | 3860 | ||
3852 | FREEVXFS FILESYSTEM | 3861 | FREEVXFS FILESYSTEM |
@@ -4446,6 +4455,13 @@ F: include/linux/i2c-*.h | |||
4446 | F: include/uapi/linux/i2c.h | 4455 | F: include/uapi/linux/i2c.h |
4447 | F: include/uapi/linux/i2c-*.h | 4456 | F: include/uapi/linux/i2c-*.h |
4448 | 4457 | ||
4458 | I2C ACPI SUPPORT | ||
4459 | M: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
4460 | L: linux-i2c@vger.kernel.org | ||
4461 | L: linux-acpi@vger.kernel.org | ||
4462 | S: Maintained | ||
4463 | F: drivers/i2c/i2c-acpi.c | ||
4464 | |||
4449 | I2C-TAOS-EVM DRIVER | 4465 | I2C-TAOS-EVM DRIVER |
4450 | M: Jean Delvare <jdelvare@suse.de> | 4466 | M: Jean Delvare <jdelvare@suse.de> |
4451 | L: linux-i2c@vger.kernel.org | 4467 | L: linux-i2c@vger.kernel.org |
@@ -5972,6 +5988,12 @@ T: git git://linuxtv.org/media_tree.git | |||
5972 | S: Maintained | 5988 | S: Maintained |
5973 | F: drivers/media/radio/radio-mr800.c | 5989 | F: drivers/media/radio/radio-mr800.c |
5974 | 5990 | ||
5991 | MRF24J40 IEEE 802.15.4 RADIO DRIVER | ||
5992 | M: Alan Ott <alan@signal11.us> | ||
5993 | L: linux-wpan@vger.kernel.org | ||
5994 | S: Maintained | ||
5995 | F: drivers/net/ieee802154/mrf24j40.c | ||
5996 | |||
5975 | MSI LAPTOP SUPPORT | 5997 | MSI LAPTOP SUPPORT |
5976 | M: "Lee, Chun-Yi" <jlee@suse.com> | 5998 | M: "Lee, Chun-Yi" <jlee@suse.com> |
5977 | L: platform-driver-x86@vger.kernel.org | 5999 | L: platform-driver-x86@vger.kernel.org |
@@ -6858,6 +6880,14 @@ S: Supported | |||
6858 | F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 6880 | F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt |
6859 | F: drivers/pci/host/pci-tegra.c | 6881 | F: drivers/pci/host/pci-tegra.c |
6860 | 6882 | ||
6883 | PCI DRIVER FOR TI DRA7XX | ||
6884 | M: Kishon Vijay Abraham I <kishon@ti.com> | ||
6885 | L: linux-omap@vger.kernel.org | ||
6886 | L: linux-pci@vger.kernel.org | ||
6887 | S: Supported | ||
6888 | F: Documentation/devicetree/bindings/pci/ti-pci.txt | ||
6889 | F: drivers/pci/host/pci-dra7xx.c | ||
6890 | |||
6861 | PCI DRIVER FOR RENESAS R-CAR | 6891 | PCI DRIVER FOR RENESAS R-CAR |
6862 | M: Simon Horman <horms@verge.net.au> | 6892 | M: Simon Horman <horms@verge.net.au> |
6863 | L: linux-pci@vger.kernel.org | 6893 | L: linux-pci@vger.kernel.org |
@@ -7059,6 +7089,7 @@ F: drivers/scsi/pmcraid.* | |||
7059 | PMC SIERRA PM8001 DRIVER | 7089 | PMC SIERRA PM8001 DRIVER |
7060 | M: xjtuwjp@gmail.com | 7090 | M: xjtuwjp@gmail.com |
7061 | M: lindar_liu@usish.com | 7091 | M: lindar_liu@usish.com |
7092 | L: pmchba@pmcs.com | ||
7062 | L: linux-scsi@vger.kernel.org | 7093 | L: linux-scsi@vger.kernel.org |
7063 | S: Supported | 7094 | S: Supported |
7064 | F: drivers/scsi/pm8001/ | 7095 | F: drivers/scsi/pm8001/ |
@@ -10016,7 +10047,7 @@ F: arch/x86/ | |||
10016 | X86 PLATFORM DRIVERS | 10047 | X86 PLATFORM DRIVERS |
10017 | M: Matthew Garrett <matthew.garrett@nebula.com> | 10048 | M: Matthew Garrett <matthew.garrett@nebula.com> |
10018 | L: platform-driver-x86@vger.kernel.org | 10049 | L: platform-driver-x86@vger.kernel.org |
10019 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git | 10050 | T: git git://cavan.codon.org.uk/platform-drivers-x86.git |
10020 | S: Maintained | 10051 | S: Maintained |
10021 | F: drivers/platform/x86/ | 10052 | F: drivers/platform/x86/ |
10022 | 10053 | ||
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 16 | 2 | PATCHLEVEL = 17 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION = -rc1 |
5 | NAME = Shuffling Zombie Juror | 5 | NAME = Shuffling Zombie Juror |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 57833546bf00..2df5e5daeebe 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile | |||
@@ -39,7 +39,7 @@ head-y := arch/arm64/kernel/head.o | |||
39 | 39 | ||
40 | # The byte offset of the kernel image in RAM from the start of RAM. | 40 | # The byte offset of the kernel image in RAM from the start of RAM. |
41 | ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) | 41 | ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) |
42 | TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}') | 42 | TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') |
43 | else | 43 | else |
44 | TEXT_OFFSET := 0x00080000 | 44 | TEXT_OFFSET := 0x00080000 |
45 | endif | 45 | endif |
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 1e52b741d806..d92ef3c54161 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
@@ -64,6 +64,8 @@ CONFIG_VIRTIO_BLK=y | |||
64 | CONFIG_BLK_DEV_SD=y | 64 | CONFIG_BLK_DEV_SD=y |
65 | # CONFIG_SCSI_LOWLEVEL is not set | 65 | # CONFIG_SCSI_LOWLEVEL is not set |
66 | CONFIG_ATA=y | 66 | CONFIG_ATA=y |
67 | CONFIG_AHCI_XGENE=y | ||
68 | CONFIG_PHY_XGENE=y | ||
67 | CONFIG_PATA_PLATFORM=y | 69 | CONFIG_PATA_PLATFORM=y |
68 | CONFIG_PATA_OF_PLATFORM=y | 70 | CONFIG_PATA_OF_PLATFORM=y |
69 | CONFIG_NETDEVICES=y | 71 | CONFIG_NETDEVICES=y |
@@ -71,6 +73,7 @@ CONFIG_TUN=y | |||
71 | CONFIG_VIRTIO_NET=y | 73 | CONFIG_VIRTIO_NET=y |
72 | CONFIG_SMC91X=y | 74 | CONFIG_SMC91X=y |
73 | CONFIG_SMSC911X=y | 75 | CONFIG_SMSC911X=y |
76 | CONFIG_NET_XGENE=y | ||
74 | # CONFIG_WLAN is not set | 77 | # CONFIG_WLAN is not set |
75 | CONFIG_INPUT_EVDEV=y | 78 | CONFIG_INPUT_EVDEV=y |
76 | # CONFIG_SERIO_SERPORT is not set | 79 | # CONFIG_SERIO_SERPORT is not set |
diff --git a/arch/arm64/include/asm/sparsemem.h b/arch/arm64/include/asm/sparsemem.h index 1be62bcb9d47..74a9d301819f 100644 --- a/arch/arm64/include/asm/sparsemem.h +++ b/arch/arm64/include/asm/sparsemem.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #define __ASM_SPARSEMEM_H | 17 | #define __ASM_SPARSEMEM_H |
18 | 18 | ||
19 | #ifdef CONFIG_SPARSEMEM | 19 | #ifdef CONFIG_SPARSEMEM |
20 | #define MAX_PHYSMEM_BITS 40 | 20 | #define MAX_PHYSMEM_BITS 48 |
21 | #define SECTION_SIZE_BITS 30 | 21 | #define SECTION_SIZE_BITS 30 |
22 | #endif | 22 | #endif |
23 | 23 | ||
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 4bc95d27e063..6d2bf419431d 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) | 41 | #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) |
42 | #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) | 42 | #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) |
43 | 43 | ||
44 | #define __NR_compat_syscalls 383 | 44 | #define __NR_compat_syscalls 386 |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #define __ARCH_WANT_SYS_CLONE | 47 | #define __ARCH_WANT_SYS_CLONE |
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index e242600c4046..da1f06b535e3 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h | |||
@@ -787,3 +787,8 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr) | |||
787 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) | 787 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) |
788 | #define __NR_renameat2 382 | 788 | #define __NR_renameat2 382 |
789 | __SYSCALL(__NR_renameat2, sys_renameat2) | 789 | __SYSCALL(__NR_renameat2, sys_renameat2) |
790 | /* 383 for seccomp */ | ||
791 | #define __NR_getrandom 384 | ||
792 | __SYSCALL(__NR_getrandom, sys_getrandom) | ||
793 | #define __NR_memfd_create 385 | ||
794 | __SYSCALL(__NR_memfd_create, sys_memfd_create) | ||
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index f798f66634af..177169623026 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c | |||
@@ -49,7 +49,7 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) | |||
49 | 49 | ||
50 | if (l1ip != ICACHE_POLICY_PIPT) | 50 | if (l1ip != ICACHE_POLICY_PIPT) |
51 | set_bit(ICACHEF_ALIASING, &__icache_flags); | 51 | set_bit(ICACHEF_ALIASING, &__icache_flags); |
52 | if (l1ip == ICACHE_POLICY_AIVIVT); | 52 | if (l1ip == ICACHE_POLICY_AIVIVT) |
53 | set_bit(ICACHEF_AIVIVT, &__icache_flags); | 53 | set_bit(ICACHEF_AIVIVT, &__icache_flags); |
54 | 54 | ||
55 | pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); | 55 | pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); |
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index e72f3100958f..24f0c6fb61d8 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -188,6 +188,8 @@ static __init void reserve_regions(void) | |||
188 | if (uefi_debug) | 188 | if (uefi_debug) |
189 | pr_cont("\n"); | 189 | pr_cont("\n"); |
190 | } | 190 | } |
191 | |||
192 | set_bit(EFI_MEMMAP, &efi.flags); | ||
191 | } | 193 | } |
192 | 194 | ||
193 | 195 | ||
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 144f10567f82..bed028364a93 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -38,11 +38,11 @@ | |||
38 | 38 | ||
39 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) | 39 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) |
40 | 40 | ||
41 | #if (TEXT_OFFSET & 0xf) != 0 | 41 | #if (TEXT_OFFSET & 0xfff) != 0 |
42 | #error TEXT_OFFSET must be at least 16B aligned | 42 | #error TEXT_OFFSET must be at least 4KB aligned |
43 | #elif (PAGE_OFFSET & 0xfffff) != 0 | 43 | #elif (PAGE_OFFSET & 0x1fffff) != 0 |
44 | #error PAGE_OFFSET must be at least 2MB aligned | 44 | #error PAGE_OFFSET must be at least 2MB aligned |
45 | #elif TEXT_OFFSET > 0xfffff | 45 | #elif TEXT_OFFSET > 0x1fffff |
46 | #error TEXT_OFFSET must be less than 2MB | 46 | #error TEXT_OFFSET must be less than 2MB |
47 | #endif | 47 | #endif |
48 | 48 | ||
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 0310811bd77d..70526cfda056 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
@@ -1115,19 +1115,15 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) | |||
1115 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) | 1115 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) |
1116 | trace_sys_enter(regs, regs->syscallno); | 1116 | trace_sys_enter(regs, regs->syscallno); |
1117 | 1117 | ||
1118 | #ifdef CONFIG_AUDITSYSCALL | ||
1119 | audit_syscall_entry(syscall_get_arch(), regs->syscallno, | 1118 | audit_syscall_entry(syscall_get_arch(), regs->syscallno, |
1120 | regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]); | 1119 | regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]); |
1121 | #endif | ||
1122 | 1120 | ||
1123 | return regs->syscallno; | 1121 | return regs->syscallno; |
1124 | } | 1122 | } |
1125 | 1123 | ||
1126 | asmlinkage void syscall_trace_exit(struct pt_regs *regs) | 1124 | asmlinkage void syscall_trace_exit(struct pt_regs *regs) |
1127 | { | 1125 | { |
1128 | #ifdef CONFIG_AUDITSYSCALL | ||
1129 | audit_syscall_exit(regs); | 1126 | audit_syscall_exit(regs); |
1130 | #endif | ||
1131 | 1127 | ||
1132 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) | 1128 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) |
1133 | trace_sys_exit(regs, regs_return_value(regs)); | 1129 | trace_sys_exit(regs, regs_return_value(regs)); |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 5b4526ee3a01..5472c2401876 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/of_fdt.h> | 32 | #include <linux/of_fdt.h> |
33 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
34 | #include <linux/dma-contiguous.h> | 34 | #include <linux/dma-contiguous.h> |
35 | #include <linux/efi.h> | ||
35 | 36 | ||
36 | #include <asm/fixmap.h> | 37 | #include <asm/fixmap.h> |
37 | #include <asm/sections.h> | 38 | #include <asm/sections.h> |
@@ -148,7 +149,8 @@ void __init arm64_memblock_init(void) | |||
148 | memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); | 149 | memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); |
149 | #endif | 150 | #endif |
150 | 151 | ||
151 | early_init_fdt_scan_reserved_mem(); | 152 | if (!efi_enabled(EFI_MEMMAP)) |
153 | early_init_fdt_scan_reserved_mem(); | ||
152 | 154 | ||
153 | /* 4GB maximum for 32-bit only capable devices */ | 155 | /* 4GB maximum for 32-bit only capable devices */ |
154 | if (IS_ENABLED(CONFIG_ZONE_DMA)) | 156 | if (IS_ENABLED(CONFIG_ZONE_DMA)) |
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index a34f309e5801..6554e78893f2 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h | |||
@@ -129,7 +129,8 @@ unsigned long get_wchan(struct task_struct *p); | |||
129 | #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) | 129 | #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) |
130 | #define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp) | 130 | #define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp) |
131 | 131 | ||
132 | #define cpu_relax() barrier() | 132 | #define cpu_relax() barrier() |
133 | #define cpu_relax_lowlatency() cpu_relax() | ||
133 | 134 | ||
134 | /* data cache prefetch */ | 135 | /* data cache prefetch */ |
135 | #define ARCH_HAS_PREFETCH | 136 | #define ARCH_HAS_PREFETCH |
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 4254f5d3218c..10a14ead70b9 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | 13 | ||
14 | #define NR_syscalls 316 /* length of syscall table */ | 14 | #define NR_syscalls 317 /* length of syscall table */ |
15 | 15 | ||
16 | /* | 16 | /* |
17 | * The following defines stop scripts/checksyscalls.sh from complaining about | 17 | * The following defines stop scripts/checksyscalls.sh from complaining about |
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h index 99801c3be914..6a65bb7d0657 100644 --- a/arch/ia64/include/uapi/asm/unistd.h +++ b/arch/ia64/include/uapi/asm/unistd.h | |||
@@ -329,5 +329,6 @@ | |||
329 | #define __NR_sched_getattr 1337 | 329 | #define __NR_sched_getattr 1337 |
330 | #define __NR_renameat2 1338 | 330 | #define __NR_renameat2 1338 |
331 | #define __NR_getrandom 1339 | 331 | #define __NR_getrandom 1339 |
332 | #define __NR_memfd_create 1339 | ||
332 | 333 | ||
333 | #endif /* _UAPI_ASM_IA64_UNISTD_H */ | 334 | #endif /* _UAPI_ASM_IA64_UNISTD_H */ |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 4c13837a9269..01edf242eb29 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1777,6 +1777,7 @@ sys_call_table: | |||
1777 | data8 sys_sched_getattr | 1777 | data8 sys_sched_getattr |
1778 | data8 sys_renameat2 | 1778 | data8 sys_renameat2 |
1779 | data8 sys_getrandom | 1779 | data8 sys_getrandom |
1780 | data8 sys_memfd_create // 1340 | ||
1780 | 1781 | ||
1781 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1782 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
1782 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ | 1783 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ |
diff --git a/arch/microblaze/include/uapi/asm/unistd.h b/arch/microblaze/include/uapi/asm/unistd.h index 4e1ddc930a68..1c2380bf8fe6 100644 --- a/arch/microblaze/include/uapi/asm/unistd.h +++ b/arch/microblaze/include/uapi/asm/unistd.h | |||
@@ -399,5 +399,8 @@ | |||
399 | #define __NR_sched_setattr 381 | 399 | #define __NR_sched_setattr 381 |
400 | #define __NR_sched_getattr 382 | 400 | #define __NR_sched_getattr 382 |
401 | #define __NR_renameat2 383 | 401 | #define __NR_renameat2 383 |
402 | #define __NR_seccomp 384 | ||
403 | #define __NR_getrandom 385 | ||
404 | #define __NR_memfd_create 386 | ||
402 | 405 | ||
403 | #endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */ | 406 | #endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */ |
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 1a23d5d5480c..de59ee1d7010 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S | |||
@@ -384,3 +384,6 @@ ENTRY(sys_call_table) | |||
384 | .long sys_sched_setattr | 384 | .long sys_sched_setattr |
385 | .long sys_sched_getattr | 385 | .long sys_sched_getattr |
386 | .long sys_renameat2 | 386 | .long sys_renameat2 |
387 | .long sys_seccomp | ||
388 | .long sys_getrandom /* 385 */ | ||
389 | .long sys_memfd_create | ||
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 329d7fdd0a6a..b9615ba5b083 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -101,7 +101,7 @@ struct kvm_rma_info *kvm_alloc_rma() | |||
101 | ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); | 101 | ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); |
102 | if (!ri) | 102 | if (!ri) |
103 | return NULL; | 103 | return NULL; |
104 | page = cma_alloc(kvm_cma, kvm_rma_pages, get_order(kvm_rma_pages)); | 104 | page = cma_alloc(kvm_cma, kvm_rma_pages, order_base_2(kvm_rma_pages)); |
105 | if (!page) | 105 | if (!page) |
106 | goto err_out; | 106 | goto err_out; |
107 | atomic_set(&ri->use_count, 1); | 107 | atomic_set(&ri->use_count, 1); |
@@ -135,12 +135,12 @@ struct page *kvm_alloc_hpt(unsigned long nr_pages) | |||
135 | { | 135 | { |
136 | unsigned long align_pages = HPT_ALIGN_PAGES; | 136 | unsigned long align_pages = HPT_ALIGN_PAGES; |
137 | 137 | ||
138 | VM_BUG_ON(get_order(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); | 138 | VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); |
139 | 139 | ||
140 | /* Old CPUs require HPT aligned on a multiple of its size */ | 140 | /* Old CPUs require HPT aligned on a multiple of its size */ |
141 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | 141 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) |
142 | align_pages = nr_pages; | 142 | align_pages = nr_pages; |
143 | return cma_alloc(kvm_cma, nr_pages, get_order(align_pages)); | 143 | return cma_alloc(kvm_cma, nr_pages, order_base_2(align_pages)); |
144 | } | 144 | } |
145 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); | 145 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); |
146 | 146 | ||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 572460175ba5..7c492ed9087b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -95,7 +95,7 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) | |||
95 | #define KVM_REFILL_PAGES 25 | 95 | #define KVM_REFILL_PAGES 25 |
96 | #define KVM_MAX_CPUID_ENTRIES 80 | 96 | #define KVM_MAX_CPUID_ENTRIES 80 |
97 | #define KVM_NR_FIXED_MTRR_REGION 88 | 97 | #define KVM_NR_FIXED_MTRR_REGION 88 |
98 | #define KVM_NR_VAR_MTRR 10 | 98 | #define KVM_NR_VAR_MTRR 8 |
99 | 99 | ||
100 | #define ASYNC_PF_PER_VCPU 64 | 100 | #define ASYNC_PF_PER_VCPU 64 |
101 | 101 | ||
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index eac9e92fe181..e21331ce368f 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -149,6 +149,9 @@ | |||
149 | 149 | ||
150 | #define MSR_CORE_C1_RES 0x00000660 | 150 | #define MSR_CORE_C1_RES 0x00000660 |
151 | 151 | ||
152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 | ||
153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 | ||
154 | |||
152 | #define MSR_AMD64_MC0_MASK 0xc0010044 | 155 | #define MSR_AMD64_MC0_MASK 0xc0010044 |
153 | 156 | ||
154 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) | 157 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 56657b0bb3bb..03954f7900f5 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
1491 | goto exception; | 1491 | goto exception; |
1492 | break; | 1492 | break; |
1493 | case VCPU_SREG_CS: | 1493 | case VCPU_SREG_CS: |
1494 | if (in_task_switch && rpl != dpl) | ||
1495 | goto exception; | ||
1496 | |||
1497 | if (!(seg_desc.type & 8)) | 1494 | if (!(seg_desc.type & 8)) |
1498 | goto exception; | 1495 | goto exception; |
1499 | 1496 | ||
@@ -4394,8 +4391,11 @@ done_prefixes: | |||
4394 | 4391 | ||
4395 | ctxt->execute = opcode.u.execute; | 4392 | ctxt->execute = opcode.u.execute; |
4396 | 4393 | ||
4394 | if (unlikely(ctxt->ud) && likely(!(ctxt->d & EmulateOnUD))) | ||
4395 | return EMULATION_FAILED; | ||
4396 | |||
4397 | if (unlikely(ctxt->d & | 4397 | if (unlikely(ctxt->d & |
4398 | (NotImpl|EmulateOnUD|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) { | 4398 | (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) { |
4399 | /* | 4399 | /* |
4400 | * These are copied unconditionally here, and checked unconditionally | 4400 | * These are copied unconditionally here, and checked unconditionally |
4401 | * in x86_emulate_insn. | 4401 | * in x86_emulate_insn. |
@@ -4406,9 +4406,6 @@ done_prefixes: | |||
4406 | if (ctxt->d & NotImpl) | 4406 | if (ctxt->d & NotImpl) |
4407 | return EMULATION_FAILED; | 4407 | return EMULATION_FAILED; |
4408 | 4408 | ||
4409 | if (!(ctxt->d & EmulateOnUD) && ctxt->ud) | ||
4410 | return EMULATION_FAILED; | ||
4411 | |||
4412 | if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack)) | 4409 | if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack)) |
4413 | ctxt->op_bytes = 8; | 4410 | ctxt->op_bytes = 8; |
4414 | 4411 | ||
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c index fc3df47fca35..f1fef74e503c 100644 --- a/drivers/ata/ahci_tegra.c +++ b/drivers/ata/ahci_tegra.c | |||
@@ -24,8 +24,8 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/tegra-powergate.h> | ||
28 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
28 | #include <soc/tegra/pmc.h> | ||
29 | #include "ahci.h" | 29 | #include "ahci.h" |
30 | 30 | ||
31 | #define SATA_CONFIGURATION_0 0x180 | 31 | #define SATA_CONFIGURATION_0 0x180 |
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index bc281115490b..c6962300b93c 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
@@ -344,7 +344,7 @@ static struct ata_port_operations xgene_ahci_ops = { | |||
344 | }; | 344 | }; |
345 | 345 | ||
346 | static const struct ata_port_info xgene_ahci_port_info = { | 346 | static const struct ata_port_info xgene_ahci_port_info = { |
347 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, | 347 | .flags = AHCI_FLAG_COMMON, |
348 | .pio_mask = ATA_PIO4, | 348 | .pio_mask = ATA_PIO4, |
349 | .udma_mask = ATA_UDMA6, | 349 | .udma_mask = ATA_UDMA6, |
350 | .port_ops = &xgene_ahci_ops, | 350 | .port_ops = &xgene_ahci_ops, |
@@ -480,7 +480,7 @@ static int xgene_ahci_probe(struct platform_device *pdev) | |||
480 | /* Configure the host controller */ | 480 | /* Configure the host controller */ |
481 | xgene_ahci_hw_init(hpriv); | 481 | xgene_ahci_hw_init(hpriv); |
482 | 482 | ||
483 | hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ; | 483 | hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ; |
484 | 484 | ||
485 | rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); | 485 | rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); |
486 | if (rc) | 486 | if (rc) |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index dbdc5d32343f..f3e7b9f894cd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4228,7 +4228,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4228 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4228 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4229 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4229 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4230 | { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4230 | { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4231 | { "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4231 | { "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4232 | 4232 | ||
4233 | /* | 4233 | /* |
4234 | * Some WD SATA-I drives spin up and down erratically when the link | 4234 | * Some WD SATA-I drives spin up and down erratically when the link |
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 2578fc16960a..1a24a5dc3940 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c | |||
@@ -360,7 +360,7 @@ static int pata_s3c_wait_after_reset(struct ata_link *link, | |||
360 | /* | 360 | /* |
361 | * pata_s3c_bus_softreset - PATA device software reset | 361 | * pata_s3c_bus_softreset - PATA device software reset |
362 | */ | 362 | */ |
363 | static unsigned int pata_s3c_bus_softreset(struct ata_port *ap, | 363 | static int pata_s3c_bus_softreset(struct ata_port *ap, |
364 | unsigned long deadline) | 364 | unsigned long deadline) |
365 | { | 365 | { |
366 | struct ata_ioports *ioaddr = &ap->ioaddr; | 366 | struct ata_ioports *ioaddr = &ap->ioaddr; |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 4e006d74bef8..7f4cb76ed9fa 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -585,7 +585,7 @@ static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask, | |||
585 | * Note: Original code is ata_bus_softreset(). | 585 | * Note: Original code is ata_bus_softreset(). |
586 | */ | 586 | */ |
587 | 587 | ||
588 | static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, | 588 | static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, |
589 | unsigned long deadline) | 589 | unsigned long deadline) |
590 | { | 590 | { |
591 | struct ata_ioports *ioaddr = &ap->ioaddr; | 591 | struct ata_ioports *ioaddr = &ap->ioaddr; |
@@ -599,9 +599,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, | |||
599 | udelay(20); | 599 | udelay(20); |
600 | out_be32(ioaddr->ctl_addr, ap->ctl); | 600 | out_be32(ioaddr->ctl_addr, ap->ctl); |
601 | 601 | ||
602 | scc_wait_after_reset(&ap->link, devmask, deadline); | 602 | return scc_wait_after_reset(&ap->link, devmask, deadline); |
603 | |||
604 | return 0; | ||
605 | } | 603 | } |
606 | 604 | ||
607 | /** | 605 | /** |
@@ -618,7 +616,8 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, | |||
618 | { | 616 | { |
619 | struct ata_port *ap = link->ap; | 617 | struct ata_port *ap = link->ap; |
620 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; | 618 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; |
621 | unsigned int devmask = 0, err_mask; | 619 | unsigned int devmask = 0; |
620 | int rc; | ||
622 | u8 err; | 621 | u8 err; |
623 | 622 | ||
624 | DPRINTK("ENTER\n"); | 623 | DPRINTK("ENTER\n"); |
@@ -634,9 +633,9 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, | |||
634 | 633 | ||
635 | /* issue bus reset */ | 634 | /* issue bus reset */ |
636 | DPRINTK("about to softreset, devmask=%x\n", devmask); | 635 | DPRINTK("about to softreset, devmask=%x\n", devmask); |
637 | err_mask = scc_bus_softreset(ap, devmask, deadline); | 636 | rc = scc_bus_softreset(ap, devmask, deadline); |
638 | if (err_mask) { | 637 | if (rc) { |
639 | ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", err_mask); | 638 | ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc); |
640 | return -EIO; | 639 | return -EIO; |
641 | } | 640 | } |
642 | 641 | ||
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 0027137daa56..2e3139eda93b 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -116,6 +116,7 @@ static int probe_common(struct virtio_device *vdev) | |||
116 | .cleanup = virtio_cleanup, | 116 | .cleanup = virtio_cleanup, |
117 | .priv = (unsigned long)vi, | 117 | .priv = (unsigned long)vi, |
118 | .name = vi->name, | 118 | .name = vi->name, |
119 | .quality = 1000, | ||
119 | }; | 120 | }; |
120 | vdev->priv = vi; | 121 | vdev->priv = vi; |
121 | 122 | ||
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index f8665f9c3e03..fd89ca982748 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig | |||
@@ -253,12 +253,12 @@ config EDAC_I7300 | |||
253 | Clarksboro MCH (Intel 7300 chipset). | 253 | Clarksboro MCH (Intel 7300 chipset). |
254 | 254 | ||
255 | config EDAC_SBRIDGE | 255 | config EDAC_SBRIDGE |
256 | tristate "Intel Sandy-Bridge Integrated MC" | 256 | tristate "Intel Sandy-Bridge/Ivy-Bridge/Haswell Integrated MC" |
257 | depends on EDAC_MM_EDAC && PCI && X86_64 && X86_MCE_INTEL | 257 | depends on EDAC_MM_EDAC && PCI && X86_64 && X86_MCE_INTEL |
258 | depends on PCI_MMCONFIG | 258 | depends on PCI_MMCONFIG |
259 | help | 259 | help |
260 | Support for error detection and correction the Intel | 260 | Support for error detection and correction the Intel |
261 | Sandy Bridge Integrated Memory Controller. | 261 | Sandy Bridge, Ivy Bridge and Haswell Integrated Memory Controllers. |
262 | 262 | ||
263 | config EDAC_MPC85XX | 263 | config EDAC_MPC85XX |
264 | tristate "Freescale MPC83xx / MPC85xx" | 264 | tristate "Freescale MPC83xx / MPC85xx" |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 01fae8289cf0..a6cd36100663 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -108,7 +108,9 @@ static const char * const mem_types[] = { | |||
108 | [MEM_RDDR2] = "Registered-DDR2", | 108 | [MEM_RDDR2] = "Registered-DDR2", |
109 | [MEM_XDR] = "XDR", | 109 | [MEM_XDR] = "XDR", |
110 | [MEM_DDR3] = "Unbuffered-DDR3", | 110 | [MEM_DDR3] = "Unbuffered-DDR3", |
111 | [MEM_RDDR3] = "Registered-DDR3" | 111 | [MEM_RDDR3] = "Registered-DDR3", |
112 | [MEM_DDR4] = "Unbuffered-DDR4", | ||
113 | [MEM_RDDR4] = "Registered-DDR4" | ||
112 | }; | 114 | }; |
113 | 115 | ||
114 | static const char * const dev_types[] = { | 116 | static const char * const dev_types[] = { |
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index deea0dc9999b..0034c4844428 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c | |||
@@ -99,6 +99,7 @@ static const u32 ibridge_dram_rule[] = { | |||
99 | #define DRAM_ATTR(reg) GET_BITFIELD(reg, 2, 3) | 99 | #define DRAM_ATTR(reg) GET_BITFIELD(reg, 2, 3) |
100 | #define INTERLEAVE_MODE(reg) GET_BITFIELD(reg, 1, 1) | 100 | #define INTERLEAVE_MODE(reg) GET_BITFIELD(reg, 1, 1) |
101 | #define DRAM_RULE_ENABLE(reg) GET_BITFIELD(reg, 0, 0) | 101 | #define DRAM_RULE_ENABLE(reg) GET_BITFIELD(reg, 0, 0) |
102 | #define A7MODE(reg) GET_BITFIELD(reg, 26, 26) | ||
102 | 103 | ||
103 | static char *get_dram_attr(u32 reg) | 104 | static char *get_dram_attr(u32 reg) |
104 | { | 105 | { |
@@ -164,6 +165,8 @@ static inline int sad_pkg(const struct interleave_pkg *table, u32 reg, | |||
164 | 165 | ||
165 | #define TOLM 0x80 | 166 | #define TOLM 0x80 |
166 | #define TOHM 0x84 | 167 | #define TOHM 0x84 |
168 | #define HASWELL_TOHM_0 0xd4 | ||
169 | #define HASWELL_TOHM_1 0xd8 | ||
167 | 170 | ||
168 | #define GET_TOLM(reg) ((GET_BITFIELD(reg, 0, 3) << 28) | 0x3ffffff) | 171 | #define GET_TOLM(reg) ((GET_BITFIELD(reg, 0, 3) << 28) | 0x3ffffff) |
169 | #define GET_TOHM(reg) ((GET_BITFIELD(reg, 0, 20) << 25) | 0x3ffffff) | 172 | #define GET_TOHM(reg) ((GET_BITFIELD(reg, 0, 20) << 25) | 0x3ffffff) |
@@ -176,8 +179,6 @@ static inline int sad_pkg(const struct interleave_pkg *table, u32 reg, | |||
176 | 179 | ||
177 | #define SAD_CONTROL 0xf4 | 180 | #define SAD_CONTROL 0xf4 |
178 | 181 | ||
179 | #define NODE_ID(reg) GET_BITFIELD(reg, 0, 2) | ||
180 | |||
181 | /* Device 14 function 0 */ | 182 | /* Device 14 function 0 */ |
182 | 183 | ||
183 | static const u32 tad_dram_rule[] = { | 184 | static const u32 tad_dram_rule[] = { |
@@ -235,7 +236,6 @@ static const u32 rir_way_limit[] = { | |||
235 | 236 | ||
236 | #define IS_RIR_VALID(reg) GET_BITFIELD(reg, 31, 31) | 237 | #define IS_RIR_VALID(reg) GET_BITFIELD(reg, 31, 31) |
237 | #define RIR_WAY(reg) GET_BITFIELD(reg, 28, 29) | 238 | #define RIR_WAY(reg) GET_BITFIELD(reg, 28, 29) |
238 | #define RIR_LIMIT(reg) ((GET_BITFIELD(reg, 1, 10) << 29)| 0x1fffffff) | ||
239 | 239 | ||
240 | #define MAX_RIR_WAY 8 | 240 | #define MAX_RIR_WAY 8 |
241 | 241 | ||
@@ -279,8 +279,6 @@ static const u32 correrrthrsld[] = { | |||
279 | 279 | ||
280 | #define IB_RANK_CFG_A 0x0320 | 280 | #define IB_RANK_CFG_A 0x0320 |
281 | 281 | ||
282 | #define IS_RDIMM_ENABLED(reg) GET_BITFIELD(reg, 11, 11) | ||
283 | |||
284 | /* | 282 | /* |
285 | * sbridge structs | 283 | * sbridge structs |
286 | */ | 284 | */ |
@@ -291,6 +289,7 @@ static const u32 correrrthrsld[] = { | |||
291 | enum type { | 289 | enum type { |
292 | SANDY_BRIDGE, | 290 | SANDY_BRIDGE, |
293 | IVY_BRIDGE, | 291 | IVY_BRIDGE, |
292 | HASWELL, | ||
294 | }; | 293 | }; |
295 | 294 | ||
296 | struct sbridge_pvt; | 295 | struct sbridge_pvt; |
@@ -300,11 +299,15 @@ struct sbridge_info { | |||
300 | u32 rankcfgr; | 299 | u32 rankcfgr; |
301 | u64 (*get_tolm)(struct sbridge_pvt *pvt); | 300 | u64 (*get_tolm)(struct sbridge_pvt *pvt); |
302 | u64 (*get_tohm)(struct sbridge_pvt *pvt); | 301 | u64 (*get_tohm)(struct sbridge_pvt *pvt); |
302 | u64 (*rir_limit)(u32 reg); | ||
303 | const u32 *dram_rule; | 303 | const u32 *dram_rule; |
304 | const u32 *interleave_list; | 304 | const u32 *interleave_list; |
305 | const struct interleave_pkg *interleave_pkg; | 305 | const struct interleave_pkg *interleave_pkg; |
306 | u8 max_sad; | 306 | u8 max_sad; |
307 | u8 max_interleave; | 307 | u8 max_interleave; |
308 | u8 (*get_node_id)(struct sbridge_pvt *pvt); | ||
309 | enum mem_type (*get_memory_type)(struct sbridge_pvt *pvt); | ||
310 | struct pci_dev *pci_vtd; | ||
308 | }; | 311 | }; |
309 | 312 | ||
310 | struct sbridge_channel { | 313 | struct sbridge_channel { |
@@ -313,9 +316,7 @@ struct sbridge_channel { | |||
313 | }; | 316 | }; |
314 | 317 | ||
315 | struct pci_id_descr { | 318 | struct pci_id_descr { |
316 | int dev; | 319 | int dev_id; |
317 | int func; | ||
318 | int dev_id; | ||
319 | int optional; | 320 | int optional; |
320 | }; | 321 | }; |
321 | 322 | ||
@@ -338,6 +339,7 @@ struct sbridge_pvt { | |||
338 | struct pci_dev *pci_sad0, *pci_sad1; | 339 | struct pci_dev *pci_sad0, *pci_sad1; |
339 | struct pci_dev *pci_ha0, *pci_ha1; | 340 | struct pci_dev *pci_ha0, *pci_ha1; |
340 | struct pci_dev *pci_br0, *pci_br1; | 341 | struct pci_dev *pci_br0, *pci_br1; |
342 | struct pci_dev *pci_ha1_ta; | ||
341 | struct pci_dev *pci_tad[NUM_CHANNELS]; | 343 | struct pci_dev *pci_tad[NUM_CHANNELS]; |
342 | 344 | ||
343 | struct sbridge_dev *sbridge_dev; | 345 | struct sbridge_dev *sbridge_dev; |
@@ -362,31 +364,29 @@ struct sbridge_pvt { | |||
362 | u64 tolm, tohm; | 364 | u64 tolm, tohm; |
363 | }; | 365 | }; |
364 | 366 | ||
365 | #define PCI_DESCR(device, function, device_id, opt) \ | 367 | #define PCI_DESCR(device_id, opt) \ |
366 | .dev = (device), \ | 368 | .dev_id = (device_id), \ |
367 | .func = (function), \ | ||
368 | .dev_id = (device_id), \ | ||
369 | .optional = opt | 369 | .optional = opt |
370 | 370 | ||
371 | static const struct pci_id_descr pci_dev_descr_sbridge[] = { | 371 | static const struct pci_id_descr pci_dev_descr_sbridge[] = { |
372 | /* Processor Home Agent */ | 372 | /* Processor Home Agent */ |
373 | { PCI_DESCR(14, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0, 0) }, | 373 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0, 0) }, |
374 | 374 | ||
375 | /* Memory controller */ | 375 | /* Memory controller */ |
376 | { PCI_DESCR(15, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA, 0) }, | 376 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA, 0) }, |
377 | { PCI_DESCR(15, 1, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS, 0) }, | 377 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS, 0) }, |
378 | { PCI_DESCR(15, 2, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD0, 0) }, | 378 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD0, 0) }, |
379 | { PCI_DESCR(15, 3, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1, 0) }, | 379 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1, 0) }, |
380 | { PCI_DESCR(15, 4, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2, 0) }, | 380 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2, 0) }, |
381 | { PCI_DESCR(15, 5, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3, 0) }, | 381 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3, 0) }, |
382 | { PCI_DESCR(17, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO, 1) }, | 382 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO, 1) }, |
383 | 383 | ||
384 | /* System Address Decoder */ | 384 | /* System Address Decoder */ |
385 | { PCI_DESCR(12, 6, PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0, 0) }, | 385 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0, 0) }, |
386 | { PCI_DESCR(12, 7, PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1, 0) }, | 386 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1, 0) }, |
387 | 387 | ||
388 | /* Broadcast Registers */ | 388 | /* Broadcast Registers */ |
389 | { PCI_DESCR(13, 6, PCI_DEVICE_ID_INTEL_SBRIDGE_BR, 0) }, | 389 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_BR, 0) }, |
390 | }; | 390 | }; |
391 | 391 | ||
392 | #define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) } | 392 | #define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) } |
@@ -423,34 +423,34 @@ static const struct pci_id_table pci_dev_descr_sbridge_table[] = { | |||
423 | 423 | ||
424 | static const struct pci_id_descr pci_dev_descr_ibridge[] = { | 424 | static const struct pci_id_descr pci_dev_descr_ibridge[] = { |
425 | /* Processor Home Agent */ | 425 | /* Processor Home Agent */ |
426 | { PCI_DESCR(14, 0, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0, 0) }, | 426 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0, 0) }, |
427 | 427 | ||
428 | /* Memory controller */ | 428 | /* Memory controller */ |
429 | { PCI_DESCR(15, 0, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA, 0) }, | 429 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA, 0) }, |
430 | { PCI_DESCR(15, 1, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_RAS, 0) }, | 430 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_RAS, 0) }, |
431 | { PCI_DESCR(15, 2, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD0, 0) }, | 431 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD0, 0) }, |
432 | { PCI_DESCR(15, 3, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD1, 0) }, | 432 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD1, 0) }, |
433 | { PCI_DESCR(15, 4, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD2, 0) }, | 433 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD2, 0) }, |
434 | { PCI_DESCR(15, 5, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD3, 0) }, | 434 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD3, 0) }, |
435 | 435 | ||
436 | /* System Address Decoder */ | 436 | /* System Address Decoder */ |
437 | { PCI_DESCR(22, 0, PCI_DEVICE_ID_INTEL_IBRIDGE_SAD, 0) }, | 437 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_SAD, 0) }, |
438 | 438 | ||
439 | /* Broadcast Registers */ | 439 | /* Broadcast Registers */ |
440 | { PCI_DESCR(22, 1, PCI_DEVICE_ID_INTEL_IBRIDGE_BR0, 1) }, | 440 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_BR0, 1) }, |
441 | { PCI_DESCR(22, 2, PCI_DEVICE_ID_INTEL_IBRIDGE_BR1, 0) }, | 441 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_BR1, 0) }, |
442 | 442 | ||
443 | /* Optional, mode 2HA */ | 443 | /* Optional, mode 2HA */ |
444 | { PCI_DESCR(28, 0, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1, 1) }, | 444 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1, 1) }, |
445 | #if 0 | 445 | #if 0 |
446 | { PCI_DESCR(29, 0, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TA, 1) }, | 446 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TA, 1) }, |
447 | { PCI_DESCR(29, 1, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_RAS, 1) }, | 447 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_RAS, 1) }, |
448 | #endif | 448 | #endif |
449 | { PCI_DESCR(29, 2, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD0, 1) }, | 449 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD0, 1) }, |
450 | { PCI_DESCR(29, 3, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD1, 1) }, | 450 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD1, 1) }, |
451 | 451 | ||
452 | { PCI_DESCR(17, 0, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_1HA_DDRIO0, 1) }, | 452 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_1HA_DDRIO0, 1) }, |
453 | { PCI_DESCR(17, 4, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_2HA_DDRIO0, 1) }, | 453 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_2HA_DDRIO0, 1) }, |
454 | }; | 454 | }; |
455 | 455 | ||
456 | static const struct pci_id_table pci_dev_descr_ibridge_table[] = { | 456 | static const struct pci_id_table pci_dev_descr_ibridge_table[] = { |
@@ -458,12 +458,80 @@ static const struct pci_id_table pci_dev_descr_ibridge_table[] = { | |||
458 | {0,} /* 0 terminated list. */ | 458 | {0,} /* 0 terminated list. */ |
459 | }; | 459 | }; |
460 | 460 | ||
461 | /* Haswell support */ | ||
462 | /* EN processor: | ||
463 | * - 1 IMC | ||
464 | * - 3 DDR3 channels, 2 DPC per channel | ||
465 | * EP processor: | ||
466 | * - 1 or 2 IMC | ||
467 | * - 4 DDR4 channels, 3 DPC per channel | ||
468 | * EP 4S processor: | ||
469 | * - 2 IMC | ||
470 | * - 4 DDR4 channels, 3 DPC per channel | ||
471 | * EX processor: | ||
472 | * - 2 IMC | ||
473 | * - each IMC interfaces with a SMI 2 channel | ||
474 | * - each SMI channel interfaces with a scalable memory buffer | ||
475 | * - each scalable memory buffer supports 4 DDR3/DDR4 channels, 3 DPC | ||
476 | */ | ||
477 | #define HASWELL_DDRCRCLKCONTROLS 0xa10 | ||
478 | #define HASWELL_HASYSDEFEATURE2 0x84 | ||
479 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_VTD_MISC 0x2f28 | ||
480 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0 0x2fa0 | ||
481 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1 0x2f60 | ||
482 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TA 0x2fa8 | ||
483 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_THERMAL 0x2f71 | ||
484 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TA 0x2f68 | ||
485 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_THERMAL 0x2f79 | ||
486 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_CBO_SAD0 0x2ffc | ||
487 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_CBO_SAD1 0x2ffd | ||
488 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD0 0x2faa | ||
489 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD1 0x2fab | ||
490 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD2 0x2fac | ||
491 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD3 0x2fad | ||
492 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD0 0x2f6a | ||
493 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD1 0x2f6b | ||
494 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD2 0x2f6c | ||
495 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD3 0x2f6d | ||
496 | #define PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0 0x2fbd | ||
497 | static const struct pci_id_descr pci_dev_descr_haswell[] = { | ||
498 | /* first item must be the HA */ | ||
499 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0, 0) }, | ||
500 | |||
501 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_CBO_SAD0, 0) }, | ||
502 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_CBO_SAD1, 0) }, | ||
503 | |||
504 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1, 1) }, | ||
505 | |||
506 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TA, 0) }, | ||
507 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_THERMAL, 0) }, | ||
508 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD0, 0) }, | ||
509 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD1, 0) }, | ||
510 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD2, 1) }, | ||
511 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD3, 1) }, | ||
512 | |||
513 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0, 1) }, | ||
514 | |||
515 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TA, 1) }, | ||
516 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_THERMAL, 1) }, | ||
517 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD0, 1) }, | ||
518 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD1, 1) }, | ||
519 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD2, 1) }, | ||
520 | { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD3, 1) }, | ||
521 | }; | ||
522 | |||
523 | static const struct pci_id_table pci_dev_descr_haswell_table[] = { | ||
524 | PCI_ID_TABLE_ENTRY(pci_dev_descr_haswell), | ||
525 | {0,} /* 0 terminated list. */ | ||
526 | }; | ||
527 | |||
461 | /* | 528 | /* |
462 | * pci_device_id table for which devices we are looking for | 529 | * pci_device_id table for which devices we are looking for |
463 | */ | 530 | */ |
464 | static const struct pci_device_id sbridge_pci_tbl[] = { | 531 | static const struct pci_device_id sbridge_pci_tbl[] = { |
465 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA)}, | 532 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA)}, |
466 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA)}, | 533 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA)}, |
534 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0)}, | ||
467 | {0,} /* 0 terminated list. */ | 535 | {0,} /* 0 terminated list. */ |
468 | }; | 536 | }; |
469 | 537 | ||
@@ -472,13 +540,17 @@ static const struct pci_device_id sbridge_pci_tbl[] = { | |||
472 | Ancillary status routines | 540 | Ancillary status routines |
473 | ****************************************************************************/ | 541 | ****************************************************************************/ |
474 | 542 | ||
475 | static inline int numrank(u32 mtr) | 543 | static inline int numrank(enum type type, u32 mtr) |
476 | { | 544 | { |
477 | int ranks = (1 << RANK_CNT_BITS(mtr)); | 545 | int ranks = (1 << RANK_CNT_BITS(mtr)); |
546 | int max = 4; | ||
478 | 547 | ||
479 | if (ranks > 4) { | 548 | if (type == HASWELL) |
480 | edac_dbg(0, "Invalid number of ranks: %d (max = 4) raw value = %x (%04x)\n", | 549 | max = 8; |
481 | ranks, (unsigned int)RANK_CNT_BITS(mtr), mtr); | 550 | |
551 | if (ranks > max) { | ||
552 | edac_dbg(0, "Invalid number of ranks: %d (max = %i) raw value = %x (%04x)\n", | ||
553 | ranks, max, (unsigned int)RANK_CNT_BITS(mtr), mtr); | ||
482 | return -EINVAL; | 554 | return -EINVAL; |
483 | } | 555 | } |
484 | 556 | ||
@@ -588,10 +660,107 @@ static u64 ibridge_get_tohm(struct sbridge_pvt *pvt) | |||
588 | return GET_TOHM(reg); | 660 | return GET_TOHM(reg); |
589 | } | 661 | } |
590 | 662 | ||
663 | static u64 rir_limit(u32 reg) | ||
664 | { | ||
665 | return ((u64)GET_BITFIELD(reg, 1, 10) << 29) | 0x1fffffff; | ||
666 | } | ||
667 | |||
668 | static enum mem_type get_memory_type(struct sbridge_pvt *pvt) | ||
669 | { | ||
670 | u32 reg; | ||
671 | enum mem_type mtype; | ||
672 | |||
673 | if (pvt->pci_ddrio) { | ||
674 | pci_read_config_dword(pvt->pci_ddrio, pvt->info.rankcfgr, | ||
675 | ®); | ||
676 | if (GET_BITFIELD(reg, 11, 11)) | ||
677 | /* FIXME: Can also be LRDIMM */ | ||
678 | mtype = MEM_RDDR3; | ||
679 | else | ||
680 | mtype = MEM_DDR3; | ||
681 | } else | ||
682 | mtype = MEM_UNKNOWN; | ||
683 | |||
684 | return mtype; | ||
685 | } | ||
686 | |||
687 | static enum mem_type haswell_get_memory_type(struct sbridge_pvt *pvt) | ||
688 | { | ||
689 | u32 reg; | ||
690 | bool registered = false; | ||
691 | enum mem_type mtype = MEM_UNKNOWN; | ||
692 | |||
693 | if (!pvt->pci_ddrio) | ||
694 | goto out; | ||
695 | |||
696 | pci_read_config_dword(pvt->pci_ddrio, | ||
697 | HASWELL_DDRCRCLKCONTROLS, ®); | ||
698 | /* Is_Rdimm */ | ||
699 | if (GET_BITFIELD(reg, 16, 16)) | ||
700 | registered = true; | ||
701 | |||
702 | pci_read_config_dword(pvt->pci_ta, MCMTR, ®); | ||
703 | if (GET_BITFIELD(reg, 14, 14)) { | ||
704 | if (registered) | ||
705 | mtype = MEM_RDDR4; | ||
706 | else | ||
707 | mtype = MEM_DDR4; | ||
708 | } else { | ||
709 | if (registered) | ||
710 | mtype = MEM_RDDR3; | ||
711 | else | ||
712 | mtype = MEM_DDR3; | ||
713 | } | ||
714 | |||
715 | out: | ||
716 | return mtype; | ||
717 | } | ||
718 | |||
719 | static u8 get_node_id(struct sbridge_pvt *pvt) | ||
720 | { | ||
721 | u32 reg; | ||
722 | pci_read_config_dword(pvt->pci_br0, SAD_CONTROL, ®); | ||
723 | return GET_BITFIELD(reg, 0, 2); | ||
724 | } | ||
725 | |||
726 | static u8 haswell_get_node_id(struct sbridge_pvt *pvt) | ||
727 | { | ||
728 | u32 reg; | ||
729 | |||
730 | pci_read_config_dword(pvt->pci_sad1, SAD_CONTROL, ®); | ||
731 | return GET_BITFIELD(reg, 0, 3); | ||
732 | } | ||
733 | |||
734 | static u64 haswell_get_tolm(struct sbridge_pvt *pvt) | ||
735 | { | ||
736 | u32 reg; | ||
737 | |||
738 | pci_read_config_dword(pvt->info.pci_vtd, TOLM, ®); | ||
739 | return (GET_BITFIELD(reg, 26, 31) << 26) | 0x1ffffff; | ||
740 | } | ||
741 | |||
742 | static u64 haswell_get_tohm(struct sbridge_pvt *pvt) | ||
743 | { | ||
744 | u64 rc; | ||
745 | u32 reg; | ||
746 | |||
747 | pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOHM_0, ®); | ||
748 | rc = GET_BITFIELD(reg, 26, 31); | ||
749 | pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOHM_1, ®); | ||
750 | rc = ((reg << 6) | rc) << 26; | ||
751 | |||
752 | return rc | 0x1ffffff; | ||
753 | } | ||
754 | |||
755 | static u64 haswell_rir_limit(u32 reg) | ||
756 | { | ||
757 | return (((u64)GET_BITFIELD(reg, 1, 11) + 1) << 29) - 1; | ||
758 | } | ||
759 | |||
591 | static inline u8 sad_pkg_socket(u8 pkg) | 760 | static inline u8 sad_pkg_socket(u8 pkg) |
592 | { | 761 | { |
593 | /* on Ivy Bridge, nodeID is SASS, where A is HA and S is node id */ | 762 | /* on Ivy Bridge, nodeID is SASS, where A is HA and S is node id */ |
594 | return (pkg >> 3) | (pkg & 0x3); | 763 | return ((pkg >> 3) << 2) | (pkg & 0x3); |
595 | } | 764 | } |
596 | 765 | ||
597 | static inline u8 sad_pkg_ha(u8 pkg) | 766 | static inline u8 sad_pkg_ha(u8 pkg) |
@@ -602,44 +771,43 @@ static inline u8 sad_pkg_ha(u8 pkg) | |||
602 | /**************************************************************************** | 771 | /**************************************************************************** |
603 | Memory check routines | 772 | Memory check routines |
604 | ****************************************************************************/ | 773 | ****************************************************************************/ |
605 | static struct pci_dev *get_pdev_slot_func(u8 bus, unsigned slot, | 774 | static struct pci_dev *get_pdev_same_bus(u8 bus, u32 id) |
606 | unsigned func) | ||
607 | { | 775 | { |
608 | struct sbridge_dev *sbridge_dev = get_sbridge_dev(bus); | 776 | struct pci_dev *pdev = NULL; |
609 | int i; | ||
610 | |||
611 | if (!sbridge_dev) | ||
612 | return NULL; | ||
613 | |||
614 | for (i = 0; i < sbridge_dev->n_devs; i++) { | ||
615 | if (!sbridge_dev->pdev[i]) | ||
616 | continue; | ||
617 | 777 | ||
618 | if (PCI_SLOT(sbridge_dev->pdev[i]->devfn) == slot && | 778 | do { |
619 | PCI_FUNC(sbridge_dev->pdev[i]->devfn) == func) { | 779 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, id, pdev); |
620 | edac_dbg(1, "Associated %02x.%02x.%d with %p\n", | 780 | if (pdev && pdev->bus->number == bus) |
621 | bus, slot, func, sbridge_dev->pdev[i]); | 781 | break; |
622 | return sbridge_dev->pdev[i]; | 782 | } while (pdev); |
623 | } | ||
624 | } | ||
625 | 783 | ||
626 | return NULL; | 784 | return pdev; |
627 | } | 785 | } |
628 | 786 | ||
629 | /** | 787 | /** |
630 | * check_if_ecc_is_active() - Checks if ECC is active | 788 | * check_if_ecc_is_active() - Checks if ECC is active |
631 | * bus: Device bus | 789 | * @bus: Device bus |
790 | * @type: Memory controller type | ||
791 | * returns: 0 in case ECC is active, -ENODEV if it can't be determined or | ||
792 | * disabled | ||
632 | */ | 793 | */ |
633 | static int check_if_ecc_is_active(const u8 bus) | 794 | static int check_if_ecc_is_active(const u8 bus, enum type type) |
634 | { | 795 | { |
635 | struct pci_dev *pdev = NULL; | 796 | struct pci_dev *pdev = NULL; |
636 | u32 mcmtr; | 797 | u32 mcmtr, id; |
798 | |||
799 | if (type == IVY_BRIDGE) | ||
800 | id = PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA; | ||
801 | else if (type == HASWELL) | ||
802 | id = PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TA; | ||
803 | else | ||
804 | id = PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA; | ||
637 | 805 | ||
638 | pdev = get_pdev_slot_func(bus, 15, 0); | 806 | pdev = get_pdev_same_bus(bus, id); |
639 | if (!pdev) { | 807 | if (!pdev) { |
640 | sbridge_printk(KERN_ERR, "Couldn't find PCI device " | 808 | sbridge_printk(KERN_ERR, "Couldn't find PCI device " |
641 | "%2x.%02d.%d!!!\n", | 809 | "%04x:%04x! on bus %02d\n", |
642 | bus, 15, 0); | 810 | PCI_VENDOR_ID_INTEL, id, bus); |
643 | return -ENODEV; | 811 | return -ENODEV; |
644 | } | 812 | } |
645 | 813 | ||
@@ -661,11 +829,14 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
661 | enum edac_type mode; | 829 | enum edac_type mode; |
662 | enum mem_type mtype; | 830 | enum mem_type mtype; |
663 | 831 | ||
664 | pci_read_config_dword(pvt->pci_br0, SAD_TARGET, ®); | 832 | if (pvt->info.type == HASWELL) |
833 | pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, ®); | ||
834 | else | ||
835 | pci_read_config_dword(pvt->pci_br0, SAD_TARGET, ®); | ||
836 | |||
665 | pvt->sbridge_dev->source_id = SOURCE_ID(reg); | 837 | pvt->sbridge_dev->source_id = SOURCE_ID(reg); |
666 | 838 | ||
667 | pci_read_config_dword(pvt->pci_br0, SAD_CONTROL, ®); | 839 | pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt); |
668 | pvt->sbridge_dev->node_id = NODE_ID(reg); | ||
669 | edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n", | 840 | edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n", |
670 | pvt->sbridge_dev->mc, | 841 | pvt->sbridge_dev->mc, |
671 | pvt->sbridge_dev->node_id, | 842 | pvt->sbridge_dev->node_id, |
@@ -698,24 +869,18 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
698 | pvt->is_close_pg = false; | 869 | pvt->is_close_pg = false; |
699 | } | 870 | } |
700 | 871 | ||
701 | if (pvt->pci_ddrio) { | 872 | mtype = pvt->info.get_memory_type(pvt); |
702 | pci_read_config_dword(pvt->pci_ddrio, pvt->info.rankcfgr, | 873 | if (mtype == MEM_RDDR3 || mtype == MEM_RDDR4) |
703 | ®); | 874 | edac_dbg(0, "Memory is registered\n"); |
704 | if (IS_RDIMM_ENABLED(reg)) { | 875 | else if (mtype == MEM_UNKNOWN) |
705 | /* FIXME: Can also be LRDIMM */ | ||
706 | edac_dbg(0, "Memory is registered\n"); | ||
707 | mtype = MEM_RDDR3; | ||
708 | } else { | ||
709 | edac_dbg(0, "Memory is unregistered\n"); | ||
710 | mtype = MEM_DDR3; | ||
711 | } | ||
712 | } else { | ||
713 | edac_dbg(0, "Cannot determine memory type\n"); | 876 | edac_dbg(0, "Cannot determine memory type\n"); |
714 | mtype = MEM_UNKNOWN; | 877 | else |
715 | } | 878 | edac_dbg(0, "Memory is unregistered\n"); |
716 | 879 | ||
717 | /* On all supported DDR3 DIMM types, there are 8 banks available */ | 880 | if (mtype == MEM_DDR4 || MEM_RDDR4) |
718 | banks = 8; | 881 | banks = 16; |
882 | else | ||
883 | banks = 8; | ||
719 | 884 | ||
720 | for (i = 0; i < NUM_CHANNELS; i++) { | 885 | for (i = 0; i < NUM_CHANNELS; i++) { |
721 | u32 mtr; | 886 | u32 mtr; |
@@ -729,11 +894,10 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
729 | if (IS_DIMM_PRESENT(mtr)) { | 894 | if (IS_DIMM_PRESENT(mtr)) { |
730 | pvt->channel[i].dimms++; | 895 | pvt->channel[i].dimms++; |
731 | 896 | ||
732 | ranks = numrank(mtr); | 897 | ranks = numrank(pvt->info.type, mtr); |
733 | rows = numrow(mtr); | 898 | rows = numrow(mtr); |
734 | cols = numcol(mtr); | 899 | cols = numcol(mtr); |
735 | 900 | ||
736 | /* DDR3 has 8 I/O banks */ | ||
737 | size = ((u64)rows * cols * banks * ranks) >> (20 - 3); | 901 | size = ((u64)rows * cols * banks * ranks) >> (20 - 3); |
738 | npages = MiB_TO_PAGES(size); | 902 | npages = MiB_TO_PAGES(size); |
739 | 903 | ||
@@ -744,7 +908,17 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
744 | 908 | ||
745 | dimm->nr_pages = npages; | 909 | dimm->nr_pages = npages; |
746 | dimm->grain = 32; | 910 | dimm->grain = 32; |
747 | dimm->dtype = (banks == 8) ? DEV_X8 : DEV_X4; | 911 | switch (banks) { |
912 | case 16: | ||
913 | dimm->dtype = DEV_X16; | ||
914 | break; | ||
915 | case 8: | ||
916 | dimm->dtype = DEV_X8; | ||
917 | break; | ||
918 | case 4: | ||
919 | dimm->dtype = DEV_X4; | ||
920 | break; | ||
921 | } | ||
748 | dimm->mtype = mtype; | 922 | dimm->mtype = mtype; |
749 | dimm->edac_mode = mode; | 923 | dimm->edac_mode = mode; |
750 | snprintf(dimm->label, sizeof(dimm->label), | 924 | snprintf(dimm->label, sizeof(dimm->label), |
@@ -887,7 +1061,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci) | |||
887 | if (!IS_RIR_VALID(reg)) | 1061 | if (!IS_RIR_VALID(reg)) |
888 | continue; | 1062 | continue; |
889 | 1063 | ||
890 | tmp_mb = RIR_LIMIT(reg) >> 20; | 1064 | tmp_mb = pvt->info.rir_limit(reg) >> 20; |
891 | rir_way = 1 << RIR_WAY(reg); | 1065 | rir_way = 1 << RIR_WAY(reg); |
892 | mb = div_u64_rem(tmp_mb, 1000, &kb); | 1066 | mb = div_u64_rem(tmp_mb, 1000, &kb); |
893 | edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", | 1067 | edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", |
@@ -936,11 +1110,11 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
936 | struct mem_ctl_info *new_mci; | 1110 | struct mem_ctl_info *new_mci; |
937 | struct sbridge_pvt *pvt = mci->pvt_info; | 1111 | struct sbridge_pvt *pvt = mci->pvt_info; |
938 | struct pci_dev *pci_ha; | 1112 | struct pci_dev *pci_ha; |
939 | int n_rir, n_sads, n_tads, sad_way, sck_xch; | 1113 | int n_rir, n_sads, n_tads, sad_way, sck_xch; |
940 | int sad_interl, idx, base_ch; | 1114 | int sad_interl, idx, base_ch; |
941 | int interleave_mode; | 1115 | int interleave_mode, shiftup = 0; |
942 | unsigned sad_interleave[pvt->info.max_interleave]; | 1116 | unsigned sad_interleave[pvt->info.max_interleave]; |
943 | u32 reg; | 1117 | u32 reg, dram_rule; |
944 | u8 ch_way, sck_way, pkg, sad_ha = 0; | 1118 | u8 ch_way, sck_way, pkg, sad_ha = 0; |
945 | u32 tad_offset; | 1119 | u32 tad_offset; |
946 | u32 rir_way; | 1120 | u32 rir_way; |
@@ -987,8 +1161,9 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
987 | sprintf(msg, "Can't discover the memory socket"); | 1161 | sprintf(msg, "Can't discover the memory socket"); |
988 | return -EINVAL; | 1162 | return -EINVAL; |
989 | } | 1163 | } |
990 | *area_type = get_dram_attr(reg); | 1164 | dram_rule = reg; |
991 | interleave_mode = INTERLEAVE_MODE(reg); | 1165 | *area_type = get_dram_attr(dram_rule); |
1166 | interleave_mode = INTERLEAVE_MODE(dram_rule); | ||
992 | 1167 | ||
993 | pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads], | 1168 | pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads], |
994 | ®); | 1169 | ®); |
@@ -1033,6 +1208,36 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
1033 | *socket = sad_interleave[idx]; | 1208 | *socket = sad_interleave[idx]; |
1034 | edac_dbg(0, "SAD interleave index: %d (wayness %d) = CPU socket %d\n", | 1209 | edac_dbg(0, "SAD interleave index: %d (wayness %d) = CPU socket %d\n", |
1035 | idx, sad_way, *socket); | 1210 | idx, sad_way, *socket); |
1211 | } else if (pvt->info.type == HASWELL) { | ||
1212 | int bits, a7mode = A7MODE(dram_rule); | ||
1213 | |||
1214 | if (a7mode) { | ||
1215 | /* A7 mode swaps P9 with P6 */ | ||
1216 | bits = GET_BITFIELD(addr, 7, 8) << 1; | ||
1217 | bits |= GET_BITFIELD(addr, 9, 9); | ||
1218 | } else | ||
1219 | bits = GET_BITFIELD(addr, 7, 9); | ||
1220 | |||
1221 | if (interleave_mode) { | ||
1222 | /* interleave mode will XOR {8,7,6} with {18,17,16} */ | ||
1223 | idx = GET_BITFIELD(addr, 16, 18); | ||
1224 | idx ^= bits; | ||
1225 | } else | ||
1226 | idx = bits; | ||
1227 | |||
1228 | pkg = sad_pkg(pvt->info.interleave_pkg, reg, idx); | ||
1229 | *socket = sad_pkg_socket(pkg); | ||
1230 | sad_ha = sad_pkg_ha(pkg); | ||
1231 | |||
1232 | if (a7mode) { | ||
1233 | /* MCChanShiftUpEnable */ | ||
1234 | pci_read_config_dword(pvt->pci_ha0, | ||
1235 | HASWELL_HASYSDEFEATURE2, ®); | ||
1236 | shiftup = GET_BITFIELD(reg, 22, 22); | ||
1237 | } | ||
1238 | |||
1239 | edac_dbg(0, "SAD interleave package: %d = CPU socket %d, HA %i, shiftup: %i\n", | ||
1240 | idx, *socket, sad_ha, shiftup); | ||
1036 | } else { | 1241 | } else { |
1037 | /* Ivy Bridge's SAD mode doesn't support XOR interleave mode */ | 1242 | /* Ivy Bridge's SAD mode doesn't support XOR interleave mode */ |
1038 | idx = (addr >> 6) & 7; | 1243 | idx = (addr >> 6) & 7; |
@@ -1090,7 +1295,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
1090 | if (ch_way == 3) | 1295 | if (ch_way == 3) |
1091 | idx = addr >> 6; | 1296 | idx = addr >> 6; |
1092 | else | 1297 | else |
1093 | idx = addr >> (6 + sck_way); | 1298 | idx = (addr >> (6 + sck_way + shiftup)) & 0x3; |
1094 | idx = idx % ch_way; | 1299 | idx = idx % ch_way; |
1095 | 1300 | ||
1096 | /* | 1301 | /* |
@@ -1181,7 +1386,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
1181 | if (!IS_RIR_VALID(reg)) | 1386 | if (!IS_RIR_VALID(reg)) |
1182 | continue; | 1387 | continue; |
1183 | 1388 | ||
1184 | limit = RIR_LIMIT(reg); | 1389 | limit = pvt->info.rir_limit(reg); |
1185 | mb = div_u64_rem(limit >> 20, 1000, &kb); | 1390 | mb = div_u64_rem(limit >> 20, 1000, &kb); |
1186 | edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", | 1391 | edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", |
1187 | n_rir, | 1392 | n_rir, |
@@ -1197,6 +1402,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
1197 | return -EINVAL; | 1402 | return -EINVAL; |
1198 | } | 1403 | } |
1199 | rir_way = RIR_WAY(reg); | 1404 | rir_way = RIR_WAY(reg); |
1405 | |||
1200 | if (pvt->is_close_pg) | 1406 | if (pvt->is_close_pg) |
1201 | idx = (ch_addr >> 6); | 1407 | idx = (ch_addr >> 6); |
1202 | else | 1408 | else |
@@ -1259,13 +1465,11 @@ static int sbridge_get_onedevice(struct pci_dev **prev, | |||
1259 | { | 1465 | { |
1260 | struct sbridge_dev *sbridge_dev; | 1466 | struct sbridge_dev *sbridge_dev; |
1261 | const struct pci_id_descr *dev_descr = &table->descr[devno]; | 1467 | const struct pci_id_descr *dev_descr = &table->descr[devno]; |
1262 | |||
1263 | struct pci_dev *pdev = NULL; | 1468 | struct pci_dev *pdev = NULL; |
1264 | u8 bus = 0; | 1469 | u8 bus = 0; |
1265 | 1470 | ||
1266 | sbridge_printk(KERN_DEBUG, | 1471 | sbridge_printk(KERN_DEBUG, |
1267 | "Seeking for: dev %02x.%d PCI ID %04x:%04x\n", | 1472 | "Seeking for: PCI ID %04x:%04x\n", |
1268 | dev_descr->dev, dev_descr->func, | ||
1269 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | 1473 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); |
1270 | 1474 | ||
1271 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1475 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
@@ -1280,12 +1484,12 @@ static int sbridge_get_onedevice(struct pci_dev **prev, | |||
1280 | if (dev_descr->optional) | 1484 | if (dev_descr->optional) |
1281 | return 0; | 1485 | return 0; |
1282 | 1486 | ||
1487 | /* if the HA wasn't found */ | ||
1283 | if (devno == 0) | 1488 | if (devno == 0) |
1284 | return -ENODEV; | 1489 | return -ENODEV; |
1285 | 1490 | ||
1286 | sbridge_printk(KERN_INFO, | 1491 | sbridge_printk(KERN_INFO, |
1287 | "Device not found: dev %02x.%d PCI ID %04x:%04x\n", | 1492 | "Device not found: %04x:%04x\n", |
1288 | dev_descr->dev, dev_descr->func, | ||
1289 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | 1493 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); |
1290 | 1494 | ||
1291 | /* End of list, leave */ | 1495 | /* End of list, leave */ |
@@ -1305,9 +1509,7 @@ static int sbridge_get_onedevice(struct pci_dev **prev, | |||
1305 | 1509 | ||
1306 | if (sbridge_dev->pdev[devno]) { | 1510 | if (sbridge_dev->pdev[devno]) { |
1307 | sbridge_printk(KERN_ERR, | 1511 | sbridge_printk(KERN_ERR, |
1308 | "Duplicated device for " | 1512 | "Duplicated device for %04x:%04x\n", |
1309 | "dev %02x:%d.%d PCI ID %04x:%04x\n", | ||
1310 | bus, dev_descr->dev, dev_descr->func, | ||
1311 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | 1513 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); |
1312 | pci_dev_put(pdev); | 1514 | pci_dev_put(pdev); |
1313 | return -ENODEV; | 1515 | return -ENODEV; |
@@ -1315,30 +1517,15 @@ static int sbridge_get_onedevice(struct pci_dev **prev, | |||
1315 | 1517 | ||
1316 | sbridge_dev->pdev[devno] = pdev; | 1518 | sbridge_dev->pdev[devno] = pdev; |
1317 | 1519 | ||
1318 | /* Sanity check */ | ||
1319 | if (unlikely(PCI_SLOT(pdev->devfn) != dev_descr->dev || | ||
1320 | PCI_FUNC(pdev->devfn) != dev_descr->func)) { | ||
1321 | sbridge_printk(KERN_ERR, | ||
1322 | "Device PCI ID %04x:%04x " | ||
1323 | "has dev %02x:%d.%d instead of dev %02x:%02x.%d\n", | ||
1324 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id, | ||
1325 | bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | ||
1326 | bus, dev_descr->dev, dev_descr->func); | ||
1327 | return -ENODEV; | ||
1328 | } | ||
1329 | |||
1330 | /* Be sure that the device is enabled */ | 1520 | /* Be sure that the device is enabled */ |
1331 | if (unlikely(pci_enable_device(pdev) < 0)) { | 1521 | if (unlikely(pci_enable_device(pdev) < 0)) { |
1332 | sbridge_printk(KERN_ERR, | 1522 | sbridge_printk(KERN_ERR, |
1333 | "Couldn't enable " | 1523 | "Couldn't enable %04x:%04x\n", |
1334 | "dev %02x:%d.%d PCI ID %04x:%04x\n", | ||
1335 | bus, dev_descr->dev, dev_descr->func, | ||
1336 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | 1524 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); |
1337 | return -ENODEV; | 1525 | return -ENODEV; |
1338 | } | 1526 | } |
1339 | 1527 | ||
1340 | edac_dbg(0, "Detected dev %02x:%d.%d PCI ID %04x:%04x\n", | 1528 | edac_dbg(0, "Detected %04x:%04x\n", |
1341 | bus, dev_descr->dev, dev_descr->func, | ||
1342 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | 1529 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); |
1343 | 1530 | ||
1344 | /* | 1531 | /* |
@@ -1355,10 +1542,9 @@ static int sbridge_get_onedevice(struct pci_dev **prev, | |||
1355 | 1542 | ||
1356 | /* | 1543 | /* |
1357 | * sbridge_get_all_devices - Find and perform 'get' operation on the MCH's | 1544 | * sbridge_get_all_devices - Find and perform 'get' operation on the MCH's |
1358 | * device/functions we want to reference for this driver. | 1545 | * devices we want to reference for this driver. |
1359 | * Need to 'get' device 16 func 1 and func 2. | ||
1360 | * @num_mc: pointer to the memory controllers count, to be incremented in case | 1546 | * @num_mc: pointer to the memory controllers count, to be incremented in case |
1361 | * of success. | 1547 | * of success. |
1362 | * @table: model specific table | 1548 | * @table: model specific table |
1363 | * | 1549 | * |
1364 | * returns 0 in case of success or error code | 1550 | * returns 0 in case of success or error code |
@@ -1396,79 +1582,51 @@ static int sbridge_mci_bind_devs(struct mem_ctl_info *mci, | |||
1396 | { | 1582 | { |
1397 | struct sbridge_pvt *pvt = mci->pvt_info; | 1583 | struct sbridge_pvt *pvt = mci->pvt_info; |
1398 | struct pci_dev *pdev; | 1584 | struct pci_dev *pdev; |
1399 | int i, func, slot; | 1585 | int i; |
1400 | 1586 | ||
1401 | for (i = 0; i < sbridge_dev->n_devs; i++) { | 1587 | for (i = 0; i < sbridge_dev->n_devs; i++) { |
1402 | pdev = sbridge_dev->pdev[i]; | 1588 | pdev = sbridge_dev->pdev[i]; |
1403 | if (!pdev) | 1589 | if (!pdev) |
1404 | continue; | 1590 | continue; |
1405 | slot = PCI_SLOT(pdev->devfn); | 1591 | |
1406 | func = PCI_FUNC(pdev->devfn); | 1592 | switch (pdev->device) { |
1407 | switch (slot) { | 1593 | case PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0: |
1408 | case 12: | 1594 | pvt->pci_sad0 = pdev; |
1409 | switch (func) { | ||
1410 | case 6: | ||
1411 | pvt->pci_sad0 = pdev; | ||
1412 | break; | ||
1413 | case 7: | ||
1414 | pvt->pci_sad1 = pdev; | ||
1415 | break; | ||
1416 | default: | ||
1417 | goto error; | ||
1418 | } | ||
1419 | break; | 1595 | break; |
1420 | case 13: | 1596 | case PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1: |
1421 | switch (func) { | 1597 | pvt->pci_sad1 = pdev; |
1422 | case 6: | ||
1423 | pvt->pci_br0 = pdev; | ||
1424 | break; | ||
1425 | default: | ||
1426 | goto error; | ||
1427 | } | ||
1428 | break; | 1598 | break; |
1429 | case 14: | 1599 | case PCI_DEVICE_ID_INTEL_SBRIDGE_BR: |
1430 | switch (func) { | 1600 | pvt->pci_br0 = pdev; |
1431 | case 0: | ||
1432 | pvt->pci_ha0 = pdev; | ||
1433 | break; | ||
1434 | default: | ||
1435 | goto error; | ||
1436 | } | ||
1437 | break; | 1601 | break; |
1438 | case 15: | 1602 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0: |
1439 | switch (func) { | 1603 | pvt->pci_ha0 = pdev; |
1440 | case 0: | ||
1441 | pvt->pci_ta = pdev; | ||
1442 | break; | ||
1443 | case 1: | ||
1444 | pvt->pci_ras = pdev; | ||
1445 | break; | ||
1446 | case 2: | ||
1447 | case 3: | ||
1448 | case 4: | ||
1449 | case 5: | ||
1450 | pvt->pci_tad[func - 2] = pdev; | ||
1451 | break; | ||
1452 | default: | ||
1453 | goto error; | ||
1454 | } | ||
1455 | break; | 1604 | break; |
1456 | case 17: | 1605 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA: |
1457 | switch (func) { | 1606 | pvt->pci_ta = pdev; |
1458 | case 0: | 1607 | break; |
1459 | pvt->pci_ddrio = pdev; | 1608 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS: |
1460 | break; | 1609 | pvt->pci_ras = pdev; |
1461 | default: | 1610 | break; |
1462 | goto error; | 1611 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD0: |
1463 | } | 1612 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1: |
1613 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2: | ||
1614 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3: | ||
1615 | { | ||
1616 | int id = pdev->device - PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD0; | ||
1617 | pvt->pci_tad[id] = pdev; | ||
1618 | } | ||
1619 | break; | ||
1620 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO: | ||
1621 | pvt->pci_ddrio = pdev; | ||
1464 | break; | 1622 | break; |
1465 | default: | 1623 | default: |
1466 | goto error; | 1624 | goto error; |
1467 | } | 1625 | } |
1468 | 1626 | ||
1469 | edac_dbg(0, "Associated PCI %02x.%02d.%d with dev = %p\n", | 1627 | edac_dbg(0, "Associated PCI %02x:%02x, bus %d with dev = %p\n", |
1628 | pdev->vendor, pdev->device, | ||
1470 | sbridge_dev->bus, | 1629 | sbridge_dev->bus, |
1471 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | ||
1472 | pdev); | 1630 | pdev); |
1473 | } | 1631 | } |
1474 | 1632 | ||
@@ -1488,9 +1646,8 @@ enodev: | |||
1488 | return -ENODEV; | 1646 | return -ENODEV; |
1489 | 1647 | ||
1490 | error: | 1648 | error: |
1491 | sbridge_printk(KERN_ERR, "Device %d, function %d " | 1649 | sbridge_printk(KERN_ERR, "Unexpected device %02x:%02x\n", |
1492 | "is out of the expected range\n", | 1650 | PCI_VENDOR_ID_INTEL, pdev->device); |
1493 | slot, func); | ||
1494 | return -EINVAL; | 1651 | return -EINVAL; |
1495 | } | 1652 | } |
1496 | 1653 | ||
@@ -1499,7 +1656,7 @@ static int ibridge_mci_bind_devs(struct mem_ctl_info *mci, | |||
1499 | { | 1656 | { |
1500 | struct sbridge_pvt *pvt = mci->pvt_info; | 1657 | struct sbridge_pvt *pvt = mci->pvt_info; |
1501 | struct pci_dev *pdev, *tmp; | 1658 | struct pci_dev *pdev, *tmp; |
1502 | int i, func, slot; | 1659 | int i; |
1503 | bool mode_2ha = false; | 1660 | bool mode_2ha = false; |
1504 | 1661 | ||
1505 | tmp = pci_get_device(PCI_VENDOR_ID_INTEL, | 1662 | tmp = pci_get_device(PCI_VENDOR_ID_INTEL, |
@@ -1513,79 +1670,60 @@ static int ibridge_mci_bind_devs(struct mem_ctl_info *mci, | |||
1513 | pdev = sbridge_dev->pdev[i]; | 1670 | pdev = sbridge_dev->pdev[i]; |
1514 | if (!pdev) | 1671 | if (!pdev) |
1515 | continue; | 1672 | continue; |
1516 | slot = PCI_SLOT(pdev->devfn); | ||
1517 | func = PCI_FUNC(pdev->devfn); | ||
1518 | 1673 | ||
1519 | switch (slot) { | 1674 | switch (pdev->device) { |
1520 | case 14: | 1675 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0: |
1521 | if (func == 0) { | 1676 | pvt->pci_ha0 = pdev; |
1522 | pvt->pci_ha0 = pdev; | 1677 | break; |
1523 | break; | 1678 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA: |
1524 | } | 1679 | pvt->pci_ta = pdev; |
1525 | goto error; | 1680 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_RAS: |
1526 | case 15: | 1681 | pvt->pci_ras = pdev; |
1527 | switch (func) { | 1682 | break; |
1528 | case 0: | 1683 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD2: |
1529 | pvt->pci_ta = pdev; | 1684 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD3: |
1530 | break; | 1685 | /* if we have 2 HAs active, channels 2 and 3 |
1531 | case 1: | 1686 | * are in other device */ |
1532 | pvt->pci_ras = pdev; | 1687 | if (mode_2ha) |
1533 | break; | ||
1534 | case 4: | ||
1535 | case 5: | ||
1536 | /* if we have 2 HAs active, channels 2 and 3 | ||
1537 | * are in other device */ | ||
1538 | if (mode_2ha) | ||
1539 | break; | ||
1540 | /* fall through */ | ||
1541 | case 2: | ||
1542 | case 3: | ||
1543 | pvt->pci_tad[func - 2] = pdev; | ||
1544 | break; | 1688 | break; |
1545 | default: | 1689 | /* fall through */ |
1546 | goto error; | 1690 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD0: |
1547 | } | 1691 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD1: |
1692 | { | ||
1693 | int id = pdev->device - PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD0; | ||
1694 | pvt->pci_tad[id] = pdev; | ||
1695 | } | ||
1548 | break; | 1696 | break; |
1549 | case 17: | 1697 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_2HA_DDRIO0: |
1550 | if (func == 4) { | 1698 | pvt->pci_ddrio = pdev; |
1699 | break; | ||
1700 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_1HA_DDRIO0: | ||
1701 | if (!mode_2ha) | ||
1551 | pvt->pci_ddrio = pdev; | 1702 | pvt->pci_ddrio = pdev; |
1552 | break; | ||
1553 | } else if (func == 0) { | ||
1554 | if (!mode_2ha) | ||
1555 | pvt->pci_ddrio = pdev; | ||
1556 | break; | ||
1557 | } | ||
1558 | goto error; | ||
1559 | case 22: | ||
1560 | switch (func) { | ||
1561 | case 0: | ||
1562 | pvt->pci_sad0 = pdev; | ||
1563 | break; | ||
1564 | case 1: | ||
1565 | pvt->pci_br0 = pdev; | ||
1566 | break; | ||
1567 | case 2: | ||
1568 | pvt->pci_br1 = pdev; | ||
1569 | break; | ||
1570 | default: | ||
1571 | goto error; | ||
1572 | } | ||
1573 | break; | 1703 | break; |
1574 | case 28: | 1704 | case PCI_DEVICE_ID_INTEL_IBRIDGE_SAD: |
1575 | if (func == 0) { | 1705 | pvt->pci_sad0 = pdev; |
1576 | pvt->pci_ha1 = pdev; | 1706 | break; |
1577 | break; | 1707 | case PCI_DEVICE_ID_INTEL_IBRIDGE_BR0: |
1578 | } | 1708 | pvt->pci_br0 = pdev; |
1579 | goto error; | 1709 | break; |
1580 | case 29: | 1710 | case PCI_DEVICE_ID_INTEL_IBRIDGE_BR1: |
1711 | pvt->pci_br1 = pdev; | ||
1712 | break; | ||
1713 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1: | ||
1714 | pvt->pci_ha1 = pdev; | ||
1715 | break; | ||
1716 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD0: | ||
1717 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD1: | ||
1718 | { | ||
1719 | int id = pdev->device - PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD0 + 2; | ||
1720 | |||
1581 | /* we shouldn't have this device if we have just one | 1721 | /* we shouldn't have this device if we have just one |
1582 | * HA present */ | 1722 | * HA present */ |
1583 | WARN_ON(!mode_2ha); | 1723 | WARN_ON(!mode_2ha); |
1584 | if (func == 2 || func == 3) { | 1724 | pvt->pci_tad[id] = pdev; |
1585 | pvt->pci_tad[func] = pdev; | 1725 | } |
1586 | break; | 1726 | break; |
1587 | } | ||
1588 | goto error; | ||
1589 | default: | 1727 | default: |
1590 | goto error; | 1728 | goto error; |
1591 | } | 1729 | } |
@@ -1614,11 +1752,111 @@ enodev: | |||
1614 | 1752 | ||
1615 | error: | 1753 | error: |
1616 | sbridge_printk(KERN_ERR, | 1754 | sbridge_printk(KERN_ERR, |
1617 | "Device %d, function %d is out of the expected range\n", | 1755 | "Unexpected device %02x:%02x\n", PCI_VENDOR_ID_INTEL, |
1618 | slot, func); | 1756 | pdev->device); |
1619 | return -EINVAL; | 1757 | return -EINVAL; |
1620 | } | 1758 | } |
1621 | 1759 | ||
1760 | static int haswell_mci_bind_devs(struct mem_ctl_info *mci, | ||
1761 | struct sbridge_dev *sbridge_dev) | ||
1762 | { | ||
1763 | struct sbridge_pvt *pvt = mci->pvt_info; | ||
1764 | struct pci_dev *pdev, *tmp; | ||
1765 | int i; | ||
1766 | bool mode_2ha = false; | ||
1767 | |||
1768 | tmp = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
1769 | PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1, NULL); | ||
1770 | if (tmp) { | ||
1771 | mode_2ha = true; | ||
1772 | pci_dev_put(tmp); | ||
1773 | } | ||
1774 | |||
1775 | /* there's only one device per system; not tied to any bus */ | ||
1776 | if (pvt->info.pci_vtd == NULL) | ||
1777 | /* result will be checked later */ | ||
1778 | pvt->info.pci_vtd = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
1779 | PCI_DEVICE_ID_INTEL_HASWELL_IMC_VTD_MISC, | ||
1780 | NULL); | ||
1781 | |||
1782 | for (i = 0; i < sbridge_dev->n_devs; i++) { | ||
1783 | pdev = sbridge_dev->pdev[i]; | ||
1784 | if (!pdev) | ||
1785 | continue; | ||
1786 | |||
1787 | switch (pdev->device) { | ||
1788 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_CBO_SAD0: | ||
1789 | pvt->pci_sad0 = pdev; | ||
1790 | break; | ||
1791 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_CBO_SAD1: | ||
1792 | pvt->pci_sad1 = pdev; | ||
1793 | break; | ||
1794 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0: | ||
1795 | pvt->pci_ha0 = pdev; | ||
1796 | break; | ||
1797 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TA: | ||
1798 | pvt->pci_ta = pdev; | ||
1799 | break; | ||
1800 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_THERMAL: | ||
1801 | pvt->pci_ras = pdev; | ||
1802 | break; | ||
1803 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD0: | ||
1804 | pvt->pci_tad[0] = pdev; | ||
1805 | break; | ||
1806 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD1: | ||
1807 | pvt->pci_tad[1] = pdev; | ||
1808 | break; | ||
1809 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD2: | ||
1810 | if (!mode_2ha) | ||
1811 | pvt->pci_tad[2] = pdev; | ||
1812 | break; | ||
1813 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD3: | ||
1814 | if (!mode_2ha) | ||
1815 | pvt->pci_tad[3] = pdev; | ||
1816 | break; | ||
1817 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0: | ||
1818 | pvt->pci_ddrio = pdev; | ||
1819 | break; | ||
1820 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1: | ||
1821 | pvt->pci_ha1 = pdev; | ||
1822 | break; | ||
1823 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TA: | ||
1824 | pvt->pci_ha1_ta = pdev; | ||
1825 | break; | ||
1826 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD0: | ||
1827 | if (mode_2ha) | ||
1828 | pvt->pci_tad[2] = pdev; | ||
1829 | break; | ||
1830 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD1: | ||
1831 | if (mode_2ha) | ||
1832 | pvt->pci_tad[3] = pdev; | ||
1833 | break; | ||
1834 | default: | ||
1835 | break; | ||
1836 | } | ||
1837 | |||
1838 | edac_dbg(0, "Associated PCI %02x.%02d.%d with dev = %p\n", | ||
1839 | sbridge_dev->bus, | ||
1840 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | ||
1841 | pdev); | ||
1842 | } | ||
1843 | |||
1844 | /* Check if everything were registered */ | ||
1845 | if (!pvt->pci_sad0 || !pvt->pci_ha0 || !pvt->pci_sad1 || | ||
1846 | !pvt->pci_ras || !pvt->pci_ta || !pvt->info.pci_vtd) | ||
1847 | goto enodev; | ||
1848 | |||
1849 | for (i = 0; i < NUM_CHANNELS; i++) { | ||
1850 | if (!pvt->pci_tad[i]) | ||
1851 | goto enodev; | ||
1852 | } | ||
1853 | return 0; | ||
1854 | |||
1855 | enodev: | ||
1856 | sbridge_printk(KERN_ERR, "Some needed devices are missing\n"); | ||
1857 | return -ENODEV; | ||
1858 | } | ||
1859 | |||
1622 | /**************************************************************************** | 1860 | /**************************************************************************** |
1623 | Error check routines | 1861 | Error check routines |
1624 | ****************************************************************************/ | 1862 | ****************************************************************************/ |
@@ -1736,6 +1974,9 @@ static void sbridge_mce_output_error(struct mem_ctl_info *mci, | |||
1736 | * EDAC core should be handling the channel mask, in order to point | 1974 | * EDAC core should be handling the channel mask, in order to point |
1737 | * to the group of dimm's where the error may be happening. | 1975 | * to the group of dimm's where the error may be happening. |
1738 | */ | 1976 | */ |
1977 | if (!pvt->is_lockstep && !pvt->is_mirrored && !pvt->is_close_pg) | ||
1978 | channel = first_channel; | ||
1979 | |||
1739 | snprintf(msg, sizeof(msg), | 1980 | snprintf(msg, sizeof(msg), |
1740 | "%s%s area:%s err_code:%04x:%04x socket:%d channel_mask:%ld rank:%d", | 1981 | "%s%s area:%s err_code:%04x:%04x socket:%d channel_mask:%ld rank:%d", |
1741 | overflow ? " OVERFLOW" : "", | 1982 | overflow ? " OVERFLOW" : "", |
@@ -1865,10 +2106,6 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val, | |||
1865 | "%u APIC %x\n", mce->cpuvendor, mce->cpuid, | 2106 | "%u APIC %x\n", mce->cpuvendor, mce->cpuid, |
1866 | mce->time, mce->socketid, mce->apicid); | 2107 | mce->time, mce->socketid, mce->apicid); |
1867 | 2108 | ||
1868 | /* Only handle if it is the right mc controller */ | ||
1869 | if (cpu_data(mce->cpu).phys_proc_id != pvt->sbridge_dev->mc) | ||
1870 | return NOTIFY_DONE; | ||
1871 | |||
1872 | smp_rmb(); | 2109 | smp_rmb(); |
1873 | if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { | 2110 | if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { |
1874 | smp_wmb(); | 2111 | smp_wmb(); |
@@ -1932,7 +2169,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) | |||
1932 | int rc; | 2169 | int rc; |
1933 | 2170 | ||
1934 | /* Check the number of active and not disabled channels */ | 2171 | /* Check the number of active and not disabled channels */ |
1935 | rc = check_if_ecc_is_active(sbridge_dev->bus); | 2172 | rc = check_if_ecc_is_active(sbridge_dev->bus, type); |
1936 | if (unlikely(rc < 0)) | 2173 | if (unlikely(rc < 0)) |
1937 | return rc; | 2174 | return rc; |
1938 | 2175 | ||
@@ -1971,11 +2208,15 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) | |||
1971 | mci->edac_check = sbridge_check_error; | 2208 | mci->edac_check = sbridge_check_error; |
1972 | 2209 | ||
1973 | pvt->info.type = type; | 2210 | pvt->info.type = type; |
1974 | if (type == IVY_BRIDGE) { | 2211 | switch (type) { |
2212 | case IVY_BRIDGE: | ||
1975 | pvt->info.rankcfgr = IB_RANK_CFG_A; | 2213 | pvt->info.rankcfgr = IB_RANK_CFG_A; |
1976 | pvt->info.get_tolm = ibridge_get_tolm; | 2214 | pvt->info.get_tolm = ibridge_get_tolm; |
1977 | pvt->info.get_tohm = ibridge_get_tohm; | 2215 | pvt->info.get_tohm = ibridge_get_tohm; |
1978 | pvt->info.dram_rule = ibridge_dram_rule; | 2216 | pvt->info.dram_rule = ibridge_dram_rule; |
2217 | pvt->info.get_memory_type = get_memory_type; | ||
2218 | pvt->info.get_node_id = get_node_id; | ||
2219 | pvt->info.rir_limit = rir_limit; | ||
1979 | pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule); | 2220 | pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule); |
1980 | pvt->info.interleave_list = ibridge_interleave_list; | 2221 | pvt->info.interleave_list = ibridge_interleave_list; |
1981 | pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); | 2222 | pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); |
@@ -1986,11 +2227,15 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) | |||
1986 | rc = ibridge_mci_bind_devs(mci, sbridge_dev); | 2227 | rc = ibridge_mci_bind_devs(mci, sbridge_dev); |
1987 | if (unlikely(rc < 0)) | 2228 | if (unlikely(rc < 0)) |
1988 | goto fail0; | 2229 | goto fail0; |
1989 | } else { | 2230 | break; |
2231 | case SANDY_BRIDGE: | ||
1990 | pvt->info.rankcfgr = SB_RANK_CFG_A; | 2232 | pvt->info.rankcfgr = SB_RANK_CFG_A; |
1991 | pvt->info.get_tolm = sbridge_get_tolm; | 2233 | pvt->info.get_tolm = sbridge_get_tolm; |
1992 | pvt->info.get_tohm = sbridge_get_tohm; | 2234 | pvt->info.get_tohm = sbridge_get_tohm; |
1993 | pvt->info.dram_rule = sbridge_dram_rule; | 2235 | pvt->info.dram_rule = sbridge_dram_rule; |
2236 | pvt->info.get_memory_type = get_memory_type; | ||
2237 | pvt->info.get_node_id = get_node_id; | ||
2238 | pvt->info.rir_limit = rir_limit; | ||
1994 | pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule); | 2239 | pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule); |
1995 | pvt->info.interleave_list = sbridge_interleave_list; | 2240 | pvt->info.interleave_list = sbridge_interleave_list; |
1996 | pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); | 2241 | pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); |
@@ -2001,8 +2246,27 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) | |||
2001 | rc = sbridge_mci_bind_devs(mci, sbridge_dev); | 2246 | rc = sbridge_mci_bind_devs(mci, sbridge_dev); |
2002 | if (unlikely(rc < 0)) | 2247 | if (unlikely(rc < 0)) |
2003 | goto fail0; | 2248 | goto fail0; |
2004 | } | 2249 | break; |
2250 | case HASWELL: | ||
2251 | /* rankcfgr isn't used */ | ||
2252 | pvt->info.get_tolm = haswell_get_tolm; | ||
2253 | pvt->info.get_tohm = haswell_get_tohm; | ||
2254 | pvt->info.dram_rule = ibridge_dram_rule; | ||
2255 | pvt->info.get_memory_type = haswell_get_memory_type; | ||
2256 | pvt->info.get_node_id = haswell_get_node_id; | ||
2257 | pvt->info.rir_limit = haswell_rir_limit; | ||
2258 | pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule); | ||
2259 | pvt->info.interleave_list = ibridge_interleave_list; | ||
2260 | pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); | ||
2261 | pvt->info.interleave_pkg = ibridge_interleave_pkg; | ||
2262 | mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell Socket#%d", mci->mc_idx); | ||
2005 | 2263 | ||
2264 | /* Store pci devices at mci for faster access */ | ||
2265 | rc = haswell_mci_bind_devs(mci, sbridge_dev); | ||
2266 | if (unlikely(rc < 0)) | ||
2267 | goto fail0; | ||
2268 | break; | ||
2269 | } | ||
2006 | 2270 | ||
2007 | /* Get dimm basic config and the memory layout */ | 2271 | /* Get dimm basic config and the memory layout */ |
2008 | get_dimm_config(mci); | 2272 | get_dimm_config(mci); |
@@ -2037,10 +2301,10 @@ fail0: | |||
2037 | 2301 | ||
2038 | static int sbridge_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 2302 | static int sbridge_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
2039 | { | 2303 | { |
2040 | int rc; | 2304 | int rc = -ENODEV; |
2041 | u8 mc, num_mc = 0; | 2305 | u8 mc, num_mc = 0; |
2042 | struct sbridge_dev *sbridge_dev; | 2306 | struct sbridge_dev *sbridge_dev; |
2043 | enum type type; | 2307 | enum type type = SANDY_BRIDGE; |
2044 | 2308 | ||
2045 | /* get the pci devices we want to reserve for our use */ | 2309 | /* get the pci devices we want to reserve for our use */ |
2046 | mutex_lock(&sbridge_edac_lock); | 2310 | mutex_lock(&sbridge_edac_lock); |
@@ -2054,12 +2318,19 @@ static int sbridge_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2054 | } | 2318 | } |
2055 | probed++; | 2319 | probed++; |
2056 | 2320 | ||
2057 | if (pdev->device == PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA) { | 2321 | switch (pdev->device) { |
2322 | case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA: | ||
2058 | rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_ibridge_table); | 2323 | rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_ibridge_table); |
2059 | type = IVY_BRIDGE; | 2324 | type = IVY_BRIDGE; |
2060 | } else { | 2325 | break; |
2326 | case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA: | ||
2061 | rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_sbridge_table); | 2327 | rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_sbridge_table); |
2062 | type = SANDY_BRIDGE; | 2328 | type = SANDY_BRIDGE; |
2329 | break; | ||
2330 | case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0: | ||
2331 | rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_haswell_table); | ||
2332 | type = HASWELL; | ||
2333 | break; | ||
2063 | } | 2334 | } |
2064 | if (unlikely(rc < 0)) | 2335 | if (unlikely(rc < 0)) |
2065 | goto fail0; | 2336 | goto fail0; |
@@ -2068,6 +2339,7 @@ static int sbridge_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2068 | list_for_each_entry(sbridge_dev, &sbridge_edac_list, list) { | 2339 | list_for_each_entry(sbridge_dev, &sbridge_edac_list, list) { |
2069 | edac_dbg(0, "Registering MC#%d (%d of %d)\n", | 2340 | edac_dbg(0, "Registering MC#%d (%d of %d)\n", |
2070 | mc, mc + 1, num_mc); | 2341 | mc, mc + 1, num_mc); |
2342 | |||
2071 | sbridge_dev->mc = mc++; | 2343 | sbridge_dev->mc = mc++; |
2072 | rc = sbridge_register_mci(sbridge_dev, type); | 2344 | rc = sbridge_register_mci(sbridge_dev, type); |
2073 | if (unlikely(rc < 0)) | 2345 | if (unlikely(rc < 0)) |
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index 10598dede9e9..68bf06768123 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c | |||
@@ -132,12 +132,12 @@ nvkm_client_notify_new(struct nouveau_client *client, | |||
132 | if (ret == 0) { | 132 | if (ret == 0) { |
133 | client->notify[index] = notify; | 133 | client->notify[index] = notify; |
134 | notify->client = client; | 134 | notify->client = client; |
135 | return 0; | 135 | return index; |
136 | } | 136 | } |
137 | } | 137 | } |
138 | 138 | ||
139 | kfree(notify); | 139 | kfree(notify); |
140 | return 0; | 140 | return ret; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int | 143 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 54ec53bc6252..cdf9147f32a1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c | |||
@@ -163,6 +163,7 @@ nve0_identify(struct nouveau_device *device) | |||
163 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 163 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
164 | device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass; | 164 | device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass; |
165 | device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass; | 165 | device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass; |
166 | device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; | ||
166 | device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass; | 167 | device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass; |
167 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 168 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
168 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 169 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index db19191176fa..30fd1dc64f93 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | |||
@@ -68,6 +68,9 @@ nvc0_graph_zbc_color_get(struct nvc0_graph_priv *priv, int format, | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | if (zbc < 0) | ||
72 | return zbc; | ||
73 | |||
71 | memcpy(priv->zbc_color[zbc].ds, ds, sizeof(priv->zbc_color[zbc].ds)); | 74 | memcpy(priv->zbc_color[zbc].ds, ds, sizeof(priv->zbc_color[zbc].ds)); |
72 | memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2)); | 75 | memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2)); |
73 | priv->zbc_color[zbc].format = format; | 76 | priv->zbc_color[zbc].format = format; |
@@ -109,6 +112,9 @@ nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format, | |||
109 | } | 112 | } |
110 | } | 113 | } |
111 | 114 | ||
115 | if (zbc < 0) | ||
116 | return zbc; | ||
117 | |||
112 | priv->zbc_depth[zbc].format = format; | 118 | priv->zbc_depth[zbc].format = format; |
113 | priv->zbc_depth[zbc].ds = ds; | 119 | priv->zbc_depth[zbc].ds = ds; |
114 | priv->zbc_depth[zbc].l2 = l2; | 120 | priv->zbc_depth[zbc].l2 = l2; |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h index 4fc6ab12382d..1794a05205d8 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/drivers/gpu/drm/nouveau/core/include/core/client.h | |||
@@ -14,7 +14,7 @@ struct nouveau_client { | |||
14 | void *data; | 14 | void *data; |
15 | 15 | ||
16 | int (*ntfy)(const void *, u32, const void *, u32); | 16 | int (*ntfy)(const void *, u32, const void *, u32); |
17 | struct nvkm_client_notify *notify[8]; | 17 | struct nvkm_client_notify *notify[16]; |
18 | }; | 18 | }; |
19 | 19 | ||
20 | static inline struct nouveau_client * | 20 | static inline struct nouveau_client * |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c index 73b1ed20c8d5..8bcbdf39cfb2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c | |||
@@ -99,8 +99,13 @@ nouveau_bar_alloc(struct nouveau_bar *bar, struct nouveau_object *parent, | |||
99 | struct nouveau_mem *mem, struct nouveau_object **pobject) | 99 | struct nouveau_mem *mem, struct nouveau_object **pobject) |
100 | { | 100 | { |
101 | struct nouveau_object *engine = nv_object(bar); | 101 | struct nouveau_object *engine = nv_object(bar); |
102 | return nouveau_object_ctor(parent, engine, &nouveau_barobj_oclass, | 102 | int ret = -ENOMEM; |
103 | mem, 0, pobject); | 103 | if (bar->iomem) { |
104 | ret = nouveau_object_ctor(parent, engine, | ||
105 | &nouveau_barobj_oclass, | ||
106 | mem, 0, pobject); | ||
107 | } | ||
108 | return ret; | ||
104 | } | 109 | } |
105 | 110 | ||
106 | int | 111 | int |
@@ -118,9 +123,12 @@ nouveau_bar_create_(struct nouveau_object *parent, | |||
118 | if (ret) | 123 | if (ret) |
119 | return ret; | 124 | return ret; |
120 | 125 | ||
121 | if (nv_device_resource_len(device, 3) != 0) | 126 | if (nv_device_resource_len(device, 3) != 0) { |
122 | bar->iomem = ioremap(nv_device_resource_start(device, 3), | 127 | bar->iomem = ioremap(nv_device_resource_start(device, 3), |
123 | nv_device_resource_len(device, 3)); | 128 | nv_device_resource_len(device, 3)); |
129 | if (!bar->iomem) | ||
130 | nv_warn(bar, "PRAMIN ioremap failed\n"); | ||
131 | } | ||
124 | 132 | ||
125 | return 0; | 133 | return 0; |
126 | } | 134 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c index 946518572346..2b284b192763 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c | |||
@@ -554,13 +554,13 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, | |||
554 | } else { | 554 | } else { |
555 | /* otherwise, address lowest common amount from 0GiB */ | 555 | /* otherwise, address lowest common amount from 0GiB */ |
556 | ret = nouveau_mm_init(&pfb->vram, rsvd_head, | 556 | ret = nouveau_mm_init(&pfb->vram, rsvd_head, |
557 | (bsize << 8) * parts, 1); | 557 | (bsize << 8) * parts - rsvd_head, 1); |
558 | if (ret) | 558 | if (ret) |
559 | return ret; | 559 | return ret; |
560 | 560 | ||
561 | /* and the rest starting from (8GiB + common_size) */ | 561 | /* and the rest starting from (8GiB + common_size) */ |
562 | offset = (0x0200000000ULL >> 12) + (bsize << 8); | 562 | offset = (0x0200000000ULL >> 12) + (bsize << 8); |
563 | length = (ram->size >> 12) - (bsize << 8) - rsvd_tail; | 563 | length = (ram->size >> 12) - ((bsize * parts) << 8) - rsvd_tail; |
564 | 564 | ||
565 | ret = nouveau_mm_init(&pfb->vram, offset, length, 0); | 565 | ret = nouveau_mm_init(&pfb->vram, offset, length, 0); |
566 | if (ret) | 566 | if (ret) |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c index 9e00a1ede120..b54b582e72c4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c | |||
@@ -156,7 +156,7 @@ gf100_ltc_init_tag_ram(struct nouveau_fb *pfb, struct nvkm_ltc_priv *priv) | |||
156 | if (ret) { | 156 | if (ret) { |
157 | priv->num_tags = 0; | 157 | priv->num_tags = 0; |
158 | } else { | 158 | } else { |
159 | u64 tag_base = (priv->tag_ram->offset << 12) + tag_margin; | 159 | u64 tag_base = ((u64)priv->tag_ram->offset << 12) + tag_margin; |
160 | 160 | ||
161 | tag_base += tag_align - 1; | 161 | tag_base += tag_align - 1; |
162 | ret = do_div(tag_base, tag_align); | 162 | ret = do_div(tag_base, tag_align); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index da5d631aa5b9..01da508625f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -1228,7 +1228,6 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | |||
1228 | struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; | 1228 | struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; |
1229 | struct nouveau_drm *drm = nouveau_bdev(bdev); | 1229 | struct nouveau_drm *drm = nouveau_bdev(bdev); |
1230 | struct nouveau_mem *node = mem->mm_node; | 1230 | struct nouveau_mem *node = mem->mm_node; |
1231 | struct drm_device *dev = drm->dev; | ||
1232 | int ret; | 1231 | int ret; |
1233 | 1232 | ||
1234 | mem->bus.addr = NULL; | 1233 | mem->bus.addr = NULL; |
@@ -1247,7 +1246,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | |||
1247 | if (drm->agp.stat == ENABLED) { | 1246 | if (drm->agp.stat == ENABLED) { |
1248 | mem->bus.offset = mem->start << PAGE_SHIFT; | 1247 | mem->bus.offset = mem->start << PAGE_SHIFT; |
1249 | mem->bus.base = drm->agp.base; | 1248 | mem->bus.base = drm->agp.base; |
1250 | mem->bus.is_iomem = !dev->agp->cant_use_aperture; | 1249 | mem->bus.is_iomem = !drm->dev->agp->cant_use_aperture; |
1251 | } | 1250 | } |
1252 | #endif | 1251 | #endif |
1253 | if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA || !node->memtype) | 1252 | if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA || !node->memtype) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 1cc7b603c753..65b4fd53dd4e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -592,7 +592,9 @@ nouveau_display_repin(struct drm_device *dev) | |||
592 | if (!nouveau_fb || !nouveau_fb->nvbo) | 592 | if (!nouveau_fb || !nouveau_fb->nvbo) |
593 | continue; | 593 | continue; |
594 | 594 | ||
595 | nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); | 595 | ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); |
596 | if (ret) | ||
597 | NV_ERROR(drm, "Could not pin framebuffer\n"); | ||
596 | } | 598 | } |
597 | 599 | ||
598 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 600 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ebfe3180109e..8bdd27091db8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -226,7 +226,7 @@ nouveau_fbcon_accel_restore(struct drm_device *dev) | |||
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | void | 229 | static void |
230 | nouveau_fbcon_accel_fini(struct drm_device *dev) | 230 | nouveau_fbcon_accel_fini(struct drm_device *dev) |
231 | { | 231 | { |
232 | struct nouveau_drm *drm = nouveau_drm(dev); | 232 | struct nouveau_drm *drm = nouveau_drm(dev); |
@@ -246,7 +246,7 @@ nouveau_fbcon_accel_fini(struct drm_device *dev) | |||
246 | } | 246 | } |
247 | } | 247 | } |
248 | 248 | ||
249 | void | 249 | static void |
250 | nouveau_fbcon_accel_init(struct drm_device *dev) | 250 | nouveau_fbcon_accel_init(struct drm_device *dev) |
251 | { | 251 | { |
252 | struct nouveau_drm *drm = nouveau_drm(dev); | 252 | struct nouveau_drm *drm = nouveau_drm(dev); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 0ffeb50d0088..246a824c16ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c | |||
@@ -149,7 +149,8 @@ power_down: | |||
149 | static int nouveau_platform_remove(struct platform_device *pdev) | 149 | static int nouveau_platform_remove(struct platform_device *pdev) |
150 | { | 150 | { |
151 | struct drm_device *drm_dev = platform_get_drvdata(pdev); | 151 | struct drm_device *drm_dev = platform_get_drvdata(pdev); |
152 | struct nouveau_device *device = nouveau_dev(drm_dev); | 152 | struct nouveau_drm *drm = nouveau_drm(drm_dev); |
153 | struct nouveau_device *device = nvkm_device(&drm->device); | ||
153 | struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu; | 154 | struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu; |
154 | 155 | ||
155 | nouveau_drm_device_remove(drm_dev); | 156 | nouveau_drm_device_remove(drm_dev); |
diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index cc81e0e5fd30..573491f84792 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h | |||
@@ -428,8 +428,8 @@ struct nv50_disp_dac_pwr_v0 { | |||
428 | struct nv50_disp_dac_load_v0 { | 428 | struct nv50_disp_dac_load_v0 { |
429 | __u8 version; | 429 | __u8 version; |
430 | __u8 load; | 430 | __u8 load; |
431 | __u16 data; | 431 | __u8 pad02[2]; |
432 | __u8 pad04[4]; | 432 | __u32 data; |
433 | }; | 433 | }; |
434 | 434 | ||
435 | struct nv50_disp_sor_pwr_v0 { | 435 | struct nv50_disp_sor_pwr_v0 { |
diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 7c06123a559c..0898c3155292 100644 --- a/drivers/gpu/drm/nouveau/nvif/notify.c +++ b/drivers/gpu/drm/nouveau/nvif/notify.c | |||
@@ -87,12 +87,25 @@ nvif_notify_get(struct nvif_notify *notify) | |||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | 89 | ||
90 | static inline int | ||
91 | nvif_notify_func(struct nvif_notify *notify, bool keep) | ||
92 | { | ||
93 | int ret = notify->func(notify); | ||
94 | if (ret == NVIF_NOTIFY_KEEP || | ||
95 | !test_and_clear_bit(NVKM_NOTIFY_USER, ¬ify->flags)) { | ||
96 | if (!keep) | ||
97 | atomic_dec(¬ify->putcnt); | ||
98 | else | ||
99 | nvif_notify_get_(notify); | ||
100 | } | ||
101 | return ret; | ||
102 | } | ||
103 | |||
90 | static void | 104 | static void |
91 | nvif_notify_work(struct work_struct *work) | 105 | nvif_notify_work(struct work_struct *work) |
92 | { | 106 | { |
93 | struct nvif_notify *notify = container_of(work, typeof(*notify), work); | 107 | struct nvif_notify *notify = container_of(work, typeof(*notify), work); |
94 | if (notify->func(notify) == NVIF_NOTIFY_KEEP) | 108 | nvif_notify_func(notify, true); |
95 | nvif_notify_get_(notify); | ||
96 | } | 109 | } |
97 | 110 | ||
98 | int | 111 | int |
@@ -113,19 +126,15 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size) | |||
113 | if (!WARN_ON(notify == NULL)) { | 126 | if (!WARN_ON(notify == NULL)) { |
114 | struct nvif_client *client = nvif_client(notify->object); | 127 | struct nvif_client *client = nvif_client(notify->object); |
115 | if (!WARN_ON(notify->size != size)) { | 128 | if (!WARN_ON(notify->size != size)) { |
129 | atomic_inc(¬ify->putcnt); | ||
116 | if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { | 130 | if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { |
117 | atomic_inc(¬ify->putcnt); | ||
118 | memcpy((void *)notify->data, data, size); | 131 | memcpy((void *)notify->data, data, size); |
119 | schedule_work(¬ify->work); | 132 | schedule_work(¬ify->work); |
120 | return NVIF_NOTIFY_DROP; | 133 | return NVIF_NOTIFY_DROP; |
121 | } | 134 | } |
122 | notify->data = data; | 135 | notify->data = data; |
123 | ret = notify->func(notify); | 136 | ret = nvif_notify_func(notify, client->driver->keep); |
124 | notify->data = NULL; | 137 | notify->data = NULL; |
125 | if (ret != NVIF_NOTIFY_DROP && client->driver->keep) { | ||
126 | atomic_inc(¬ify->putcnt); | ||
127 | nvif_notify_get_(notify); | ||
128 | } | ||
129 | } | 138 | } |
130 | } | 139 | } |
131 | 140 | ||
@@ -228,8 +237,10 @@ nvif_notify_new(struct nvif_object *object, int (*func)(struct nvif_notify *), | |||
228 | if (notify) { | 237 | if (notify) { |
229 | int ret = nvif_notify_init(object, nvif_notify_del, func, work, | 238 | int ret = nvif_notify_init(object, nvif_notify_del, func, work, |
230 | type, data, size, reply, notify); | 239 | type, data, size, reply, notify); |
231 | if (ret) | 240 | if (ret) { |
232 | kfree(notify); | 241 | kfree(notify); |
242 | notify = NULL; | ||
243 | } | ||
233 | *pnotify = notify; | 244 | *pnotify = notify; |
234 | return ret; | 245 | return ret; |
235 | } | 246 | } |
diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index b0c82206ece2..dd85b56f6aa5 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c | |||
@@ -275,8 +275,10 @@ nvif_object_new(struct nvif_object *parent, u32 handle, u32 oclass, | |||
275 | if (object) { | 275 | if (object) { |
276 | int ret = nvif_object_init(parent, nvif_object_del, handle, | 276 | int ret = nvif_object_init(parent, nvif_object_del, handle, |
277 | oclass, data, size, object); | 277 | oclass, data, size, object); |
278 | if (ret) | 278 | if (ret) { |
279 | kfree(object); | 279 | kfree(object); |
280 | object = NULL; | ||
281 | } | ||
280 | *pobject = object; | 282 | *pobject = object; |
281 | return ret; | 283 | return ret; |
282 | } | 284 | } |
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index 1bdcccc54a1d..f745d2c1325e 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c | |||
@@ -28,7 +28,7 @@ | |||
28 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 28 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
29 | unsigned int *rsize) | 29 | unsigned int *rsize) |
30 | { | 30 | { |
31 | if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | 31 | if (*rsize >= 18 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { |
32 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); | 32 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); |
33 | rdesc[11] = rdesc[16] = 0xff; | 33 | rdesc[11] = rdesc[16] = 0xff; |
34 | rdesc[12] = rdesc[17] = 0x03; | 34 | rdesc[12] = rdesc[17] = 0x03; |
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c index 60f44cd1b0ed..61b68ca27790 100644 --- a/drivers/hid/hid-huion.c +++ b/drivers/hid/hid-huion.c | |||
@@ -84,6 +84,15 @@ static const __u8 huion_tablet_rdesc_template[] = { | |||
84 | 0xC0 /* End Collection */ | 84 | 0xC0 /* End Collection */ |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* Parameter indices */ | ||
88 | enum huion_prm { | ||
89 | HUION_PRM_X_LM = 1, | ||
90 | HUION_PRM_Y_LM = 2, | ||
91 | HUION_PRM_PRESSURE_LM = 4, | ||
92 | HUION_PRM_RESOLUTION = 5, | ||
93 | HUION_PRM_NUM | ||
94 | }; | ||
95 | |||
87 | /* Driver data */ | 96 | /* Driver data */ |
88 | struct huion_drvdata { | 97 | struct huion_drvdata { |
89 | __u8 *rdesc; | 98 | __u8 *rdesc; |
@@ -115,7 +124,12 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
115 | int rc; | 124 | int rc; |
116 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | 125 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); |
117 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); | 126 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); |
118 | __le16 buf[6]; | 127 | __le16 *buf = NULL; |
128 | size_t len; | ||
129 | s32 params[HUION_PH_ID_NUM]; | ||
130 | s32 resolution; | ||
131 | __u8 *p; | ||
132 | s32 v; | ||
119 | 133 | ||
120 | /* | 134 | /* |
121 | * Read string descriptor containing tablet parameters. The specific | 135 | * Read string descriptor containing tablet parameters. The specific |
@@ -123,65 +137,79 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
123 | * driver traffic. | 137 | * driver traffic. |
124 | * NOTE: This enables fully-functional tablet mode. | 138 | * NOTE: This enables fully-functional tablet mode. |
125 | */ | 139 | */ |
140 | len = HUION_PRM_NUM * sizeof(*buf); | ||
141 | buf = kmalloc(len, GFP_KERNEL); | ||
142 | if (buf == NULL) { | ||
143 | hid_err(hdev, "failed to allocate parameter buffer\n"); | ||
144 | rc = -ENOMEM; | ||
145 | goto cleanup; | ||
146 | } | ||
126 | rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 147 | rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
127 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 148 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
128 | (USB_DT_STRING << 8) + 0x64, | 149 | (USB_DT_STRING << 8) + 0x64, |
129 | 0x0409, buf, sizeof(buf), | 150 | 0x0409, buf, len, |
130 | USB_CTRL_GET_TIMEOUT); | 151 | USB_CTRL_GET_TIMEOUT); |
131 | if (rc == -EPIPE) | 152 | if (rc == -EPIPE) { |
132 | hid_warn(hdev, "device parameters not found\n"); | 153 | hid_err(hdev, "device parameters not found\n"); |
133 | else if (rc < 0) | 154 | rc = -ENODEV; |
134 | hid_warn(hdev, "failed to get device parameters: %d\n", rc); | 155 | goto cleanup; |
135 | else if (rc != sizeof(buf)) | 156 | } else if (rc < 0) { |
136 | hid_warn(hdev, "invalid device parameters\n"); | 157 | hid_err(hdev, "failed to get device parameters: %d\n", rc); |
137 | else { | 158 | rc = -ENODEV; |
138 | s32 params[HUION_PH_ID_NUM]; | 159 | goto cleanup; |
139 | s32 resolution; | 160 | } else if (rc != len) { |
140 | __u8 *p; | 161 | hid_err(hdev, "invalid device parameters\n"); |
141 | s32 v; | 162 | rc = -ENODEV; |
163 | goto cleanup; | ||
164 | } | ||
142 | 165 | ||
143 | /* Extract device parameters */ | 166 | /* Extract device parameters */ |
144 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); | 167 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]); |
145 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); | 168 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]); |
146 | params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); | 169 | params[HUION_PH_ID_PRESSURE_LM] = |
147 | resolution = le16_to_cpu(buf[5]); | 170 | le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]); |
148 | if (resolution == 0) { | 171 | resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]); |
149 | params[HUION_PH_ID_X_PM] = 0; | 172 | if (resolution == 0) { |
150 | params[HUION_PH_ID_Y_PM] = 0; | 173 | params[HUION_PH_ID_X_PM] = 0; |
151 | } else { | 174 | params[HUION_PH_ID_Y_PM] = 0; |
152 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * | 175 | } else { |
153 | 1000 / resolution; | 176 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * |
154 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * | 177 | 1000 / resolution; |
155 | 1000 / resolution; | 178 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * |
156 | } | 179 | 1000 / resolution; |
180 | } | ||
157 | 181 | ||
158 | /* Allocate fixed report descriptor */ | 182 | /* Allocate fixed report descriptor */ |
159 | drvdata->rdesc = devm_kmalloc(&hdev->dev, | 183 | drvdata->rdesc = devm_kmalloc(&hdev->dev, |
160 | sizeof(huion_tablet_rdesc_template), | 184 | sizeof(huion_tablet_rdesc_template), |
161 | GFP_KERNEL); | 185 | GFP_KERNEL); |
162 | if (drvdata->rdesc == NULL) { | 186 | if (drvdata->rdesc == NULL) { |
163 | hid_err(hdev, "failed to allocate fixed rdesc\n"); | 187 | hid_err(hdev, "failed to allocate fixed rdesc\n"); |
164 | return -ENOMEM; | 188 | rc = -ENOMEM; |
165 | } | 189 | goto cleanup; |
166 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | 190 | } |
191 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | ||
167 | 192 | ||
168 | /* Format fixed report descriptor */ | 193 | /* Format fixed report descriptor */ |
169 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, | 194 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, |
170 | drvdata->rsize); | 195 | drvdata->rsize); |
171 | for (p = drvdata->rdesc; | 196 | for (p = drvdata->rdesc; |
172 | p <= drvdata->rdesc + drvdata->rsize - 4;) { | 197 | p <= drvdata->rdesc + drvdata->rsize - 4;) { |
173 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && | 198 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && |
174 | p[3] < sizeof(params)) { | 199 | p[3] < sizeof(params)) { |
175 | v = params[p[3]]; | 200 | v = params[p[3]]; |
176 | put_unaligned(cpu_to_le32(v), (s32 *)p); | 201 | put_unaligned(cpu_to_le32(v), (s32 *)p); |
177 | p += 4; | 202 | p += 4; |
178 | } else { | 203 | } else { |
179 | p++; | 204 | p++; |
180 | } | ||
181 | } | 205 | } |
182 | } | 206 | } |
183 | 207 | ||
184 | return 0; | 208 | rc = 0; |
209 | |||
210 | cleanup: | ||
211 | kfree(buf); | ||
212 | return rc; | ||
185 | } | 213 | } |
186 | 214 | ||
187 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) | 215 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index e77696367591..b92bf01a1ae8 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
@@ -300,7 +300,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
300 | * - change the button usage range to 4-7 for the extra | 300 | * - change the button usage range to 4-7 for the extra |
301 | * buttons | 301 | * buttons |
302 | */ | 302 | */ |
303 | if (*rsize >= 74 && | 303 | if (*rsize >= 75 && |
304 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && | 304 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && |
305 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && | 305 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && |
306 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && | 306 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a976f48263f6..f91ff145db9a 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -345,14 +345,14 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
345 | struct usb_device_descriptor *udesc; | 345 | struct usb_device_descriptor *udesc; |
346 | __u16 bcdDevice, rev_maj, rev_min; | 346 | __u16 bcdDevice, rev_maj, rev_min; |
347 | 347 | ||
348 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | 348 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 91 && rdesc[83] == 0x26 && |
349 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 349 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
350 | hid_info(hdev, | 350 | hid_info(hdev, |
351 | "fixing up Logitech keyboard report descriptor\n"); | 351 | "fixing up Logitech keyboard report descriptor\n"); |
352 | rdesc[84] = rdesc[89] = 0x4d; | 352 | rdesc[84] = rdesc[89] = 0x4d; |
353 | rdesc[85] = rdesc[90] = 0x10; | 353 | rdesc[85] = rdesc[90] = 0x10; |
354 | } | 354 | } |
355 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && | 355 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 && |
356 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && | 356 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && |
357 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { | 357 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { |
358 | hid_info(hdev, | 358 | hid_info(hdev, |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index cc2bd2022198..7835717bc020 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
@@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at | |||
451 | drv_data = hid_get_drvdata(hid); | 451 | drv_data = hid_get_drvdata(hid); |
452 | if (!drv_data) { | 452 | if (!drv_data) { |
453 | hid_err(hid, "Private driver data not found!\n"); | 453 | hid_err(hid, "Private driver data not found!\n"); |
454 | return 0; | 454 | return -EINVAL; |
455 | } | 455 | } |
456 | 456 | ||
457 | entry = drv_data->device_props; | 457 | entry = drv_data->device_props; |
458 | if (!entry) { | 458 | if (!entry) { |
459 | hid_err(hid, "Device properties not found!\n"); | 459 | hid_err(hid, "Device properties not found!\n"); |
460 | return 0; | 460 | return -EINVAL; |
461 | } | 461 | } |
462 | 462 | ||
463 | if (range == 0) | 463 | if (range == 0) |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 486dbde2ba2d..b7ba82960c79 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -238,13 +238,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
238 | return; | 238 | return; |
239 | } | 239 | } |
240 | 240 | ||
241 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
242 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
243 | dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n", | ||
244 | __func__, dj_report->device_index); | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { | 241 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { |
249 | /* The device is already known. No need to reallocate it. */ | 242 | /* The device is already known. No need to reallocate it. */ |
250 | dbg_hid("%s: device is already known\n", __func__); | 243 | dbg_hid("%s: device is already known\n", __func__); |
@@ -557,7 +550,7 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, | |||
557 | if (!out_buf) | 550 | if (!out_buf) |
558 | return -ENOMEM; | 551 | return -ENOMEM; |
559 | 552 | ||
560 | if (count < DJREPORT_SHORT_LENGTH - 2) | 553 | if (count > DJREPORT_SHORT_LENGTH - 2) |
561 | count = DJREPORT_SHORT_LENGTH - 2; | 554 | count = DJREPORT_SHORT_LENGTH - 2; |
562 | 555 | ||
563 | out_buf[0] = REPORT_ID_DJ_SHORT; | 556 | out_buf[0] = REPORT_ID_DJ_SHORT; |
@@ -690,6 +683,12 @@ static int logi_dj_raw_event(struct hid_device *hdev, | |||
690 | * device (via hid_input_report() ) and return 1 so hid-core does not do | 683 | * device (via hid_input_report() ) and return 1 so hid-core does not do |
691 | * anything else with it. | 684 | * anything else with it. |
692 | */ | 685 | */ |
686 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
687 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
688 | dev_err(&hdev->dev, "%s: invalid device index:%d\n", | ||
689 | __func__, dj_report->device_index); | ||
690 | return false; | ||
691 | } | ||
693 | 692 | ||
694 | spin_lock_irqsave(&djrcv_dev->lock, flags); | 693 | spin_lock_irqsave(&djrcv_dev->lock, flags); |
695 | if (dj_report->report_id == REPORT_ID_DJ_SHORT) { | 694 | if (dj_report->report_id == REPORT_ID_DJ_SHORT) { |
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c index 9e14c00eb1b6..25daf28b26bd 100644 --- a/drivers/hid/hid-monterey.c +++ b/drivers/hid/hid-monterey.c | |||
@@ -24,7 +24,7 @@ | |||
24 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 24 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
25 | unsigned int *rsize) | 25 | unsigned int *rsize) |
26 | { | 26 | { |
27 | if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { | 27 | if (*rsize >= 31 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { |
28 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); | 28 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); |
29 | rdesc[30] = 0x0c; | 29 | rdesc[30] = 0x0c; |
30 | } | 30 | } |
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 736b2502df4f..6aca4f2554bf 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c | |||
@@ -25,7 +25,7 @@ | |||
25 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 25 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
26 | unsigned int *rsize) | 26 | unsigned int *rsize) |
27 | { | 27 | { |
28 | if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && | 28 | if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && |
29 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && | 29 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && |
30 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { | 30 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { |
31 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); | 31 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 0dc25142f451..8389e8109218 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
@@ -909,10 +909,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
909 | return ret; | 909 | return ret; |
910 | } | 910 | } |
911 | 911 | ||
912 | if (!test_bit(RMI_STARTED, &data->flags)) { | 912 | if (!test_bit(RMI_STARTED, &data->flags)) |
913 | hid_hw_stop(hdev); | 913 | /* |
914 | return -EIO; | 914 | * The device maybe in the bootloader if rmi_input_configured |
915 | } | 915 | * failed to find F11 in the PDT. Print an error, but don't |
916 | * return an error from rmi_probe so that hidraw will be | ||
917 | * accessible from userspace. That way a userspace tool | ||
918 | * can be used to reload working firmware on the touchpad. | ||
919 | */ | ||
920 | hid_err(hdev, "Device failed to be properly configured\n"); | ||
916 | 921 | ||
917 | return 0; | 922 | return 0; |
918 | } | 923 | } |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index e244e449cbba..2ac25760a9a9 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -604,9 +604,9 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
604 | ret = -EINVAL; | 604 | ret = -EINVAL; |
605 | goto err_stop_hw; | 605 | goto err_stop_hw; |
606 | } | 606 | } |
607 | sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * | 607 | sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt * |
608 | sizeof(struct mfd_cell), | 608 | sizeof(struct mfd_cell), |
609 | GFP_KERNEL); | 609 | GFP_KERNEL); |
610 | if (sd->hid_sensor_hub_client_devs == NULL) { | 610 | if (sd->hid_sensor_hub_client_devs == NULL) { |
611 | hid_err(hdev, "Failed to allocate memory for mfd cells\n"); | 611 | hid_err(hdev, "Failed to allocate memory for mfd cells\n"); |
612 | ret = -ENOMEM; | 612 | ret = -ENOMEM; |
@@ -618,11 +618,12 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
618 | 618 | ||
619 | if (collection->type == HID_COLLECTION_PHYSICAL) { | 619 | if (collection->type == HID_COLLECTION_PHYSICAL) { |
620 | 620 | ||
621 | hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL); | 621 | hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), |
622 | GFP_KERNEL); | ||
622 | if (!hsdev) { | 623 | if (!hsdev) { |
623 | hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); | 624 | hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); |
624 | ret = -ENOMEM; | 625 | ret = -ENOMEM; |
625 | goto err_no_mem; | 626 | goto err_stop_hw; |
626 | } | 627 | } |
627 | hsdev->hdev = hdev; | 628 | hsdev->hdev = hdev; |
628 | hsdev->vendor_id = hdev->vendor; | 629 | hsdev->vendor_id = hdev->vendor; |
@@ -631,13 +632,13 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
631 | if (last_hsdev) | 632 | if (last_hsdev) |
632 | last_hsdev->end_collection_index = i; | 633 | last_hsdev->end_collection_index = i; |
633 | last_hsdev = hsdev; | 634 | last_hsdev = hsdev; |
634 | name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", | 635 | name = devm_kasprintf(&hdev->dev, GFP_KERNEL, |
635 | collection->usage); | 636 | "HID-SENSOR-%x", |
637 | collection->usage); | ||
636 | if (name == NULL) { | 638 | if (name == NULL) { |
637 | hid_err(hdev, "Failed MFD device name\n"); | 639 | hid_err(hdev, "Failed MFD device name\n"); |
638 | ret = -ENOMEM; | 640 | ret = -ENOMEM; |
639 | kfree(hsdev); | 641 | goto err_stop_hw; |
640 | goto err_no_mem; | ||
641 | } | 642 | } |
642 | sd->hid_sensor_hub_client_devs[ | 643 | sd->hid_sensor_hub_client_devs[ |
643 | sd->hid_sensor_client_cnt].id = | 644 | sd->hid_sensor_client_cnt].id = |
@@ -661,16 +662,10 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
661 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, | 662 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, |
662 | sd->hid_sensor_client_cnt, NULL, 0, NULL); | 663 | sd->hid_sensor_client_cnt, NULL, 0, NULL); |
663 | if (ret < 0) | 664 | if (ret < 0) |
664 | goto err_no_mem; | 665 | goto err_stop_hw; |
665 | 666 | ||
666 | return ret; | 667 | return ret; |
667 | 668 | ||
668 | err_no_mem: | ||
669 | for (i = 0; i < sd->hid_sensor_client_cnt; ++i) { | ||
670 | kfree(sd->hid_sensor_hub_client_devs[i].name); | ||
671 | kfree(sd->hid_sensor_hub_client_devs[i].platform_data); | ||
672 | } | ||
673 | kfree(sd->hid_sensor_hub_client_devs); | ||
674 | err_stop_hw: | 669 | err_stop_hw: |
675 | hid_hw_stop(hdev); | 670 | hid_hw_stop(hdev); |
676 | 671 | ||
@@ -681,7 +676,6 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
681 | { | 676 | { |
682 | struct sensor_hub_data *data = hid_get_drvdata(hdev); | 677 | struct sensor_hub_data *data = hid_get_drvdata(hdev); |
683 | unsigned long flags; | 678 | unsigned long flags; |
684 | int i; | ||
685 | 679 | ||
686 | hid_dbg(hdev, " hardware removed\n"); | 680 | hid_dbg(hdev, " hardware removed\n"); |
687 | hid_hw_close(hdev); | 681 | hid_hw_close(hdev); |
@@ -691,11 +685,6 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
691 | complete(&data->pending.ready); | 685 | complete(&data->pending.ready); |
692 | spin_unlock_irqrestore(&data->lock, flags); | 686 | spin_unlock_irqrestore(&data->lock, flags); |
693 | mfd_remove_devices(&hdev->dev); | 687 | mfd_remove_devices(&hdev->dev); |
694 | for (i = 0; i < data->hid_sensor_client_cnt; ++i) { | ||
695 | kfree(data->hid_sensor_hub_client_devs[i].name); | ||
696 | kfree(data->hid_sensor_hub_client_devs[i].platform_data); | ||
697 | } | ||
698 | kfree(data->hid_sensor_hub_client_devs); | ||
699 | hid_set_drvdata(hdev, NULL); | 688 | hid_set_drvdata(hdev, NULL); |
700 | mutex_destroy(&data->mutex); | 689 | mutex_destroy(&data->mutex); |
701 | } | 690 | } |
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c index 87fc91e1c8de..91072fa54663 100644 --- a/drivers/hid/hid-sunplus.c +++ b/drivers/hid/hid-sunplus.c | |||
@@ -24,7 +24,7 @@ | |||
24 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 24 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
25 | unsigned int *rsize) | 25 | unsigned int *rsize) |
26 | { | 26 | { |
27 | if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && | 27 | if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && |
28 | rdesc[106] == 0x03) { | 28 | rdesc[106] == 0x03) { |
29 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); | 29 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); |
30 | rdesc[105] = rdesc[110] = 0x03; | 30 | rdesc[105] = rdesc[110] = 0x03; |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 3e388ec31da8..f0db7eca9023 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -1416,6 +1416,7 @@ static void wacom_remove(struct hid_device *hdev) | |||
1416 | kfree(wacom); | 1416 | kfree(wacom); |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | #ifdef CONFIG_PM | ||
1419 | static int wacom_resume(struct hid_device *hdev) | 1420 | static int wacom_resume(struct hid_device *hdev) |
1420 | { | 1421 | { |
1421 | struct wacom *wacom = hid_get_drvdata(hdev); | 1422 | struct wacom *wacom = hid_get_drvdata(hdev); |
@@ -1436,6 +1437,7 @@ static int wacom_reset_resume(struct hid_device *hdev) | |||
1436 | { | 1437 | { |
1437 | return wacom_resume(hdev); | 1438 | return wacom_resume(hdev); |
1438 | } | 1439 | } |
1440 | #endif /* CONFIG_PM */ | ||
1439 | 1441 | ||
1440 | static struct hid_driver wacom_driver = { | 1442 | static struct hid_driver wacom_driver = { |
1441 | .name = "wacom", | 1443 | .name = "wacom", |
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 3e3b680dc007..b51a402752c4 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig | |||
@@ -23,17 +23,14 @@ config I2C | |||
23 | This I2C support can also be built as a module. If so, the module | 23 | This I2C support can also be built as a module. If so, the module |
24 | will be called i2c-core. | 24 | will be called i2c-core. |
25 | 25 | ||
26 | config I2C_ACPI | 26 | config ACPI_I2C_OPREGION |
27 | bool "I2C ACPI support" | 27 | bool "ACPI I2C Operation region support" |
28 | select I2C | 28 | depends on I2C=y && ACPI |
29 | depends on ACPI | ||
30 | default y | 29 | default y |
31 | help | 30 | help |
32 | Say Y here if you want to enable ACPI I2C support. This includes support | 31 | Say Y here if you want to enable ACPI I2C operation region support. |
33 | for automatic enumeration of I2C slave devices and support for ACPI I2C | 32 | Operation Regions allow firmware (BIOS) code to access I2C slave devices, |
34 | Operation Regions. Operation Regions allow firmware (BIOS) code to | 33 | such as smart batteries through an I2C host controller driver. |
35 | access I2C slave devices, such as smart batteries through an I2C host | ||
36 | controller driver. | ||
37 | 34 | ||
38 | if I2C | 35 | if I2C |
39 | 36 | ||
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index a1f590cbb435..e0228b228256 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | i2ccore-y := i2c-core.o | 5 | i2ccore-y := i2c-core.o |
6 | i2ccore-$(CONFIG_I2C_ACPI) += i2c-acpi.o | 6 | i2ccore-$(CONFIG_ACPI) += i2c-acpi.o |
7 | 7 | ||
8 | obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o | 8 | obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o |
9 | obj-$(CONFIG_I2C) += i2ccore.o | 9 | obj-$(CONFIG_I2C) += i2ccore.o |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 2994690b26e9..10467a327749 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -164,6 +164,7 @@ | |||
164 | 164 | ||
165 | /* Older devices have their ID defined in <linux/pci_ids.h> */ | 165 | /* Older devices have their ID defined in <linux/pci_ids.h> */ |
166 | #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 | 166 | #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 |
167 | #define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292 | ||
167 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 | 168 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 |
168 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 | 169 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 |
169 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ | 170 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ |
@@ -828,6 +829,7 @@ static const struct pci_device_id i801_ids[] = { | |||
828 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, | 829 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, |
829 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, | 830 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, |
830 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, | 831 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, |
832 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, | ||
831 | { 0, } | 833 | { 0, } |
832 | }; | 834 | }; |
833 | 835 | ||
diff --git a/drivers/i2c/i2c-acpi.c b/drivers/i2c/i2c-acpi.c index e8b61967334b..0dbc18c15c43 100644 --- a/drivers/i2c/i2c-acpi.c +++ b/drivers/i2c/i2c-acpi.c | |||
@@ -126,6 +126,7 @@ void acpi_i2c_register_devices(struct i2c_adapter *adap) | |||
126 | dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); | 126 | dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); |
127 | } | 127 | } |
128 | 128 | ||
129 | #ifdef CONFIG_ACPI_I2C_OPREGION | ||
129 | static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, | 130 | static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, |
130 | u8 cmd, u8 *data, u8 data_len) | 131 | u8 cmd, u8 *data, u8 data_len) |
131 | { | 132 | { |
@@ -360,3 +361,4 @@ void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter) | |||
360 | 361 | ||
361 | acpi_bus_detach_private_data(handle); | 362 | acpi_bus_detach_private_data(handle); |
362 | } | 363 | } |
364 | #endif | ||
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 4d140bbbe100..9b7ee7e427df 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -89,6 +89,7 @@ struct idle_cpu { | |||
89 | * Indicate which enable bits to clear here. | 89 | * Indicate which enable bits to clear here. |
90 | */ | 90 | */ |
91 | unsigned long auto_demotion_disable_flags; | 91 | unsigned long auto_demotion_disable_flags; |
92 | bool byt_auto_demotion_disable_flag; | ||
92 | bool disable_promotion_to_c1e; | 93 | bool disable_promotion_to_c1e; |
93 | }; | 94 | }; |
94 | 95 | ||
@@ -442,6 +443,66 @@ static struct cpuidle_state hsw_cstates[] = { | |||
442 | { | 443 | { |
443 | .enter = NULL } | 444 | .enter = NULL } |
444 | }; | 445 | }; |
446 | static struct cpuidle_state bdw_cstates[] = { | ||
447 | { | ||
448 | .name = "C1-BDW", | ||
449 | .desc = "MWAIT 0x00", | ||
450 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
451 | .exit_latency = 2, | ||
452 | .target_residency = 2, | ||
453 | .enter = &intel_idle }, | ||
454 | { | ||
455 | .name = "C1E-BDW", | ||
456 | .desc = "MWAIT 0x01", | ||
457 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
458 | .exit_latency = 10, | ||
459 | .target_residency = 20, | ||
460 | .enter = &intel_idle }, | ||
461 | { | ||
462 | .name = "C3-BDW", | ||
463 | .desc = "MWAIT 0x10", | ||
464 | .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
465 | .exit_latency = 40, | ||
466 | .target_residency = 100, | ||
467 | .enter = &intel_idle }, | ||
468 | { | ||
469 | .name = "C6-BDW", | ||
470 | .desc = "MWAIT 0x20", | ||
471 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
472 | .exit_latency = 133, | ||
473 | .target_residency = 400, | ||
474 | .enter = &intel_idle }, | ||
475 | { | ||
476 | .name = "C7s-BDW", | ||
477 | .desc = "MWAIT 0x32", | ||
478 | .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
479 | .exit_latency = 166, | ||
480 | .target_residency = 500, | ||
481 | .enter = &intel_idle }, | ||
482 | { | ||
483 | .name = "C8-BDW", | ||
484 | .desc = "MWAIT 0x40", | ||
485 | .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
486 | .exit_latency = 300, | ||
487 | .target_residency = 900, | ||
488 | .enter = &intel_idle }, | ||
489 | { | ||
490 | .name = "C9-BDW", | ||
491 | .desc = "MWAIT 0x50", | ||
492 | .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
493 | .exit_latency = 600, | ||
494 | .target_residency = 1800, | ||
495 | .enter = &intel_idle }, | ||
496 | { | ||
497 | .name = "C10-BDW", | ||
498 | .desc = "MWAIT 0x60", | ||
499 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
500 | .exit_latency = 2600, | ||
501 | .target_residency = 7700, | ||
502 | .enter = &intel_idle }, | ||
503 | { | ||
504 | .enter = NULL } | ||
505 | }; | ||
445 | 506 | ||
446 | static struct cpuidle_state atom_cstates[] = { | 507 | static struct cpuidle_state atom_cstates[] = { |
447 | { | 508 | { |
@@ -613,6 +674,7 @@ static const struct idle_cpu idle_cpu_snb = { | |||
613 | static const struct idle_cpu idle_cpu_byt = { | 674 | static const struct idle_cpu idle_cpu_byt = { |
614 | .state_table = byt_cstates, | 675 | .state_table = byt_cstates, |
615 | .disable_promotion_to_c1e = true, | 676 | .disable_promotion_to_c1e = true, |
677 | .byt_auto_demotion_disable_flag = true, | ||
616 | }; | 678 | }; |
617 | 679 | ||
618 | static const struct idle_cpu idle_cpu_ivb = { | 680 | static const struct idle_cpu idle_cpu_ivb = { |
@@ -630,6 +692,11 @@ static const struct idle_cpu idle_cpu_hsw = { | |||
630 | .disable_promotion_to_c1e = true, | 692 | .disable_promotion_to_c1e = true, |
631 | }; | 693 | }; |
632 | 694 | ||
695 | static const struct idle_cpu idle_cpu_bdw = { | ||
696 | .state_table = bdw_cstates, | ||
697 | .disable_promotion_to_c1e = true, | ||
698 | }; | ||
699 | |||
633 | static const struct idle_cpu idle_cpu_avn = { | 700 | static const struct idle_cpu idle_cpu_avn = { |
634 | .state_table = avn_cstates, | 701 | .state_table = avn_cstates, |
635 | .disable_promotion_to_c1e = true, | 702 | .disable_promotion_to_c1e = true, |
@@ -658,7 +725,10 @@ static const struct x86_cpu_id intel_idle_ids[] = { | |||
658 | ICPU(0x3f, idle_cpu_hsw), | 725 | ICPU(0x3f, idle_cpu_hsw), |
659 | ICPU(0x45, idle_cpu_hsw), | 726 | ICPU(0x45, idle_cpu_hsw), |
660 | ICPU(0x46, idle_cpu_hsw), | 727 | ICPU(0x46, idle_cpu_hsw), |
661 | ICPU(0x4D, idle_cpu_avn), | 728 | ICPU(0x4d, idle_cpu_avn), |
729 | ICPU(0x3d, idle_cpu_bdw), | ||
730 | ICPU(0x4f, idle_cpu_bdw), | ||
731 | ICPU(0x56, idle_cpu_bdw), | ||
662 | {} | 732 | {} |
663 | }; | 733 | }; |
664 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); | 734 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); |
@@ -814,6 +884,11 @@ static int __init intel_idle_cpuidle_driver_init(void) | |||
814 | if (icpu->auto_demotion_disable_flags) | 884 | if (icpu->auto_demotion_disable_flags) |
815 | on_each_cpu(auto_demotion_disable, NULL, 1); | 885 | on_each_cpu(auto_demotion_disable, NULL, 1); |
816 | 886 | ||
887 | if (icpu->byt_auto_demotion_disable_flag) { | ||
888 | wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); | ||
889 | wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); | ||
890 | } | ||
891 | |||
817 | if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ | 892 | if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ |
818 | on_each_cpu(c1e_promotion_disable, NULL, 1); | 893 | on_each_cpu(c1e_promotion_disable, NULL, 1); |
819 | 894 | ||
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index d398f1321f14..c30204f2fa30 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
@@ -237,6 +237,31 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | |||
237 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | 237 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); |
238 | 238 | ||
239 | /** | 239 | /** |
240 | * input_mt_drop_unused() - Inactivate slots not seen in this frame | ||
241 | * @dev: input device with allocated MT slots | ||
242 | * | ||
243 | * Lift all slots not seen since the last call to this function. | ||
244 | */ | ||
245 | void input_mt_drop_unused(struct input_dev *dev) | ||
246 | { | ||
247 | struct input_mt *mt = dev->mt; | ||
248 | int i; | ||
249 | |||
250 | if (!mt) | ||
251 | return; | ||
252 | |||
253 | for (i = 0; i < mt->num_slots; i++) { | ||
254 | if (!input_mt_is_used(mt, &mt->slots[i])) { | ||
255 | input_mt_slot(dev, i); | ||
256 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | mt->frame++; | ||
261 | } | ||
262 | EXPORT_SYMBOL(input_mt_drop_unused); | ||
263 | |||
264 | /** | ||
240 | * input_mt_sync_frame() - synchronize mt frame | 265 | * input_mt_sync_frame() - synchronize mt frame |
241 | * @dev: input device with allocated MT slots | 266 | * @dev: input device with allocated MT slots |
242 | * | 267 | * |
@@ -247,27 +272,18 @@ EXPORT_SYMBOL(input_mt_report_pointer_emulation); | |||
247 | void input_mt_sync_frame(struct input_dev *dev) | 272 | void input_mt_sync_frame(struct input_dev *dev) |
248 | { | 273 | { |
249 | struct input_mt *mt = dev->mt; | 274 | struct input_mt *mt = dev->mt; |
250 | struct input_mt_slot *s; | ||
251 | bool use_count = false; | 275 | bool use_count = false; |
252 | 276 | ||
253 | if (!mt) | 277 | if (!mt) |
254 | return; | 278 | return; |
255 | 279 | ||
256 | if (mt->flags & INPUT_MT_DROP_UNUSED) { | 280 | if (mt->flags & INPUT_MT_DROP_UNUSED) |
257 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { | 281 | input_mt_drop_unused(dev); |
258 | if (input_mt_is_used(mt, s)) | ||
259 | continue; | ||
260 | input_mt_slot(dev, s - mt->slots); | ||
261 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
262 | } | ||
263 | } | ||
264 | 282 | ||
265 | if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) | 283 | if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) |
266 | use_count = true; | 284 | use_count = true; |
267 | 285 | ||
268 | input_mt_report_pointer_emulation(dev, use_count); | 286 | input_mt_report_pointer_emulation(dev, use_count); |
269 | |||
270 | mt->frame++; | ||
271 | } | 287 | } |
272 | EXPORT_SYMBOL(input_mt_sync_frame); | 288 | EXPORT_SYMBOL(input_mt_sync_frame); |
273 | 289 | ||
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 9135606c8649..ab0fdcd36e18 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -158,7 +158,7 @@ static unsigned int get_time_pit(void) | |||
158 | #define GET_TIME(x) rdtscl(x) | 158 | #define GET_TIME(x) rdtscl(x) |
159 | #define DELTA(x,y) ((y)-(x)) | 159 | #define DELTA(x,y) ((y)-(x)) |
160 | #define TIME_NAME "TSC" | 160 | #define TIME_NAME "TSC" |
161 | #elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE) | 161 | #elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_TILE) |
162 | #define GET_TIME(x) do { x = get_cycles(); } while (0) | 162 | #define GET_TIME(x) do { x = get_cycles(); } while (0) |
163 | #define DELTA(x,y) ((y)-(x)) | 163 | #define DELTA(x,y) ((y)-(x)) |
164 | #define TIME_NAME "get_cycles" | 164 | #define TIME_NAME "get_cycles" |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 603fe0dd3682..177602cf7079 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -95,7 +95,8 @@ | |||
95 | #define XTYPE_XBOX 0 | 95 | #define XTYPE_XBOX 0 |
96 | #define XTYPE_XBOX360 1 | 96 | #define XTYPE_XBOX360 1 |
97 | #define XTYPE_XBOX360W 2 | 97 | #define XTYPE_XBOX360W 2 |
98 | #define XTYPE_UNKNOWN 3 | 98 | #define XTYPE_XBOXONE 3 |
99 | #define XTYPE_UNKNOWN 4 | ||
99 | 100 | ||
100 | static bool dpad_to_buttons; | 101 | static bool dpad_to_buttons; |
101 | module_param(dpad_to_buttons, bool, S_IRUGO); | 102 | module_param(dpad_to_buttons, bool, S_IRUGO); |
@@ -121,6 +122,7 @@ static const struct xpad_device { | |||
121 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, | 122 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, |
122 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, | 123 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, |
123 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, | 124 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, |
125 | { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, | ||
124 | { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 126 | { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
125 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 127 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
126 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, | 128 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, |
@@ -231,10 +233,12 @@ static const signed short xpad_abs_triggers[] = { | |||
231 | -1 | 233 | -1 |
232 | }; | 234 | }; |
233 | 235 | ||
234 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only | 236 | /* |
237 | * Xbox 360 has a vendor-specific class, so we cannot match it with only | ||
235 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we | 238 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we |
236 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, | 239 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
237 | * wireless controllers have protocol 129. */ | 240 | * wireless controllers have protocol 129. |
241 | */ | ||
238 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ | 242 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ |
239 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ | 243 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ |
240 | .idVendor = (vend), \ | 244 | .idVendor = (vend), \ |
@@ -245,9 +249,20 @@ static const signed short xpad_abs_triggers[] = { | |||
245 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ | 249 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ |
246 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } | 250 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } |
247 | 251 | ||
252 | /* The Xbox One controller uses subclass 71 and protocol 208. */ | ||
253 | #define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \ | ||
254 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
255 | .idVendor = (vend), \ | ||
256 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ | ||
257 | .bInterfaceSubClass = 71, \ | ||
258 | .bInterfaceProtocol = (pr) | ||
259 | #define XPAD_XBOXONE_VENDOR(vend) \ | ||
260 | { XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) } | ||
261 | |||
248 | static struct usb_device_id xpad_table[] = { | 262 | static struct usb_device_id xpad_table[] = { |
249 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ | 263 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ |
250 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ | 264 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ |
265 | XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ | ||
251 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ | 266 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ |
252 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ | 267 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ |
253 | { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ | 268 | { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ |
@@ -278,12 +293,10 @@ struct usb_xpad { | |||
278 | struct urb *bulk_out; | 293 | struct urb *bulk_out; |
279 | unsigned char *bdata; | 294 | unsigned char *bdata; |
280 | 295 | ||
281 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) | ||
282 | struct urb *irq_out; /* urb for interrupt out report */ | 296 | struct urb *irq_out; /* urb for interrupt out report */ |
283 | unsigned char *odata; /* output data */ | 297 | unsigned char *odata; /* output data */ |
284 | dma_addr_t odata_dma; | 298 | dma_addr_t odata_dma; |
285 | struct mutex odata_mutex; | 299 | struct mutex odata_mutex; |
286 | #endif | ||
287 | 300 | ||
288 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS) | 301 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS) |
289 | struct xpad_led *led; | 302 | struct xpad_led *led; |
@@ -470,6 +483,105 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha | |||
470 | xpad360_process_packet(xpad, cmd, &data[4]); | 483 | xpad360_process_packet(xpad, cmd, &data[4]); |
471 | } | 484 | } |
472 | 485 | ||
486 | /* | ||
487 | * xpadone_process_buttons | ||
488 | * | ||
489 | * Process a button update packet from an Xbox one controller. | ||
490 | */ | ||
491 | static void xpadone_process_buttons(struct usb_xpad *xpad, | ||
492 | struct input_dev *dev, | ||
493 | unsigned char *data) | ||
494 | { | ||
495 | /* menu/view buttons */ | ||
496 | input_report_key(dev, BTN_START, data[4] & 0x04); | ||
497 | input_report_key(dev, BTN_SELECT, data[4] & 0x08); | ||
498 | |||
499 | /* buttons A,B,X,Y */ | ||
500 | input_report_key(dev, BTN_A, data[4] & 0x10); | ||
501 | input_report_key(dev, BTN_B, data[4] & 0x20); | ||
502 | input_report_key(dev, BTN_X, data[4] & 0x40); | ||
503 | input_report_key(dev, BTN_Y, data[4] & 0x80); | ||
504 | |||
505 | /* digital pad */ | ||
506 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { | ||
507 | /* dpad as buttons (left, right, up, down) */ | ||
508 | input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04); | ||
509 | input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08); | ||
510 | input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01); | ||
511 | input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02); | ||
512 | } else { | ||
513 | input_report_abs(dev, ABS_HAT0X, | ||
514 | !!(data[5] & 0x08) - !!(data[5] & 0x04)); | ||
515 | input_report_abs(dev, ABS_HAT0Y, | ||
516 | !!(data[5] & 0x02) - !!(data[5] & 0x01)); | ||
517 | } | ||
518 | |||
519 | /* TL/TR */ | ||
520 | input_report_key(dev, BTN_TL, data[5] & 0x10); | ||
521 | input_report_key(dev, BTN_TR, data[5] & 0x20); | ||
522 | |||
523 | /* stick press left/right */ | ||
524 | input_report_key(dev, BTN_THUMBL, data[5] & 0x40); | ||
525 | input_report_key(dev, BTN_THUMBR, data[5] & 0x80); | ||
526 | |||
527 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { | ||
528 | /* left stick */ | ||
529 | input_report_abs(dev, ABS_X, | ||
530 | (__s16) le16_to_cpup((__le16 *)(data + 10))); | ||
531 | input_report_abs(dev, ABS_Y, | ||
532 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); | ||
533 | |||
534 | /* right stick */ | ||
535 | input_report_abs(dev, ABS_RX, | ||
536 | (__s16) le16_to_cpup((__le16 *)(data + 14))); | ||
537 | input_report_abs(dev, ABS_RY, | ||
538 | ~(__s16) le16_to_cpup((__le16 *)(data + 16))); | ||
539 | } | ||
540 | |||
541 | /* triggers left/right */ | ||
542 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | ||
543 | input_report_key(dev, BTN_TL2, | ||
544 | (__u16) le16_to_cpup((__le16 *)(data + 6))); | ||
545 | input_report_key(dev, BTN_TR2, | ||
546 | (__u16) le16_to_cpup((__le16 *)(data + 8))); | ||
547 | } else { | ||
548 | input_report_abs(dev, ABS_Z, | ||
549 | (__u16) le16_to_cpup((__le16 *)(data + 6))); | ||
550 | input_report_abs(dev, ABS_RZ, | ||
551 | (__u16) le16_to_cpup((__le16 *)(data + 8))); | ||
552 | } | ||
553 | |||
554 | input_sync(dev); | ||
555 | } | ||
556 | |||
557 | /* | ||
558 | * xpadone_process_packet | ||
559 | * | ||
560 | * Completes a request by converting the data into events for the | ||
561 | * input subsystem. This version is for the Xbox One controller. | ||
562 | * | ||
563 | * The report format was gleaned from | ||
564 | * https://github.com/kylelemons/xbox/blob/master/xbox.go | ||
565 | */ | ||
566 | |||
567 | static void xpadone_process_packet(struct usb_xpad *xpad, | ||
568 | u16 cmd, unsigned char *data) | ||
569 | { | ||
570 | struct input_dev *dev = xpad->dev; | ||
571 | |||
572 | switch (data[0]) { | ||
573 | case 0x20: | ||
574 | xpadone_process_buttons(xpad, dev, data); | ||
575 | break; | ||
576 | |||
577 | case 0x07: | ||
578 | /* the xbox button has its own special report */ | ||
579 | input_report_key(dev, BTN_MODE, data[4] & 0x01); | ||
580 | input_sync(dev); | ||
581 | break; | ||
582 | } | ||
583 | } | ||
584 | |||
473 | static void xpad_irq_in(struct urb *urb) | 585 | static void xpad_irq_in(struct urb *urb) |
474 | { | 586 | { |
475 | struct usb_xpad *xpad = urb->context; | 587 | struct usb_xpad *xpad = urb->context; |
@@ -502,6 +614,9 @@ static void xpad_irq_in(struct urb *urb) | |||
502 | case XTYPE_XBOX360W: | 614 | case XTYPE_XBOX360W: |
503 | xpad360w_process_packet(xpad, 0, xpad->idata); | 615 | xpad360w_process_packet(xpad, 0, xpad->idata); |
504 | break; | 616 | break; |
617 | case XTYPE_XBOXONE: | ||
618 | xpadone_process_packet(xpad, 0, xpad->idata); | ||
619 | break; | ||
505 | default: | 620 | default: |
506 | xpad_process_packet(xpad, 0, xpad->idata); | 621 | xpad_process_packet(xpad, 0, xpad->idata); |
507 | } | 622 | } |
@@ -535,7 +650,6 @@ static void xpad_bulk_out(struct urb *urb) | |||
535 | } | 650 | } |
536 | } | 651 | } |
537 | 652 | ||
538 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) | ||
539 | static void xpad_irq_out(struct urb *urb) | 653 | static void xpad_irq_out(struct urb *urb) |
540 | { | 654 | { |
541 | struct usb_xpad *xpad = urb->context; | 655 | struct usb_xpad *xpad = urb->context; |
@@ -573,6 +687,7 @@ exit: | |||
573 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 687 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
574 | { | 688 | { |
575 | struct usb_endpoint_descriptor *ep_irq_out; | 689 | struct usb_endpoint_descriptor *ep_irq_out; |
690 | int ep_irq_out_idx; | ||
576 | int error; | 691 | int error; |
577 | 692 | ||
578 | if (xpad->xtype == XTYPE_UNKNOWN) | 693 | if (xpad->xtype == XTYPE_UNKNOWN) |
@@ -593,7 +708,10 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
593 | goto fail2; | 708 | goto fail2; |
594 | } | 709 | } |
595 | 710 | ||
596 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; | 711 | /* Xbox One controller has in/out endpoints swapped. */ |
712 | ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1; | ||
713 | ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc; | ||
714 | |||
597 | usb_fill_int_urb(xpad->irq_out, xpad->udev, | 715 | usb_fill_int_urb(xpad->irq_out, xpad->udev, |
598 | usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), | 716 | usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), |
599 | xpad->odata, XPAD_PKT_LEN, | 717 | xpad->odata, XPAD_PKT_LEN, |
@@ -621,11 +739,6 @@ static void xpad_deinit_output(struct usb_xpad *xpad) | |||
621 | xpad->odata, xpad->odata_dma); | 739 | xpad->odata, xpad->odata_dma); |
622 | } | 740 | } |
623 | } | 741 | } |
624 | #else | ||
625 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } | ||
626 | static void xpad_deinit_output(struct usb_xpad *xpad) {} | ||
627 | static void xpad_stop_output(struct usb_xpad *xpad) {} | ||
628 | #endif | ||
629 | 742 | ||
630 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 743 | #ifdef CONFIG_JOYSTICK_XPAD_FF |
631 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) | 744 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) |
@@ -692,7 +805,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect | |||
692 | 805 | ||
693 | static int xpad_init_ff(struct usb_xpad *xpad) | 806 | static int xpad_init_ff(struct usb_xpad *xpad) |
694 | { | 807 | { |
695 | if (xpad->xtype == XTYPE_UNKNOWN) | 808 | if (xpad->xtype == XTYPE_UNKNOWN || xpad->xtype == XTYPE_XBOXONE) |
696 | return 0; | 809 | return 0; |
697 | 810 | ||
698 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 811 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |
@@ -801,6 +914,14 @@ static int xpad_open(struct input_dev *dev) | |||
801 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) | 914 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) |
802 | return -EIO; | 915 | return -EIO; |
803 | 916 | ||
917 | if (xpad->xtype == XTYPE_XBOXONE) { | ||
918 | /* Xbox one controller needs to be initialized. */ | ||
919 | xpad->odata[0] = 0x05; | ||
920 | xpad->odata[1] = 0x20; | ||
921 | xpad->irq_out->transfer_buffer_length = 2; | ||
922 | return usb_submit_urb(xpad->irq_out, GFP_KERNEL); | ||
923 | } | ||
924 | |||
804 | return 0; | 925 | return 0; |
805 | } | 926 | } |
806 | 927 | ||
@@ -816,6 +937,7 @@ static void xpad_close(struct input_dev *dev) | |||
816 | 937 | ||
817 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | 938 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) |
818 | { | 939 | { |
940 | struct usb_xpad *xpad = input_get_drvdata(input_dev); | ||
819 | set_bit(abs, input_dev->absbit); | 941 | set_bit(abs, input_dev->absbit); |
820 | 942 | ||
821 | switch (abs) { | 943 | switch (abs) { |
@@ -827,7 +949,10 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | |||
827 | break; | 949 | break; |
828 | case ABS_Z: | 950 | case ABS_Z: |
829 | case ABS_RZ: /* the triggers (if mapped to axes) */ | 951 | case ABS_RZ: /* the triggers (if mapped to axes) */ |
830 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | 952 | if (xpad->xtype == XTYPE_XBOXONE) |
953 | input_set_abs_params(input_dev, abs, 0, 1023, 0, 0); | ||
954 | else | ||
955 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | ||
831 | break; | 956 | break; |
832 | case ABS_HAT0X: | 957 | case ABS_HAT0X: |
833 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ | 958 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ |
@@ -842,6 +967,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
842 | struct usb_xpad *xpad; | 967 | struct usb_xpad *xpad; |
843 | struct input_dev *input_dev; | 968 | struct input_dev *input_dev; |
844 | struct usb_endpoint_descriptor *ep_irq_in; | 969 | struct usb_endpoint_descriptor *ep_irq_in; |
970 | int ep_irq_in_idx; | ||
845 | int i, error; | 971 | int i, error; |
846 | 972 | ||
847 | for (i = 0; xpad_device[i].idVendor; i++) { | 973 | for (i = 0; xpad_device[i].idVendor; i++) { |
@@ -850,6 +976,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
850 | break; | 976 | break; |
851 | } | 977 | } |
852 | 978 | ||
979 | if (xpad_device[i].xtype == XTYPE_XBOXONE && | ||
980 | intf->cur_altsetting->desc.bInterfaceNumber != 0) { | ||
981 | /* | ||
982 | * The Xbox One controller lists three interfaces all with the | ||
983 | * same interface class, subclass and protocol. Differentiate by | ||
984 | * interface number. | ||
985 | */ | ||
986 | return -ENODEV; | ||
987 | } | ||
988 | |||
853 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); | 989 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); |
854 | input_dev = input_allocate_device(); | 990 | input_dev = input_allocate_device(); |
855 | if (!xpad || !input_dev) { | 991 | if (!xpad || !input_dev) { |
@@ -920,7 +1056,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
920 | __set_bit(xpad_common_btn[i], input_dev->keybit); | 1056 | __set_bit(xpad_common_btn[i], input_dev->keybit); |
921 | 1057 | ||
922 | /* set up model-specific ones */ | 1058 | /* set up model-specific ones */ |
923 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { | 1059 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W || |
1060 | xpad->xtype == XTYPE_XBOXONE) { | ||
924 | for (i = 0; xpad360_btn[i] >= 0; i++) | 1061 | for (i = 0; xpad360_btn[i] >= 0; i++) |
925 | __set_bit(xpad360_btn[i], input_dev->keybit); | 1062 | __set_bit(xpad360_btn[i], input_dev->keybit); |
926 | } else { | 1063 | } else { |
@@ -933,7 +1070,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
933 | __set_bit(xpad_btn_pad[i], input_dev->keybit); | 1070 | __set_bit(xpad_btn_pad[i], input_dev->keybit); |
934 | } else { | 1071 | } else { |
935 | for (i = 0; xpad_abs_pad[i] >= 0; i++) | 1072 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
936 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | 1073 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); |
937 | } | 1074 | } |
938 | 1075 | ||
939 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | 1076 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
@@ -956,7 +1093,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
956 | if (error) | 1093 | if (error) |
957 | goto fail5; | 1094 | goto fail5; |
958 | 1095 | ||
959 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 1096 | /* Xbox One controller has in/out endpoints swapped. */ |
1097 | ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0; | ||
1098 | ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; | ||
1099 | |||
960 | usb_fill_int_urb(xpad->irq_in, udev, | 1100 | usb_fill_int_urb(xpad->irq_in, udev, |
961 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), | 1101 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), |
962 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, | 1102 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, |
diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c index f7d7a0d4ab4e..180b184ab90f 100644 --- a/drivers/input/keyboard/cap1106.c +++ b/drivers/input/keyboard/cap1106.c | |||
@@ -64,7 +64,7 @@ struct cap1106_priv { | |||
64 | struct input_dev *idev; | 64 | struct input_dev *idev; |
65 | 65 | ||
66 | /* config */ | 66 | /* config */ |
67 | unsigned int keycodes[CAP1106_NUM_CHN]; | 67 | unsigned short keycodes[CAP1106_NUM_CHN]; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static const struct reg_default cap1106_reg_defaults[] = { | 70 | static const struct reg_default cap1106_reg_defaults[] = { |
@@ -272,6 +272,12 @@ static int cap1106_i2c_probe(struct i2c_client *i2c_client, | |||
272 | for (i = 0; i < CAP1106_NUM_CHN; i++) | 272 | for (i = 0; i < CAP1106_NUM_CHN; i++) |
273 | __set_bit(priv->keycodes[i], priv->idev->keybit); | 273 | __set_bit(priv->keycodes[i], priv->idev->keybit); |
274 | 274 | ||
275 | __clear_bit(KEY_RESERVED, priv->idev->keybit); | ||
276 | |||
277 | priv->idev->keycode = priv->keycodes; | ||
278 | priv->idev->keycodesize = sizeof(priv->keycodes[0]); | ||
279 | priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); | ||
280 | |||
275 | priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; | 281 | priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; |
276 | priv->idev->id.product = CAP1106_PRODUCT_ID; | 282 | priv->idev->id.product = CAP1106_PRODUCT_ID; |
277 | priv->idev->id.version = rev; | 283 | priv->idev->id.version = rev; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ef9e0b8a9aa7..e8573c68f77e 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -117,6 +117,9 @@ void synaptics_reset(struct psmouse *psmouse) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
120 | |||
121 | static bool cr48_profile_sensor; | ||
122 | |||
120 | struct min_max_quirk { | 123 | struct min_max_quirk { |
121 | const char * const *pnp_ids; | 124 | const char * const *pnp_ids; |
122 | int x_min, x_max, y_min, y_max; | 125 | int x_min, x_max, y_min, y_max; |
@@ -1152,6 +1155,42 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse, | |||
1152 | priv->agm_pending = false; | 1155 | priv->agm_pending = false; |
1153 | } | 1156 | } |
1154 | 1157 | ||
1158 | static void synaptics_profile_sensor_process(struct psmouse *psmouse, | ||
1159 | struct synaptics_hw_state *sgm, | ||
1160 | int num_fingers) | ||
1161 | { | ||
1162 | struct input_dev *dev = psmouse->dev; | ||
1163 | struct synaptics_data *priv = psmouse->private; | ||
1164 | struct synaptics_hw_state *hw[2] = { sgm, &priv->agm }; | ||
1165 | struct input_mt_pos pos[2]; | ||
1166 | int slot[2], nsemi, i; | ||
1167 | |||
1168 | nsemi = clamp_val(num_fingers, 0, 2); | ||
1169 | |||
1170 | for (i = 0; i < nsemi; i++) { | ||
1171 | pos[i].x = hw[i]->x; | ||
1172 | pos[i].y = synaptics_invert_y(hw[i]->y); | ||
1173 | } | ||
1174 | |||
1175 | input_mt_assign_slots(dev, slot, pos, nsemi); | ||
1176 | |||
1177 | for (i = 0; i < nsemi; i++) { | ||
1178 | input_mt_slot(dev, slot[i]); | ||
1179 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, true); | ||
1180 | input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x); | ||
1181 | input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y); | ||
1182 | input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z); | ||
1183 | } | ||
1184 | |||
1185 | input_mt_drop_unused(dev); | ||
1186 | input_mt_report_pointer_emulation(dev, false); | ||
1187 | input_mt_report_finger_count(dev, num_fingers); | ||
1188 | |||
1189 | synaptics_report_buttons(psmouse, sgm); | ||
1190 | |||
1191 | input_sync(dev); | ||
1192 | } | ||
1193 | |||
1155 | /* | 1194 | /* |
1156 | * called for each full received packet from the touchpad | 1195 | * called for each full received packet from the touchpad |
1157 | */ | 1196 | */ |
@@ -1215,6 +1254,11 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
1215 | finger_width = 0; | 1254 | finger_width = 0; |
1216 | } | 1255 | } |
1217 | 1256 | ||
1257 | if (cr48_profile_sensor) { | ||
1258 | synaptics_profile_sensor_process(psmouse, &hw, num_fingers); | ||
1259 | return; | ||
1260 | } | ||
1261 | |||
1218 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | 1262 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) |
1219 | synaptics_report_semi_mt_data(dev, &hw, &priv->agm, | 1263 | synaptics_report_semi_mt_data(dev, &hw, &priv->agm, |
1220 | num_fingers); | 1264 | num_fingers); |
@@ -1360,6 +1404,9 @@ static void set_input_params(struct psmouse *psmouse, | |||
1360 | set_abs_position_params(dev, priv, ABS_X, ABS_Y); | 1404 | set_abs_position_params(dev, priv, ABS_X, ABS_Y); |
1361 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1405 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
1362 | 1406 | ||
1407 | if (cr48_profile_sensor) | ||
1408 | input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
1409 | |||
1363 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1410 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
1364 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1411 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1365 | ABS_MT_POSITION_Y); | 1412 | ABS_MT_POSITION_Y); |
@@ -1371,11 +1418,16 @@ static void set_input_params(struct psmouse *psmouse, | |||
1371 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 1418 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
1372 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); | 1419 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); |
1373 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 1420 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
1374 | /* Non-image sensors with AGM use semi-mt */ | ||
1375 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
1376 | input_mt_init_slots(dev, 2, 0); | ||
1377 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1421 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1378 | ABS_MT_POSITION_Y); | 1422 | ABS_MT_POSITION_Y); |
1423 | /* | ||
1424 | * Profile sensor in CR-48 tracks contacts reasonably well, | ||
1425 | * other non-image sensors with AGM use semi-mt. | ||
1426 | */ | ||
1427 | input_mt_init_slots(dev, 2, | ||
1428 | INPUT_MT_POINTER | | ||
1429 | (cr48_profile_sensor ? | ||
1430 | INPUT_MT_TRACK : INPUT_MT_SEMI_MT)); | ||
1379 | } | 1431 | } |
1380 | 1432 | ||
1381 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 1433 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
@@ -1577,10 +1629,24 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { | |||
1577 | { } | 1629 | { } |
1578 | }; | 1630 | }; |
1579 | 1631 | ||
1632 | static const struct dmi_system_id __initconst cr48_dmi_table[] = { | ||
1633 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1634 | { | ||
1635 | /* Cr-48 Chromebook (Codename Mario) */ | ||
1636 | .matches = { | ||
1637 | DMI_MATCH(DMI_SYS_VENDOR, "IEC"), | ||
1638 | DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), | ||
1639 | }, | ||
1640 | }, | ||
1641 | #endif | ||
1642 | { } | ||
1643 | }; | ||
1644 | |||
1580 | void __init synaptics_module_init(void) | 1645 | void __init synaptics_module_init(void) |
1581 | { | 1646 | { |
1582 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 1647 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
1583 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | 1648 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); |
1649 | cr48_profile_sensor = dmi_check_system(cr48_dmi_table); | ||
1584 | } | 1650 | } |
1585 | 1651 | ||
1586 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | 1652 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 03b85711cb70..db178ed2b47e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -359,7 +359,6 @@ static int mxt_bootloader_read(struct mxt_data *data, | |||
359 | msg.buf = val; | 359 | msg.buf = val; |
360 | 360 | ||
361 | ret = i2c_transfer(data->client->adapter, &msg, 1); | 361 | ret = i2c_transfer(data->client->adapter, &msg, 1); |
362 | |||
363 | if (ret == 1) { | 362 | if (ret == 1) { |
364 | ret = 0; | 363 | ret = 0; |
365 | } else { | 364 | } else { |
@@ -414,6 +413,7 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) | |||
414 | case 0x5b: | 413 | case 0x5b: |
415 | bootloader = appmode - 0x26; | 414 | bootloader = appmode - 0x26; |
416 | break; | 415 | break; |
416 | |||
417 | default: | 417 | default: |
418 | dev_err(&data->client->dev, | 418 | dev_err(&data->client->dev, |
419 | "Appmode i2c address 0x%02x not found\n", | 419 | "Appmode i2c address 0x%02x not found\n", |
@@ -425,20 +425,20 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) | |||
425 | return 0; | 425 | return 0; |
426 | } | 426 | } |
427 | 427 | ||
428 | static int mxt_probe_bootloader(struct mxt_data *data, bool retry) | 428 | static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address) |
429 | { | 429 | { |
430 | struct device *dev = &data->client->dev; | 430 | struct device *dev = &data->client->dev; |
431 | int ret; | 431 | int error; |
432 | u8 val; | 432 | u8 val; |
433 | bool crc_failure; | 433 | bool crc_failure; |
434 | 434 | ||
435 | ret = mxt_lookup_bootloader_address(data, retry); | 435 | error = mxt_lookup_bootloader_address(data, alt_address); |
436 | if (ret) | 436 | if (error) |
437 | return ret; | 437 | return error; |
438 | 438 | ||
439 | ret = mxt_bootloader_read(data, &val, 1); | 439 | error = mxt_bootloader_read(data, &val, 1); |
440 | if (ret) | 440 | if (error) |
441 | return ret; | 441 | return error; |
442 | 442 | ||
443 | /* Check app crc fail mode */ | 443 | /* Check app crc fail mode */ |
444 | crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL; | 444 | crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL; |
@@ -1064,6 +1064,137 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off) | |||
1064 | return crc; | 1064 | return crc; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | static int mxt_prepare_cfg_mem(struct mxt_data *data, | ||
1068 | const struct firmware *cfg, | ||
1069 | unsigned int data_pos, | ||
1070 | unsigned int cfg_start_ofs, | ||
1071 | u8 *config_mem, | ||
1072 | size_t config_mem_size) | ||
1073 | { | ||
1074 | struct device *dev = &data->client->dev; | ||
1075 | struct mxt_object *object; | ||
1076 | unsigned int type, instance, size, byte_offset; | ||
1077 | int offset; | ||
1078 | int ret; | ||
1079 | int i; | ||
1080 | u16 reg; | ||
1081 | u8 val; | ||
1082 | |||
1083 | while (data_pos < cfg->size) { | ||
1084 | /* Read type, instance, length */ | ||
1085 | ret = sscanf(cfg->data + data_pos, "%x %x %x%n", | ||
1086 | &type, &instance, &size, &offset); | ||
1087 | if (ret == 0) { | ||
1088 | /* EOF */ | ||
1089 | break; | ||
1090 | } else if (ret != 3) { | ||
1091 | dev_err(dev, "Bad format: failed to parse object\n"); | ||
1092 | return -EINVAL; | ||
1093 | } | ||
1094 | data_pos += offset; | ||
1095 | |||
1096 | object = mxt_get_object(data, type); | ||
1097 | if (!object) { | ||
1098 | /* Skip object */ | ||
1099 | for (i = 0; i < size; i++) { | ||
1100 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1101 | &val, &offset); | ||
1102 | if (ret != 1) { | ||
1103 | dev_err(dev, "Bad format in T%d at %d\n", | ||
1104 | type, i); | ||
1105 | return -EINVAL; | ||
1106 | } | ||
1107 | data_pos += offset; | ||
1108 | } | ||
1109 | continue; | ||
1110 | } | ||
1111 | |||
1112 | if (size > mxt_obj_size(object)) { | ||
1113 | /* | ||
1114 | * Either we are in fallback mode due to wrong | ||
1115 | * config or config from a later fw version, | ||
1116 | * or the file is corrupt or hand-edited. | ||
1117 | */ | ||
1118 | dev_warn(dev, "Discarding %zu byte(s) in T%u\n", | ||
1119 | size - mxt_obj_size(object), type); | ||
1120 | } else if (mxt_obj_size(object) > size) { | ||
1121 | /* | ||
1122 | * If firmware is upgraded, new bytes may be added to | ||
1123 | * end of objects. It is generally forward compatible | ||
1124 | * to zero these bytes - previous behaviour will be | ||
1125 | * retained. However this does invalidate the CRC and | ||
1126 | * will force fallback mode until the configuration is | ||
1127 | * updated. We warn here but do nothing else - the | ||
1128 | * malloc has zeroed the entire configuration. | ||
1129 | */ | ||
1130 | dev_warn(dev, "Zeroing %zu byte(s) in T%d\n", | ||
1131 | mxt_obj_size(object) - size, type); | ||
1132 | } | ||
1133 | |||
1134 | if (instance >= mxt_obj_instances(object)) { | ||
1135 | dev_err(dev, "Object instances exceeded!\n"); | ||
1136 | return -EINVAL; | ||
1137 | } | ||
1138 | |||
1139 | reg = object->start_address + mxt_obj_size(object) * instance; | ||
1140 | |||
1141 | for (i = 0; i < size; i++) { | ||
1142 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1143 | &val, | ||
1144 | &offset); | ||
1145 | if (ret != 1) { | ||
1146 | dev_err(dev, "Bad format in T%d at %d\n", | ||
1147 | type, i); | ||
1148 | return -EINVAL; | ||
1149 | } | ||
1150 | data_pos += offset; | ||
1151 | |||
1152 | if (i > mxt_obj_size(object)) | ||
1153 | continue; | ||
1154 | |||
1155 | byte_offset = reg + i - cfg_start_ofs; | ||
1156 | |||
1157 | if (byte_offset >= 0 && byte_offset < config_mem_size) { | ||
1158 | *(config_mem + byte_offset) = val; | ||
1159 | } else { | ||
1160 | dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n", | ||
1161 | reg, object->type, byte_offset); | ||
1162 | return -EINVAL; | ||
1163 | } | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start, | ||
1171 | u8 *config_mem, size_t config_mem_size) | ||
1172 | { | ||
1173 | unsigned int byte_offset = 0; | ||
1174 | int error; | ||
1175 | |||
1176 | /* Write configuration as blocks */ | ||
1177 | while (byte_offset < config_mem_size) { | ||
1178 | unsigned int size = config_mem_size - byte_offset; | ||
1179 | |||
1180 | if (size > MXT_MAX_BLOCK_WRITE) | ||
1181 | size = MXT_MAX_BLOCK_WRITE; | ||
1182 | |||
1183 | error = __mxt_write_reg(data->client, | ||
1184 | cfg_start + byte_offset, | ||
1185 | size, config_mem + byte_offset); | ||
1186 | if (error) { | ||
1187 | dev_err(&data->client->dev, | ||
1188 | "Config write error, ret=%d\n", error); | ||
1189 | return error; | ||
1190 | } | ||
1191 | |||
1192 | byte_offset += size; | ||
1193 | } | ||
1194 | |||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1067 | /* | 1198 | /* |
1068 | * mxt_update_cfg - download configuration to chip | 1199 | * mxt_update_cfg - download configuration to chip |
1069 | * | 1200 | * |
@@ -1087,26 +1218,20 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1087 | { | 1218 | { |
1088 | struct device *dev = &data->client->dev; | 1219 | struct device *dev = &data->client->dev; |
1089 | struct mxt_info cfg_info; | 1220 | struct mxt_info cfg_info; |
1090 | struct mxt_object *object; | ||
1091 | int ret; | 1221 | int ret; |
1092 | int offset; | 1222 | int offset; |
1093 | int data_pos; | 1223 | int data_pos; |
1094 | int byte_offset; | ||
1095 | int i; | 1224 | int i; |
1096 | int cfg_start_ofs; | 1225 | int cfg_start_ofs; |
1097 | u32 info_crc, config_crc, calculated_crc; | 1226 | u32 info_crc, config_crc, calculated_crc; |
1098 | u8 *config_mem; | 1227 | u8 *config_mem; |
1099 | size_t config_mem_size; | 1228 | size_t config_mem_size; |
1100 | unsigned int type, instance, size; | ||
1101 | u8 val; | ||
1102 | u16 reg; | ||
1103 | 1229 | ||
1104 | mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); | 1230 | mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); |
1105 | 1231 | ||
1106 | if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { | 1232 | if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { |
1107 | dev_err(dev, "Unrecognised config file\n"); | 1233 | dev_err(dev, "Unrecognised config file\n"); |
1108 | ret = -EINVAL; | 1234 | return -EINVAL; |
1109 | goto release; | ||
1110 | } | 1235 | } |
1111 | 1236 | ||
1112 | data_pos = strlen(MXT_CFG_MAGIC); | 1237 | data_pos = strlen(MXT_CFG_MAGIC); |
@@ -1118,8 +1243,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1118 | &offset); | 1243 | &offset); |
1119 | if (ret != 1) { | 1244 | if (ret != 1) { |
1120 | dev_err(dev, "Bad format\n"); | 1245 | dev_err(dev, "Bad format\n"); |
1121 | ret = -EINVAL; | 1246 | return -EINVAL; |
1122 | goto release; | ||
1123 | } | 1247 | } |
1124 | 1248 | ||
1125 | data_pos += offset; | 1249 | data_pos += offset; |
@@ -1127,30 +1251,26 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1127 | 1251 | ||
1128 | if (cfg_info.family_id != data->info.family_id) { | 1252 | if (cfg_info.family_id != data->info.family_id) { |
1129 | dev_err(dev, "Family ID mismatch!\n"); | 1253 | dev_err(dev, "Family ID mismatch!\n"); |
1130 | ret = -EINVAL; | 1254 | return -EINVAL; |
1131 | goto release; | ||
1132 | } | 1255 | } |
1133 | 1256 | ||
1134 | if (cfg_info.variant_id != data->info.variant_id) { | 1257 | if (cfg_info.variant_id != data->info.variant_id) { |
1135 | dev_err(dev, "Variant ID mismatch!\n"); | 1258 | dev_err(dev, "Variant ID mismatch!\n"); |
1136 | ret = -EINVAL; | 1259 | return -EINVAL; |
1137 | goto release; | ||
1138 | } | 1260 | } |
1139 | 1261 | ||
1140 | /* Read CRCs */ | 1262 | /* Read CRCs */ |
1141 | ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset); | 1263 | ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset); |
1142 | if (ret != 1) { | 1264 | if (ret != 1) { |
1143 | dev_err(dev, "Bad format: failed to parse Info CRC\n"); | 1265 | dev_err(dev, "Bad format: failed to parse Info CRC\n"); |
1144 | ret = -EINVAL; | 1266 | return -EINVAL; |
1145 | goto release; | ||
1146 | } | 1267 | } |
1147 | data_pos += offset; | 1268 | data_pos += offset; |
1148 | 1269 | ||
1149 | ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset); | 1270 | ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset); |
1150 | if (ret != 1) { | 1271 | if (ret != 1) { |
1151 | dev_err(dev, "Bad format: failed to parse Config CRC\n"); | 1272 | dev_err(dev, "Bad format: failed to parse Config CRC\n"); |
1152 | ret = -EINVAL; | 1273 | return -EINVAL; |
1153 | goto release; | ||
1154 | } | 1274 | } |
1155 | data_pos += offset; | 1275 | data_pos += offset; |
1156 | 1276 | ||
@@ -1166,8 +1286,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1166 | } else if (config_crc == data->config_crc) { | 1286 | } else if (config_crc == data->config_crc) { |
1167 | dev_dbg(dev, "Config CRC 0x%06X: OK\n", | 1287 | dev_dbg(dev, "Config CRC 0x%06X: OK\n", |
1168 | data->config_crc); | 1288 | data->config_crc); |
1169 | ret = 0; | 1289 | return 0; |
1170 | goto release; | ||
1171 | } else { | 1290 | } else { |
1172 | dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", | 1291 | dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", |
1173 | data->config_crc, config_crc); | 1292 | data->config_crc, config_crc); |
@@ -1186,93 +1305,13 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1186 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); | 1305 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); |
1187 | if (!config_mem) { | 1306 | if (!config_mem) { |
1188 | dev_err(dev, "Failed to allocate memory\n"); | 1307 | dev_err(dev, "Failed to allocate memory\n"); |
1189 | ret = -ENOMEM; | 1308 | return -ENOMEM; |
1190 | goto release; | ||
1191 | } | 1309 | } |
1192 | 1310 | ||
1193 | while (data_pos < cfg->size) { | 1311 | ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs, |
1194 | /* Read type, instance, length */ | 1312 | config_mem, config_mem_size); |
1195 | ret = sscanf(cfg->data + data_pos, "%x %x %x%n", | 1313 | if (ret) |
1196 | &type, &instance, &size, &offset); | 1314 | goto release_mem; |
1197 | if (ret == 0) { | ||
1198 | /* EOF */ | ||
1199 | break; | ||
1200 | } else if (ret != 3) { | ||
1201 | dev_err(dev, "Bad format: failed to parse object\n"); | ||
1202 | ret = -EINVAL; | ||
1203 | goto release_mem; | ||
1204 | } | ||
1205 | data_pos += offset; | ||
1206 | |||
1207 | object = mxt_get_object(data, type); | ||
1208 | if (!object) { | ||
1209 | /* Skip object */ | ||
1210 | for (i = 0; i < size; i++) { | ||
1211 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1212 | &val, | ||
1213 | &offset); | ||
1214 | data_pos += offset; | ||
1215 | } | ||
1216 | continue; | ||
1217 | } | ||
1218 | |||
1219 | if (size > mxt_obj_size(object)) { | ||
1220 | /* | ||
1221 | * Either we are in fallback mode due to wrong | ||
1222 | * config or config from a later fw version, | ||
1223 | * or the file is corrupt or hand-edited. | ||
1224 | */ | ||
1225 | dev_warn(dev, "Discarding %zu byte(s) in T%u\n", | ||
1226 | size - mxt_obj_size(object), type); | ||
1227 | } else if (mxt_obj_size(object) > size) { | ||
1228 | /* | ||
1229 | * If firmware is upgraded, new bytes may be added to | ||
1230 | * end of objects. It is generally forward compatible | ||
1231 | * to zero these bytes - previous behaviour will be | ||
1232 | * retained. However this does invalidate the CRC and | ||
1233 | * will force fallback mode until the configuration is | ||
1234 | * updated. We warn here but do nothing else - the | ||
1235 | * malloc has zeroed the entire configuration. | ||
1236 | */ | ||
1237 | dev_warn(dev, "Zeroing %zu byte(s) in T%d\n", | ||
1238 | mxt_obj_size(object) - size, type); | ||
1239 | } | ||
1240 | |||
1241 | if (instance >= mxt_obj_instances(object)) { | ||
1242 | dev_err(dev, "Object instances exceeded!\n"); | ||
1243 | ret = -EINVAL; | ||
1244 | goto release_mem; | ||
1245 | } | ||
1246 | |||
1247 | reg = object->start_address + mxt_obj_size(object) * instance; | ||
1248 | |||
1249 | for (i = 0; i < size; i++) { | ||
1250 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1251 | &val, | ||
1252 | &offset); | ||
1253 | if (ret != 1) { | ||
1254 | dev_err(dev, "Bad format in T%d\n", type); | ||
1255 | ret = -EINVAL; | ||
1256 | goto release_mem; | ||
1257 | } | ||
1258 | data_pos += offset; | ||
1259 | |||
1260 | if (i > mxt_obj_size(object)) | ||
1261 | continue; | ||
1262 | |||
1263 | byte_offset = reg + i - cfg_start_ofs; | ||
1264 | |||
1265 | if ((byte_offset >= 0) | ||
1266 | && (byte_offset <= config_mem_size)) { | ||
1267 | *(config_mem + byte_offset) = val; | ||
1268 | } else { | ||
1269 | dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n", | ||
1270 | reg, object->type, byte_offset); | ||
1271 | ret = -EINVAL; | ||
1272 | goto release_mem; | ||
1273 | } | ||
1274 | } | ||
1275 | } | ||
1276 | 1315 | ||
1277 | /* Calculate crc of the received configs (not the raw config file) */ | 1316 | /* Calculate crc of the received configs (not the raw config file) */ |
1278 | if (data->T7_address < cfg_start_ofs) { | 1317 | if (data->T7_address < cfg_start_ofs) { |
@@ -1286,28 +1325,14 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1286 | data->T7_address - cfg_start_ofs, | 1325 | data->T7_address - cfg_start_ofs, |
1287 | config_mem_size); | 1326 | config_mem_size); |
1288 | 1327 | ||
1289 | if (config_crc > 0 && (config_crc != calculated_crc)) | 1328 | if (config_crc > 0 && config_crc != calculated_crc) |
1290 | dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n", | 1329 | dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n", |
1291 | calculated_crc, config_crc); | 1330 | calculated_crc, config_crc); |
1292 | 1331 | ||
1293 | /* Write configuration as blocks */ | 1332 | ret = mxt_upload_cfg_mem(data, cfg_start_ofs, |
1294 | byte_offset = 0; | 1333 | config_mem, config_mem_size); |
1295 | while (byte_offset < config_mem_size) { | 1334 | if (ret) |
1296 | size = config_mem_size - byte_offset; | 1335 | goto release_mem; |
1297 | |||
1298 | if (size > MXT_MAX_BLOCK_WRITE) | ||
1299 | size = MXT_MAX_BLOCK_WRITE; | ||
1300 | |||
1301 | ret = __mxt_write_reg(data->client, | ||
1302 | cfg_start_ofs + byte_offset, | ||
1303 | size, config_mem + byte_offset); | ||
1304 | if (ret != 0) { | ||
1305 | dev_err(dev, "Config write error, ret=%d\n", ret); | ||
1306 | goto release_mem; | ||
1307 | } | ||
1308 | |||
1309 | byte_offset += size; | ||
1310 | } | ||
1311 | 1336 | ||
1312 | mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); | 1337 | mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); |
1313 | 1338 | ||
@@ -1319,8 +1344,6 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1319 | 1344 | ||
1320 | release_mem: | 1345 | release_mem: |
1321 | kfree(config_mem); | 1346 | kfree(config_mem); |
1322 | release: | ||
1323 | release_firmware(cfg); | ||
1324 | return ret; | 1347 | return ret; |
1325 | } | 1348 | } |
1326 | 1349 | ||
@@ -1422,10 +1445,12 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1422 | 1445 | ||
1423 | switch (object->type) { | 1446 | switch (object->type) { |
1424 | case MXT_GEN_MESSAGE_T5: | 1447 | case MXT_GEN_MESSAGE_T5: |
1425 | if (data->info.family_id == 0x80) { | 1448 | if (data->info.family_id == 0x80 && |
1449 | data->info.version < 0x20) { | ||
1426 | /* | 1450 | /* |
1427 | * On mXT224 read and discard unused CRC byte | 1451 | * On mXT224 firmware versions prior to V2.0 |
1428 | * otherwise DMA reads are misaligned | 1452 | * read and discard unused CRC byte otherwise |
1453 | * DMA reads are misaligned. | ||
1429 | */ | 1454 | */ |
1430 | data->T5_msg_size = mxt_obj_size(object); | 1455 | data->T5_msg_size = mxt_obj_size(object); |
1431 | } else { | 1456 | } else { |
@@ -1433,6 +1458,7 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1433 | data->T5_msg_size = mxt_obj_size(object) - 1; | 1458 | data->T5_msg_size = mxt_obj_size(object) - 1; |
1434 | } | 1459 | } |
1435 | data->T5_address = object->start_address; | 1460 | data->T5_address = object->start_address; |
1461 | break; | ||
1436 | case MXT_GEN_COMMAND_T6: | 1462 | case MXT_GEN_COMMAND_T6: |
1437 | data->T6_reportid = min_id; | 1463 | data->T6_reportid = min_id; |
1438 | data->T6_address = object->start_address; | 1464 | data->T6_address = object->start_address; |
@@ -1638,46 +1664,45 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
1638 | static void mxt_config_cb(const struct firmware *cfg, void *ctx) | 1664 | static void mxt_config_cb(const struct firmware *cfg, void *ctx) |
1639 | { | 1665 | { |
1640 | mxt_configure_objects(ctx, cfg); | 1666 | mxt_configure_objects(ctx, cfg); |
1667 | release_firmware(cfg); | ||
1641 | } | 1668 | } |
1642 | 1669 | ||
1643 | static int mxt_initialize(struct mxt_data *data) | 1670 | static int mxt_initialize(struct mxt_data *data) |
1644 | { | 1671 | { |
1645 | struct i2c_client *client = data->client; | 1672 | struct i2c_client *client = data->client; |
1673 | int recovery_attempts = 0; | ||
1646 | int error; | 1674 | int error; |
1647 | bool alt_bootloader_addr = false; | ||
1648 | bool retry = false; | ||
1649 | 1675 | ||
1650 | retry_info: | 1676 | while (1) { |
1651 | error = mxt_get_info(data); | 1677 | error = mxt_get_info(data); |
1652 | if (error) { | 1678 | if (!error) |
1653 | retry_bootloader: | 1679 | break; |
1654 | error = mxt_probe_bootloader(data, alt_bootloader_addr); | 1680 | |
1681 | /* Check bootloader state */ | ||
1682 | error = mxt_probe_bootloader(data, false); | ||
1655 | if (error) { | 1683 | if (error) { |
1656 | if (alt_bootloader_addr) { | 1684 | dev_info(&client->dev, "Trying alternate bootloader address\n"); |
1685 | error = mxt_probe_bootloader(data, true); | ||
1686 | if (error) { | ||
1657 | /* Chip is not in appmode or bootloader mode */ | 1687 | /* Chip is not in appmode or bootloader mode */ |
1658 | return error; | 1688 | return error; |
1659 | } | 1689 | } |
1690 | } | ||
1660 | 1691 | ||
1661 | dev_info(&client->dev, "Trying alternate bootloader address\n"); | 1692 | /* OK, we are in bootloader, see if we can recover */ |
1662 | alt_bootloader_addr = true; | 1693 | if (++recovery_attempts > 1) { |
1663 | goto retry_bootloader; | 1694 | dev_err(&client->dev, "Could not recover from bootloader mode\n"); |
1664 | } else { | 1695 | /* |
1665 | if (retry) { | 1696 | * We can reflash from this state, so do not |
1666 | dev_err(&client->dev, "Could not recover from bootloader mode\n"); | 1697 | * abort initialization. |
1667 | /* | 1698 | */ |
1668 | * We can reflash from this state, so do not | 1699 | data->in_bootloader = true; |
1669 | * abort init | 1700 | return 0; |
1670 | */ | ||
1671 | data->in_bootloader = true; | ||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1675 | /* Attempt to exit bootloader into app mode */ | ||
1676 | mxt_send_bootloader_cmd(data, false); | ||
1677 | msleep(MXT_FW_RESET_TIME); | ||
1678 | retry = true; | ||
1679 | goto retry_info; | ||
1680 | } | 1701 | } |
1702 | |||
1703 | /* Attempt to exit bootloader into app mode */ | ||
1704 | mxt_send_bootloader_cmd(data, false); | ||
1705 | msleep(MXT_FW_RESET_TIME); | ||
1681 | } | 1706 | } |
1682 | 1707 | ||
1683 | /* Get object table information */ | 1708 | /* Get object table information */ |
@@ -1687,13 +1712,18 @@ retry_bootloader: | |||
1687 | return error; | 1712 | return error; |
1688 | } | 1713 | } |
1689 | 1714 | ||
1690 | mxt_acquire_irq(data); | 1715 | error = mxt_acquire_irq(data); |
1691 | if (error) | 1716 | if (error) |
1692 | goto err_free_object_table; | 1717 | goto err_free_object_table; |
1693 | 1718 | ||
1694 | request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, | 1719 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, |
1695 | &data->client->dev, GFP_KERNEL, data, | 1720 | &client->dev, GFP_KERNEL, data, |
1696 | mxt_config_cb); | 1721 | mxt_config_cb); |
1722 | if (error) { | ||
1723 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", | ||
1724 | error); | ||
1725 | goto err_free_object_table; | ||
1726 | } | ||
1697 | 1727 | ||
1698 | return 0; | 1728 | return 0; |
1699 | 1729 | ||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 5a6d50c004d7..8857d5b9be71 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -262,7 +262,6 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, | |||
262 | case M06: | 262 | case M06: |
263 | wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; | 263 | wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; |
264 | wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; | 264 | wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; |
265 | wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; | ||
266 | wrbuf[2] = value; | 265 | wrbuf[2] = value; |
267 | wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; | 266 | wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; |
268 | return edt_ft5x06_ts_readwrite(tsdata->client, 4, | 267 | return edt_ft5x06_ts_readwrite(tsdata->client, 4, |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 18405314168b..ecb0109a5360 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -3149,14 +3149,16 @@ free_domains: | |||
3149 | 3149 | ||
3150 | static void cleanup_domain(struct protection_domain *domain) | 3150 | static void cleanup_domain(struct protection_domain *domain) |
3151 | { | 3151 | { |
3152 | struct iommu_dev_data *dev_data, *next; | 3152 | struct iommu_dev_data *entry; |
3153 | unsigned long flags; | 3153 | unsigned long flags; |
3154 | 3154 | ||
3155 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 3155 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
3156 | 3156 | ||
3157 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { | 3157 | while (!list_empty(&domain->dev_list)) { |
3158 | __detach_device(dev_data); | 3158 | entry = list_first_entry(&domain->dev_list, |
3159 | atomic_set(&dev_data->bind, 0); | 3159 | struct iommu_dev_data, list); |
3160 | __detach_device(entry); | ||
3161 | atomic_set(&entry->bind, 0); | ||
3160 | } | 3162 | } |
3161 | 3163 | ||
3162 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 3164 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d1f5caad04f9..5619f264862d 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -3869,6 +3869,14 @@ static int device_notifier(struct notifier_block *nb, | |||
3869 | action != BUS_NOTIFY_DEL_DEVICE) | 3869 | action != BUS_NOTIFY_DEL_DEVICE) |
3870 | return 0; | 3870 | return 0; |
3871 | 3871 | ||
3872 | /* | ||
3873 | * If the device is still attached to a device driver we can't | ||
3874 | * tear down the domain yet as DMA mappings may still be in use. | ||
3875 | * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. | ||
3876 | */ | ||
3877 | if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) | ||
3878 | return 0; | ||
3879 | |||
3872 | domain = find_domain(dev); | 3880 | domain = find_domain(dev); |
3873 | if (!domain) | 3881 | if (!domain) |
3874 | return 0; | 3882 | return 0; |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 169836020208..ac4adb337038 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
@@ -995,7 +995,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
995 | size_t orig_size = size; | 995 | size_t orig_size = size; |
996 | int ret = 0; | 996 | int ret = 0; |
997 | 997 | ||
998 | if (unlikely(domain->ops->unmap == NULL || | 998 | if (unlikely(domain->ops->map == NULL || |
999 | domain->ops->pgsize_bitmap == 0UL)) | 999 | domain->ops->pgsize_bitmap == 0UL)) |
1000 | return -ENODEV; | 1000 | return -ENODEV; |
1001 | 1001 | ||
diff --git a/drivers/isdn/hardware/eicon/xdi_msg.h b/drivers/isdn/hardware/eicon/xdi_msg.h index 58368f7b5cba..2498c349a32e 100644 --- a/drivers/isdn/hardware/eicon/xdi_msg.h +++ b/drivers/isdn/hardware/eicon/xdi_msg.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* $Id: xdi_msg.h,v 1.1.2.2 2001/02/16 08:40:36 armin Exp $ */ | 1 | /* $Id: xdi_msg.h,v 1.1.2.2 2001/02/16 08:40:36 armin Exp $ */ |
2 | 2 | ||
3 | #ifndef __DIVA_XDI_UM_CFG_MESSSGE_H__ | 3 | #ifndef __DIVA_XDI_UM_CFG_MESSAGE_H__ |
4 | #define __DIVA_XDI_UM_CFG_MESSAGE_H__ | 4 | #define __DIVA_XDI_UM_CFG_MESSAGE_H__ |
5 | 5 | ||
6 | /* | 6 | /* |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b08c18871323..6703751d87d7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -2953,6 +2953,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
2953 | */ | 2953 | */ |
2954 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { | 2954 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { |
2955 | end_reshape(conf); | 2955 | end_reshape(conf); |
2956 | close_sync(conf); | ||
2956 | return 0; | 2957 | return 0; |
2957 | } | 2958 | } |
2958 | 2959 | ||
@@ -3081,6 +3082,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
3081 | } | 3082 | } |
3082 | 3083 | ||
3083 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 3084 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
3085 | r10_bio->state = 0; | ||
3084 | raise_barrier(conf, rb2 != NULL); | 3086 | raise_barrier(conf, rb2 != NULL); |
3085 | atomic_set(&r10_bio->remaining, 0); | 3087 | atomic_set(&r10_bio->remaining, 0); |
3086 | 3088 | ||
@@ -3269,6 +3271,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
3269 | if (sync_blocks < max_sync) | 3271 | if (sync_blocks < max_sync) |
3270 | max_sync = sync_blocks; | 3272 | max_sync = sync_blocks; |
3271 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 3273 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
3274 | r10_bio->state = 0; | ||
3272 | 3275 | ||
3273 | r10_bio->mddev = mddev; | 3276 | r10_bio->mddev = mddev; |
3274 | atomic_set(&r10_bio->remaining, 0); | 3277 | atomic_set(&r10_bio->remaining, 0); |
@@ -4384,6 +4387,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, | |||
4384 | read_more: | 4387 | read_more: |
4385 | /* Now schedule reads for blocks from sector_nr to last */ | 4388 | /* Now schedule reads for blocks from sector_nr to last */ |
4386 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); | 4389 | r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO); |
4390 | r10_bio->state = 0; | ||
4387 | raise_barrier(conf, sectors_done != 0); | 4391 | raise_barrier(conf, sectors_done != 0); |
4388 | atomic_set(&r10_bio->remaining, 0); | 4392 | atomic_set(&r10_bio->remaining, 0); |
4389 | r10_bio->mddev = mddev; | 4393 | r10_bio->mddev = mddev; |
@@ -4398,6 +4402,7 @@ read_more: | |||
4398 | * on all the target devices. | 4402 | * on all the target devices. |
4399 | */ | 4403 | */ |
4400 | // FIXME | 4404 | // FIXME |
4405 | mempool_free(r10_bio, conf->r10buf_pool); | ||
4401 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 4406 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
4402 | return sectors_done; | 4407 | return sectors_done; |
4403 | } | 4408 | } |
@@ -4410,7 +4415,7 @@ read_more: | |||
4410 | read_bio->bi_private = r10_bio; | 4415 | read_bio->bi_private = r10_bio; |
4411 | read_bio->bi_end_io = end_sync_read; | 4416 | read_bio->bi_end_io = end_sync_read; |
4412 | read_bio->bi_rw = READ; | 4417 | read_bio->bi_rw = READ; |
4413 | read_bio->bi_flags &= ~(BIO_POOL_MASK - 1); | 4418 | read_bio->bi_flags &= (~0UL << BIO_RESET_BITS); |
4414 | read_bio->bi_flags |= 1 << BIO_UPTODATE; | 4419 | read_bio->bi_flags |= 1 << BIO_UPTODATE; |
4415 | read_bio->bi_vcnt = 0; | 4420 | read_bio->bi_vcnt = 0; |
4416 | read_bio->bi_iter.bi_size = 0; | 4421 | read_bio->bi_iter.bi_size = 0; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 6234b2e84587..183588b11fc1 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2922,7 +2922,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, | |||
2922 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) && | 2922 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) && |
2923 | !test_bit(R5_OVERWRITE, &fdev[0]->flags)) || | 2923 | !test_bit(R5_OVERWRITE, &fdev[0]->flags)) || |
2924 | (sh->raid_conf->level == 6 && s->failed && s->to_write && | 2924 | (sh->raid_conf->level == 6 && s->failed && s->to_write && |
2925 | s->to_write < sh->raid_conf->raid_disks - 2 && | 2925 | s->to_write - s->non_overwrite < sh->raid_conf->raid_disks - 2 && |
2926 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) { | 2926 | (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) { |
2927 | /* we would like to get this block, possibly by computing it, | 2927 | /* we would like to get this block, possibly by computing it, |
2928 | * otherwise read it if the backing disk is insync | 2928 | * otherwise read it if the backing disk is insync |
@@ -3817,6 +3817,8 @@ static void handle_stripe(struct stripe_head *sh) | |||
3817 | set_bit(R5_Wantwrite, &dev->flags); | 3817 | set_bit(R5_Wantwrite, &dev->flags); |
3818 | if (prexor) | 3818 | if (prexor) |
3819 | continue; | 3819 | continue; |
3820 | if (s.failed > 1) | ||
3821 | continue; | ||
3820 | if (!test_bit(R5_Insync, &dev->flags) || | 3822 | if (!test_bit(R5_Insync, &dev->flags) || |
3821 | ((i == sh->pd_idx || i == sh->qd_idx) && | 3823 | ((i == sh->pd_idx || i == sh->qd_idx) && |
3822 | s.failed == 0)) | 3824 | s.failed == 0)) |
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 5dede6e64376..109cb44291f5 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c | |||
@@ -280,7 +280,7 @@ static int c_can_plat_probe(struct platform_device *pdev) | |||
280 | 280 | ||
281 | priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, | 281 | priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, |
282 | resource_size(res)); | 282 | resource_size(res)); |
283 | if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) | 283 | if (!priv->raminit_ctrlreg || priv->instance < 0) |
284 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); | 284 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); |
285 | else | 285 | else |
286 | priv->raminit = c_can_hw_raminit_ti; | 286 | priv->raminit = c_can_hw_raminit_ti; |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index ff1beb92a985..2700865efcad 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -608,6 +608,13 @@ static void do_state(struct net_device *dev, | |||
608 | 608 | ||
609 | /* process state changes depending on the new state */ | 609 | /* process state changes depending on the new state */ |
610 | switch (new_state) { | 610 | switch (new_state) { |
611 | case CAN_STATE_ERROR_WARNING: | ||
612 | netdev_dbg(dev, "Error Warning\n"); | ||
613 | cf->can_id |= CAN_ERR_CRTL; | ||
614 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
615 | CAN_ERR_CRTL_TX_WARNING : | ||
616 | CAN_ERR_CRTL_RX_WARNING; | ||
617 | break; | ||
611 | case CAN_STATE_ERROR_ACTIVE: | 618 | case CAN_STATE_ERROR_ACTIVE: |
612 | netdev_dbg(dev, "Error Active\n"); | 619 | netdev_dbg(dev, "Error Active\n"); |
613 | cf->can_id |= CAN_ERR_PROT; | 620 | cf->can_id |= CAN_ERR_PROT; |
@@ -911,6 +918,8 @@ static int flexcan_chip_start(struct net_device *dev) | |||
911 | if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || | 918 | if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || |
912 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | 919 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
913 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; | 920 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; |
921 | else | ||
922 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK; | ||
914 | 923 | ||
915 | /* save for later use */ | 924 | /* save for later use */ |
916 | priv->reg_ctrl_default = reg_ctrl; | 925 | priv->reg_ctrl_default = reg_ctrl; |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index d1692154ed1b..b27ac6074afb 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev) | |||
172 | netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); | 172 | netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); |
173 | } | 173 | } |
174 | 174 | ||
175 | /* | ||
176 | * initialize SJA1000 chip: | ||
177 | * - reset chip | ||
178 | * - set output mode | ||
179 | * - set baudrate | ||
180 | * - enable interrupts | ||
181 | * - start operating mode | ||
182 | */ | ||
183 | static void chipset_init(struct net_device *dev) | ||
184 | { | ||
185 | struct sja1000_priv *priv = netdev_priv(dev); | ||
186 | |||
187 | /* set clock divider and output control register */ | ||
188 | priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); | ||
189 | |||
190 | /* set acceptance filter (accept all) */ | ||
191 | priv->write_reg(priv, SJA1000_ACCC0, 0x00); | ||
192 | priv->write_reg(priv, SJA1000_ACCC1, 0x00); | ||
193 | priv->write_reg(priv, SJA1000_ACCC2, 0x00); | ||
194 | priv->write_reg(priv, SJA1000_ACCC3, 0x00); | ||
195 | |||
196 | priv->write_reg(priv, SJA1000_ACCM0, 0xFF); | ||
197 | priv->write_reg(priv, SJA1000_ACCM1, 0xFF); | ||
198 | priv->write_reg(priv, SJA1000_ACCM2, 0xFF); | ||
199 | priv->write_reg(priv, SJA1000_ACCM3, 0xFF); | ||
200 | |||
201 | priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL); | ||
202 | } | ||
203 | |||
175 | static void sja1000_start(struct net_device *dev) | 204 | static void sja1000_start(struct net_device *dev) |
176 | { | 205 | { |
177 | struct sja1000_priv *priv = netdev_priv(dev); | 206 | struct sja1000_priv *priv = netdev_priv(dev); |
@@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev) | |||
180 | if (priv->can.state != CAN_STATE_STOPPED) | 209 | if (priv->can.state != CAN_STATE_STOPPED) |
181 | set_reset_mode(dev); | 210 | set_reset_mode(dev); |
182 | 211 | ||
212 | /* Initialize chip if uninitialized at this stage */ | ||
213 | if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN)) | ||
214 | chipset_init(dev); | ||
215 | |||
183 | /* Clear error counters and error code capture */ | 216 | /* Clear error counters and error code capture */ |
184 | priv->write_reg(priv, SJA1000_TXERR, 0x0); | 217 | priv->write_reg(priv, SJA1000_TXERR, 0x0); |
185 | priv->write_reg(priv, SJA1000_RXERR, 0x0); | 218 | priv->write_reg(priv, SJA1000_RXERR, 0x0); |
@@ -237,35 +270,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev, | |||
237 | } | 270 | } |
238 | 271 | ||
239 | /* | 272 | /* |
240 | * initialize SJA1000 chip: | ||
241 | * - reset chip | ||
242 | * - set output mode | ||
243 | * - set baudrate | ||
244 | * - enable interrupts | ||
245 | * - start operating mode | ||
246 | */ | ||
247 | static void chipset_init(struct net_device *dev) | ||
248 | { | ||
249 | struct sja1000_priv *priv = netdev_priv(dev); | ||
250 | |||
251 | /* set clock divider and output control register */ | ||
252 | priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); | ||
253 | |||
254 | /* set acceptance filter (accept all) */ | ||
255 | priv->write_reg(priv, SJA1000_ACCC0, 0x00); | ||
256 | priv->write_reg(priv, SJA1000_ACCC1, 0x00); | ||
257 | priv->write_reg(priv, SJA1000_ACCC2, 0x00); | ||
258 | priv->write_reg(priv, SJA1000_ACCC3, 0x00); | ||
259 | |||
260 | priv->write_reg(priv, SJA1000_ACCM0, 0xFF); | ||
261 | priv->write_reg(priv, SJA1000_ACCM1, 0xFF); | ||
262 | priv->write_reg(priv, SJA1000_ACCM2, 0xFF); | ||
263 | priv->write_reg(priv, SJA1000_ACCM3, 0xFF); | ||
264 | |||
265 | priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL); | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * transmit a CAN message | 273 | * transmit a CAN message |
270 | * message layout in the sk_buff should be like this: | 274 | * message layout in the sk_buff should be like this: |
271 | * xx xx xx xx ff ll 00 11 22 33 44 55 66 77 | 275 | * xx xx xx xx ff ll 00 11 22 33 44 55 66 77 |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index e1a8f4e19983..e4222af2baa6 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c | |||
@@ -563,15 +563,21 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata) | |||
563 | struct xgene_enet_desc_ring *ring; | 563 | struct xgene_enet_desc_ring *ring; |
564 | 564 | ||
565 | ring = pdata->tx_ring; | 565 | ring = pdata->tx_ring; |
566 | if (ring && ring->cp_ring && ring->cp_ring->cp_skb) | 566 | if (ring) { |
567 | devm_kfree(dev, ring->cp_ring->cp_skb); | 567 | if (ring->cp_ring && ring->cp_ring->cp_skb) |
568 | xgene_enet_free_desc_ring(ring); | 568 | devm_kfree(dev, ring->cp_ring->cp_skb); |
569 | xgene_enet_free_desc_ring(ring); | ||
570 | } | ||
569 | 571 | ||
570 | ring = pdata->rx_ring; | 572 | ring = pdata->rx_ring; |
571 | if (ring && ring->buf_pool && ring->buf_pool->rx_skb) | 573 | if (ring) { |
572 | devm_kfree(dev, ring->buf_pool->rx_skb); | 574 | if (ring->buf_pool) { |
573 | xgene_enet_free_desc_ring(ring->buf_pool); | 575 | if (ring->buf_pool->rx_skb) |
574 | xgene_enet_free_desc_ring(ring); | 576 | devm_kfree(dev, ring->buf_pool->rx_skb); |
577 | xgene_enet_free_desc_ring(ring->buf_pool); | ||
578 | } | ||
579 | xgene_enet_free_desc_ring(ring); | ||
580 | } | ||
575 | } | 581 | } |
576 | 582 | ||
577 | static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring( | 583 | static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring( |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index a1dd2e417a97..23881448fb02 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -483,11 +483,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
483 | 483 | ||
484 | #ifdef BNX2X_STOP_ON_ERROR | 484 | #ifdef BNX2X_STOP_ON_ERROR |
485 | fp->tpa_queue_used |= (1 << queue); | 485 | fp->tpa_queue_used |= (1 << queue); |
486 | #ifdef _ASM_GENERIC_INT_L64_H | ||
487 | DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n", | ||
488 | #else | ||
489 | DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n", | 486 | DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n", |
490 | #endif | ||
491 | fp->tpa_queue_used); | 487 | fp->tpa_queue_used); |
492 | #endif | 488 | #endif |
493 | } | 489 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 07cfe33798a4..a008f48cfaae 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -10123,6 +10123,8 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, | |||
10123 | } | 10123 | } |
10124 | 10124 | ||
10125 | #define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4)) | 10125 | #define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4)) |
10126 | #define BNX2X_PREV_UNDI_PROD_ADDR_H(f) (BAR_TSTRORM_INTMEM + \ | ||
10127 | 0x1848 + ((f) << 4)) | ||
10126 | #define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff) | 10128 | #define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff) |
10127 | #define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff) | 10129 | #define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff) |
10128 | #define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq)) | 10130 | #define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq)) |
@@ -10130,8 +10132,6 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, | |||
10130 | #define BCM_5710_UNDI_FW_MF_MAJOR (0x07) | 10132 | #define BCM_5710_UNDI_FW_MF_MAJOR (0x07) |
10131 | #define BCM_5710_UNDI_FW_MF_MINOR (0x08) | 10133 | #define BCM_5710_UNDI_FW_MF_MINOR (0x08) |
10132 | #define BCM_5710_UNDI_FW_MF_VERS (0x05) | 10134 | #define BCM_5710_UNDI_FW_MF_VERS (0x05) |
10133 | #define BNX2X_PREV_UNDI_MF_PORT(p) (BAR_TSTRORM_INTMEM + 0x150c + ((p) << 4)) | ||
10134 | #define BNX2X_PREV_UNDI_MF_FUNC(f) (BAR_TSTRORM_INTMEM + 0x184c + ((f) << 4)) | ||
10135 | 10135 | ||
10136 | static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) | 10136 | static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) |
10137 | { | 10137 | { |
@@ -10150,72 +10150,25 @@ static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) | |||
10150 | return false; | 10150 | return false; |
10151 | } | 10151 | } |
10152 | 10152 | ||
10153 | static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp) | 10153 | static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 inc) |
10154 | { | ||
10155 | u8 major, minor, version; | ||
10156 | u32 fw; | ||
10157 | |||
10158 | /* Must check that FW is loaded */ | ||
10159 | if (!(REG_RD(bp, MISC_REG_RESET_REG_1) & | ||
10160 | MISC_REGISTERS_RESET_REG_1_RST_XSEM)) { | ||
10161 | BNX2X_DEV_INFO("XSEM is reset - UNDI MF FW is not loaded\n"); | ||
10162 | return false; | ||
10163 | } | ||
10164 | |||
10165 | /* Read Currently loaded FW version */ | ||
10166 | fw = REG_RD(bp, XSEM_REG_PRAM); | ||
10167 | major = fw & 0xff; | ||
10168 | minor = (fw >> 0x8) & 0xff; | ||
10169 | version = (fw >> 0x10) & 0xff; | ||
10170 | BNX2X_DEV_INFO("Loaded FW: 0x%08x: Major 0x%02x Minor 0x%02x Version 0x%02x\n", | ||
10171 | fw, major, minor, version); | ||
10172 | |||
10173 | if (major > BCM_5710_UNDI_FW_MF_MAJOR) | ||
10174 | return true; | ||
10175 | |||
10176 | if ((major == BCM_5710_UNDI_FW_MF_MAJOR) && | ||
10177 | (minor > BCM_5710_UNDI_FW_MF_MINOR)) | ||
10178 | return true; | ||
10179 | |||
10180 | if ((major == BCM_5710_UNDI_FW_MF_MAJOR) && | ||
10181 | (minor == BCM_5710_UNDI_FW_MF_MINOR) && | ||
10182 | (version >= BCM_5710_UNDI_FW_MF_VERS)) | ||
10183 | return true; | ||
10184 | |||
10185 | return false; | ||
10186 | } | ||
10187 | |||
10188 | static void bnx2x_prev_unload_undi_mf(struct bnx2x *bp) | ||
10189 | { | ||
10190 | int i; | ||
10191 | |||
10192 | /* Due to legacy (FW) code, the first function on each engine has a | ||
10193 | * different offset macro from the rest of the functions. | ||
10194 | * Setting this for all 8 functions is harmless regardless of whether | ||
10195 | * this is actually a multi-function device. | ||
10196 | */ | ||
10197 | for (i = 0; i < 2; i++) | ||
10198 | REG_WR(bp, BNX2X_PREV_UNDI_MF_PORT(i), 1); | ||
10199 | |||
10200 | for (i = 2; i < 8; i++) | ||
10201 | REG_WR(bp, BNX2X_PREV_UNDI_MF_FUNC(i - 2), 1); | ||
10202 | |||
10203 | BNX2X_DEV_INFO("UNDI FW (MF) set to discard\n"); | ||
10204 | } | ||
10205 | |||
10206 | static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port, u8 inc) | ||
10207 | { | 10154 | { |
10208 | u16 rcq, bd; | 10155 | u16 rcq, bd; |
10209 | u32 tmp_reg = REG_RD(bp, BNX2X_PREV_UNDI_PROD_ADDR(port)); | 10156 | u32 addr, tmp_reg; |
10210 | 10157 | ||
10158 | if (BP_FUNC(bp) < 2) | ||
10159 | addr = BNX2X_PREV_UNDI_PROD_ADDR(BP_PORT(bp)); | ||
10160 | else | ||
10161 | addr = BNX2X_PREV_UNDI_PROD_ADDR_H(BP_FUNC(bp) - 2); | ||
10162 | |||
10163 | tmp_reg = REG_RD(bp, addr); | ||
10211 | rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc; | 10164 | rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc; |
10212 | bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc; | 10165 | bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc; |
10213 | 10166 | ||
10214 | tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd); | 10167 | tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd); |
10215 | REG_WR(bp, BNX2X_PREV_UNDI_PROD_ADDR(port), tmp_reg); | 10168 | REG_WR(bp, addr, tmp_reg); |
10216 | 10169 | ||
10217 | BNX2X_DEV_INFO("UNDI producer [%d] rings bd -> 0x%04x, rcq -> 0x%04x\n", | 10170 | BNX2X_DEV_INFO("UNDI producer [%d/%d][%08x] rings bd -> 0x%04x, rcq -> 0x%04x\n", |
10218 | port, bd, rcq); | 10171 | BP_PORT(bp), BP_FUNC(bp), addr, bd, rcq); |
10219 | } | 10172 | } |
10220 | 10173 | ||
10221 | static int bnx2x_prev_mcp_done(struct bnx2x *bp) | 10174 | static int bnx2x_prev_mcp_done(struct bnx2x *bp) |
@@ -10454,7 +10407,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) | |||
10454 | /* Reset should be performed after BRB is emptied */ | 10407 | /* Reset should be performed after BRB is emptied */ |
10455 | if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) { | 10408 | if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) { |
10456 | u32 timer_count = 1000; | 10409 | u32 timer_count = 1000; |
10457 | bool need_write = true; | ||
10458 | 10410 | ||
10459 | /* Close the MAC Rx to prevent BRB from filling up */ | 10411 | /* Close the MAC Rx to prevent BRB from filling up */ |
10460 | bnx2x_prev_unload_close_mac(bp, &mac_vals); | 10412 | bnx2x_prev_unload_close_mac(bp, &mac_vals); |
@@ -10491,20 +10443,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) | |||
10491 | else | 10443 | else |
10492 | timer_count--; | 10444 | timer_count--; |
10493 | 10445 | ||
10494 | /* New UNDI FW supports MF and contains better | 10446 | /* If UNDI resides in memory, manually increment it */ |
10495 | * cleaning methods - might be redundant but harmless. | 10447 | if (prev_undi) |
10496 | */ | 10448 | bnx2x_prev_unload_undi_inc(bp, 1); |
10497 | if (bnx2x_prev_unload_undi_fw_supports_mf(bp)) { | 10449 | |
10498 | if (need_write) { | ||
10499 | bnx2x_prev_unload_undi_mf(bp); | ||
10500 | need_write = false; | ||
10501 | } | ||
10502 | } else if (prev_undi) { | ||
10503 | /* If UNDI resides in memory, | ||
10504 | * manually increment it | ||
10505 | */ | ||
10506 | bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1); | ||
10507 | } | ||
10508 | udelay(10); | 10450 | udelay(10); |
10509 | } | 10451 | } |
10510 | 10452 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index d57282172ea5..c067b7888ac4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -652,6 +652,7 @@ struct adapter { | |||
652 | struct tid_info tids; | 652 | struct tid_info tids; |
653 | void **tid_release_head; | 653 | void **tid_release_head; |
654 | spinlock_t tid_release_lock; | 654 | spinlock_t tid_release_lock; |
655 | struct workqueue_struct *workq; | ||
655 | struct work_struct tid_release_task; | 656 | struct work_struct tid_release_task; |
656 | struct work_struct db_full_task; | 657 | struct work_struct db_full_task; |
657 | struct work_struct db_drop_task; | 658 | struct work_struct db_drop_task; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 1afee70ce856..18fb9c61d7ba 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -643,8 +643,6 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) | |||
643 | return ret; | 643 | return ret; |
644 | } | 644 | } |
645 | 645 | ||
646 | static struct workqueue_struct *workq; | ||
647 | |||
648 | /** | 646 | /** |
649 | * link_start - enable a port | 647 | * link_start - enable a port |
650 | * @dev: the port to enable | 648 | * @dev: the port to enable |
@@ -3340,7 +3338,7 @@ static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, | |||
3340 | adap->tid_release_head = (void **)((uintptr_t)p | chan); | 3338 | adap->tid_release_head = (void **)((uintptr_t)p | chan); |
3341 | if (!adap->tid_release_task_busy) { | 3339 | if (!adap->tid_release_task_busy) { |
3342 | adap->tid_release_task_busy = true; | 3340 | adap->tid_release_task_busy = true; |
3343 | queue_work(workq, &adap->tid_release_task); | 3341 | queue_work(adap->workq, &adap->tid_release_task); |
3344 | } | 3342 | } |
3345 | spin_unlock_bh(&adap->tid_release_lock); | 3343 | spin_unlock_bh(&adap->tid_release_lock); |
3346 | } | 3344 | } |
@@ -4140,7 +4138,7 @@ void t4_db_full(struct adapter *adap) | |||
4140 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); | 4138 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); |
4141 | t4_set_reg_field(adap, SGE_INT_ENABLE3, | 4139 | t4_set_reg_field(adap, SGE_INT_ENABLE3, |
4142 | DBFIFO_HP_INT | DBFIFO_LP_INT, 0); | 4140 | DBFIFO_HP_INT | DBFIFO_LP_INT, 0); |
4143 | queue_work(workq, &adap->db_full_task); | 4141 | queue_work(adap->workq, &adap->db_full_task); |
4144 | } | 4142 | } |
4145 | } | 4143 | } |
4146 | 4144 | ||
@@ -4150,7 +4148,7 @@ void t4_db_dropped(struct adapter *adap) | |||
4150 | disable_dbs(adap); | 4148 | disable_dbs(adap); |
4151 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); | 4149 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); |
4152 | } | 4150 | } |
4153 | queue_work(workq, &adap->db_drop_task); | 4151 | queue_work(adap->workq, &adap->db_drop_task); |
4154 | } | 4152 | } |
4155 | 4153 | ||
4156 | static void uld_attach(struct adapter *adap, unsigned int uld) | 4154 | static void uld_attach(struct adapter *adap, unsigned int uld) |
@@ -6517,6 +6515,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6517 | goto out_disable_device; | 6515 | goto out_disable_device; |
6518 | } | 6516 | } |
6519 | 6517 | ||
6518 | adapter->workq = create_singlethread_workqueue("cxgb4"); | ||
6519 | if (!adapter->workq) { | ||
6520 | err = -ENOMEM; | ||
6521 | goto out_free_adapter; | ||
6522 | } | ||
6523 | |||
6520 | /* PCI device has been enabled */ | 6524 | /* PCI device has been enabled */ |
6521 | adapter->flags |= DEV_ENABLED; | 6525 | adapter->flags |= DEV_ENABLED; |
6522 | 6526 | ||
@@ -6715,6 +6719,9 @@ sriov: | |||
6715 | out_unmap_bar0: | 6719 | out_unmap_bar0: |
6716 | iounmap(adapter->regs); | 6720 | iounmap(adapter->regs); |
6717 | out_free_adapter: | 6721 | out_free_adapter: |
6722 | if (adapter->workq) | ||
6723 | destroy_workqueue(adapter->workq); | ||
6724 | |||
6718 | kfree(adapter); | 6725 | kfree(adapter); |
6719 | out_disable_device: | 6726 | out_disable_device: |
6720 | pci_disable_pcie_error_reporting(pdev); | 6727 | pci_disable_pcie_error_reporting(pdev); |
@@ -6736,6 +6743,11 @@ static void remove_one(struct pci_dev *pdev) | |||
6736 | if (adapter) { | 6743 | if (adapter) { |
6737 | int i; | 6744 | int i; |
6738 | 6745 | ||
6746 | /* Tear down per-adapter Work Queue first since it can contain | ||
6747 | * references to our adapter data structure. | ||
6748 | */ | ||
6749 | destroy_workqueue(adapter->workq); | ||
6750 | |||
6739 | if (is_offload(adapter)) | 6751 | if (is_offload(adapter)) |
6740 | detach_ulds(adapter); | 6752 | detach_ulds(adapter); |
6741 | 6753 | ||
@@ -6788,20 +6800,14 @@ static int __init cxgb4_init_module(void) | |||
6788 | { | 6800 | { |
6789 | int ret; | 6801 | int ret; |
6790 | 6802 | ||
6791 | workq = create_singlethread_workqueue("cxgb4"); | ||
6792 | if (!workq) | ||
6793 | return -ENOMEM; | ||
6794 | |||
6795 | /* Debugfs support is optional, just warn if this fails */ | 6803 | /* Debugfs support is optional, just warn if this fails */ |
6796 | cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | 6804 | cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); |
6797 | if (!cxgb4_debugfs_root) | 6805 | if (!cxgb4_debugfs_root) |
6798 | pr_warn("could not create debugfs entry, continuing\n"); | 6806 | pr_warn("could not create debugfs entry, continuing\n"); |
6799 | 6807 | ||
6800 | ret = pci_register_driver(&cxgb4_driver); | 6808 | ret = pci_register_driver(&cxgb4_driver); |
6801 | if (ret < 0) { | 6809 | if (ret < 0) |
6802 | debugfs_remove(cxgb4_debugfs_root); | 6810 | debugfs_remove(cxgb4_debugfs_root); |
6803 | destroy_workqueue(workq); | ||
6804 | } | ||
6805 | 6811 | ||
6806 | register_inet6addr_notifier(&cxgb4_inet6addr_notifier); | 6812 | register_inet6addr_notifier(&cxgb4_inet6addr_notifier); |
6807 | 6813 | ||
@@ -6813,8 +6819,6 @@ static void __exit cxgb4_cleanup_module(void) | |||
6813 | unregister_inet6addr_notifier(&cxgb4_inet6addr_notifier); | 6819 | unregister_inet6addr_notifier(&cxgb4_inet6addr_notifier); |
6814 | pci_unregister_driver(&cxgb4_driver); | 6820 | pci_unregister_driver(&cxgb4_driver); |
6815 | debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ | 6821 | debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ |
6816 | flush_workqueue(workq); | ||
6817 | destroy_workqueue(workq); | ||
6818 | } | 6822 | } |
6819 | 6823 | ||
6820 | module_init(cxgb4_init_module); | 6824 | module_init(cxgb4_init_module); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index b0bba32d69d5..d22d728d4e5c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
@@ -2303,7 +2303,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | |||
2303 | FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); | 2303 | FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); |
2304 | c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | | 2304 | c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | |
2305 | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); | 2305 | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); |
2306 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); | 2306 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE | |
2307 | FW_EQ_ETH_CMD_VIID(pi->viid)); | ||
2307 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | | 2308 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | |
2308 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | | 2309 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | |
2309 | FW_EQ_ETH_CMD_FETCHRO(1) | | 2310 | FW_EQ_ETH_CMD_FETCHRO(1) | |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 0549170d7e2e..5f2729ebadbe 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
@@ -1227,6 +1227,7 @@ struct fw_eq_eth_cmd { | |||
1227 | #define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16) | 1227 | #define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16) |
1228 | #define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0) | 1228 | #define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0) |
1229 | 1229 | ||
1230 | #define FW_EQ_ETH_CMD_AUTOEQUEQE (1U << 30) | ||
1230 | #define FW_EQ_ETH_CMD_VIID(x) ((x) << 16) | 1231 | #define FW_EQ_ETH_CMD_VIID(x) ((x) << 16) |
1231 | 1232 | ||
1232 | struct fw_eq_ctrl_cmd { | 1233 | struct fw_eq_ctrl_cmd { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index bdfa80ca5e31..a5fb9493dee8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c | |||
@@ -2250,7 +2250,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, | |||
2250 | cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC | | 2250 | cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC | |
2251 | FW_EQ_ETH_CMD_EQSTART | | 2251 | FW_EQ_ETH_CMD_EQSTART | |
2252 | FW_LEN16(cmd)); | 2252 | FW_LEN16(cmd)); |
2253 | cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_VIID(pi->viid)); | 2253 | cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_AUTOEQUEQE | |
2254 | FW_EQ_ETH_CMD_VIID(pi->viid)); | ||
2254 | cmd.fetchszm_to_iqid = | 2255 | cmd.fetchszm_to_iqid = |
2255 | cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) | | 2256 | cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) | |
2256 | FW_EQ_ETH_CMD_PCIECHN(pi->port_id) | | 2257 | FW_EQ_ETH_CMD_PCIECHN(pi->port_id) | |
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 9f7fa644a397..ee41d98b44b6 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h | |||
@@ -275,6 +275,9 @@ struct fec_enet_private { | |||
275 | struct clk *clk_enet_out; | 275 | struct clk *clk_enet_out; |
276 | struct clk *clk_ptp; | 276 | struct clk *clk_ptp; |
277 | 277 | ||
278 | bool ptp_clk_on; | ||
279 | struct mutex ptp_clk_mutex; | ||
280 | |||
278 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ | 281 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ |
279 | unsigned char *tx_bounce[TX_RING_SIZE]; | 282 | unsigned char *tx_bounce[TX_RING_SIZE]; |
280 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; | 283 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; |
@@ -335,7 +338,7 @@ struct fec_enet_private { | |||
335 | u32 cycle_speed; | 338 | u32 cycle_speed; |
336 | int hwts_rx_en; | 339 | int hwts_rx_en; |
337 | int hwts_tx_en; | 340 | int hwts_tx_en; |
338 | struct timer_list time_keep; | 341 | struct delayed_work time_keep; |
339 | struct regulator *reg_phy; | 342 | struct regulator *reg_phy; |
340 | }; | 343 | }; |
341 | 344 | ||
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 4f87dffcb9b2..89355a719625 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -1611,17 +1611,27 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) | |||
1611 | goto failed_clk_enet_out; | 1611 | goto failed_clk_enet_out; |
1612 | } | 1612 | } |
1613 | if (fep->clk_ptp) { | 1613 | if (fep->clk_ptp) { |
1614 | mutex_lock(&fep->ptp_clk_mutex); | ||
1614 | ret = clk_prepare_enable(fep->clk_ptp); | 1615 | ret = clk_prepare_enable(fep->clk_ptp); |
1615 | if (ret) | 1616 | if (ret) { |
1617 | mutex_unlock(&fep->ptp_clk_mutex); | ||
1616 | goto failed_clk_ptp; | 1618 | goto failed_clk_ptp; |
1619 | } else { | ||
1620 | fep->ptp_clk_on = true; | ||
1621 | } | ||
1622 | mutex_unlock(&fep->ptp_clk_mutex); | ||
1617 | } | 1623 | } |
1618 | } else { | 1624 | } else { |
1619 | clk_disable_unprepare(fep->clk_ahb); | 1625 | clk_disable_unprepare(fep->clk_ahb); |
1620 | clk_disable_unprepare(fep->clk_ipg); | 1626 | clk_disable_unprepare(fep->clk_ipg); |
1621 | if (fep->clk_enet_out) | 1627 | if (fep->clk_enet_out) |
1622 | clk_disable_unprepare(fep->clk_enet_out); | 1628 | clk_disable_unprepare(fep->clk_enet_out); |
1623 | if (fep->clk_ptp) | 1629 | if (fep->clk_ptp) { |
1630 | mutex_lock(&fep->ptp_clk_mutex); | ||
1624 | clk_disable_unprepare(fep->clk_ptp); | 1631 | clk_disable_unprepare(fep->clk_ptp); |
1632 | fep->ptp_clk_on = false; | ||
1633 | mutex_unlock(&fep->ptp_clk_mutex); | ||
1634 | } | ||
1625 | } | 1635 | } |
1626 | 1636 | ||
1627 | return 0; | 1637 | return 0; |
@@ -2625,6 +2635,8 @@ fec_probe(struct platform_device *pdev) | |||
2625 | if (IS_ERR(fep->clk_enet_out)) | 2635 | if (IS_ERR(fep->clk_enet_out)) |
2626 | fep->clk_enet_out = NULL; | 2636 | fep->clk_enet_out = NULL; |
2627 | 2637 | ||
2638 | fep->ptp_clk_on = false; | ||
2639 | mutex_init(&fep->ptp_clk_mutex); | ||
2628 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); | 2640 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); |
2629 | fep->bufdesc_ex = | 2641 | fep->bufdesc_ex = |
2630 | pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; | 2642 | pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; |
@@ -2715,10 +2727,10 @@ fec_drv_remove(struct platform_device *pdev) | |||
2715 | struct net_device *ndev = platform_get_drvdata(pdev); | 2727 | struct net_device *ndev = platform_get_drvdata(pdev); |
2716 | struct fec_enet_private *fep = netdev_priv(ndev); | 2728 | struct fec_enet_private *fep = netdev_priv(ndev); |
2717 | 2729 | ||
2730 | cancel_delayed_work_sync(&fep->time_keep); | ||
2718 | cancel_work_sync(&fep->tx_timeout_work); | 2731 | cancel_work_sync(&fep->tx_timeout_work); |
2719 | unregister_netdev(ndev); | 2732 | unregister_netdev(ndev); |
2720 | fec_enet_mii_remove(fep); | 2733 | fec_enet_mii_remove(fep); |
2721 | del_timer_sync(&fep->time_keep); | ||
2722 | if (fep->reg_phy) | 2734 | if (fep->reg_phy) |
2723 | regulator_disable(fep->reg_phy); | 2735 | regulator_disable(fep->reg_phy); |
2724 | if (fep->ptp_clock) | 2736 | if (fep->ptp_clock) |
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 82386b29914a..cca3617a2321 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c | |||
@@ -245,12 +245,20 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp, | |||
245 | u64 ns; | 245 | u64 ns; |
246 | unsigned long flags; | 246 | unsigned long flags; |
247 | 247 | ||
248 | mutex_lock(&fep->ptp_clk_mutex); | ||
249 | /* Check the ptp clock */ | ||
250 | if (!fep->ptp_clk_on) { | ||
251 | mutex_unlock(&fep->ptp_clk_mutex); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
248 | ns = ts->tv_sec * 1000000000ULL; | 255 | ns = ts->tv_sec * 1000000000ULL; |
249 | ns += ts->tv_nsec; | 256 | ns += ts->tv_nsec; |
250 | 257 | ||
251 | spin_lock_irqsave(&fep->tmreg_lock, flags); | 258 | spin_lock_irqsave(&fep->tmreg_lock, flags); |
252 | timecounter_init(&fep->tc, &fep->cc, ns); | 259 | timecounter_init(&fep->tc, &fep->cc, ns); |
253 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | 260 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); |
261 | mutex_unlock(&fep->ptp_clk_mutex); | ||
254 | return 0; | 262 | return 0; |
255 | } | 263 | } |
256 | 264 | ||
@@ -338,17 +346,22 @@ int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr) | |||
338 | * fec_time_keep - call timecounter_read every second to avoid timer overrun | 346 | * fec_time_keep - call timecounter_read every second to avoid timer overrun |
339 | * because ENET just support 32bit counter, will timeout in 4s | 347 | * because ENET just support 32bit counter, will timeout in 4s |
340 | */ | 348 | */ |
341 | static void fec_time_keep(unsigned long _data) | 349 | static void fec_time_keep(struct work_struct *work) |
342 | { | 350 | { |
343 | struct fec_enet_private *fep = (struct fec_enet_private *)_data; | 351 | struct delayed_work *dwork = to_delayed_work(work); |
352 | struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep); | ||
344 | u64 ns; | 353 | u64 ns; |
345 | unsigned long flags; | 354 | unsigned long flags; |
346 | 355 | ||
347 | spin_lock_irqsave(&fep->tmreg_lock, flags); | 356 | mutex_lock(&fep->ptp_clk_mutex); |
348 | ns = timecounter_read(&fep->tc); | 357 | if (fep->ptp_clk_on) { |
349 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | 358 | spin_lock_irqsave(&fep->tmreg_lock, flags); |
359 | ns = timecounter_read(&fep->tc); | ||
360 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
361 | } | ||
362 | mutex_unlock(&fep->ptp_clk_mutex); | ||
350 | 363 | ||
351 | mod_timer(&fep->time_keep, jiffies + HZ); | 364 | schedule_delayed_work(&fep->time_keep, HZ); |
352 | } | 365 | } |
353 | 366 | ||
354 | /** | 367 | /** |
@@ -386,15 +399,13 @@ void fec_ptp_init(struct platform_device *pdev) | |||
386 | 399 | ||
387 | fec_ptp_start_cyclecounter(ndev); | 400 | fec_ptp_start_cyclecounter(ndev); |
388 | 401 | ||
389 | init_timer(&fep->time_keep); | 402 | INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep); |
390 | fep->time_keep.data = (unsigned long)fep; | ||
391 | fep->time_keep.function = fec_time_keep; | ||
392 | fep->time_keep.expires = jiffies + HZ; | ||
393 | add_timer(&fep->time_keep); | ||
394 | 403 | ||
395 | fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev); | 404 | fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev); |
396 | if (IS_ERR(fep->ptp_clock)) { | 405 | if (IS_ERR(fep->ptp_clock)) { |
397 | fep->ptp_clock = NULL; | 406 | fep->ptp_clock = NULL; |
398 | pr_err("ptp_clock_register failed\n"); | 407 | pr_err("ptp_clock_register failed\n"); |
399 | } | 408 | } |
409 | |||
410 | schedule_delayed_work(&fep->time_keep, HZ); | ||
400 | } | 411 | } |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index c9127562bd22..21978cc019e7 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
@@ -292,6 +292,18 @@ failure: | |||
292 | atomic_add(buffers_added, &(pool->available)); | 292 | atomic_add(buffers_added, &(pool->available)); |
293 | } | 293 | } |
294 | 294 | ||
295 | /* | ||
296 | * The final 8 bytes of the buffer list is a counter of frames dropped | ||
297 | * because there was not a buffer in the buffer list capable of holding | ||
298 | * the frame. | ||
299 | */ | ||
300 | static void ibmveth_update_rx_no_buffer(struct ibmveth_adapter *adapter) | ||
301 | { | ||
302 | __be64 *p = adapter->buffer_list_addr + 4096 - 8; | ||
303 | |||
304 | adapter->rx_no_buffer = be64_to_cpup(p); | ||
305 | } | ||
306 | |||
295 | /* replenish routine */ | 307 | /* replenish routine */ |
296 | static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) | 308 | static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) |
297 | { | 309 | { |
@@ -307,8 +319,7 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) | |||
307 | ibmveth_replenish_buffer_pool(adapter, pool); | 319 | ibmveth_replenish_buffer_pool(adapter, pool); |
308 | } | 320 | } |
309 | 321 | ||
310 | adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) + | 322 | ibmveth_update_rx_no_buffer(adapter); |
311 | 4096 - 8); | ||
312 | } | 323 | } |
313 | 324 | ||
314 | /* empty and free ana buffer pool - also used to do cleanup in error paths */ | 325 | /* empty and free ana buffer pool - also used to do cleanup in error paths */ |
@@ -698,8 +709,7 @@ static int ibmveth_close(struct net_device *netdev) | |||
698 | 709 | ||
699 | free_irq(netdev->irq, netdev); | 710 | free_irq(netdev->irq, netdev); |
700 | 711 | ||
701 | adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) + | 712 | ibmveth_update_rx_no_buffer(adapter); |
702 | 4096 - 8); | ||
703 | 713 | ||
704 | ibmveth_cleanup(adapter); | 714 | ibmveth_cleanup(adapter); |
705 | 715 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index bb7fe98b3a6c..537b6216971d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c | |||
@@ -247,7 +247,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi) | |||
247 | u32 prttsyn_stat; | 247 | u32 prttsyn_stat; |
248 | int n; | 248 | int n; |
249 | 249 | ||
250 | if (pf->flags & I40E_FLAG_PTP) | 250 | if (!(pf->flags & I40E_FLAG_PTP)) |
251 | return; | 251 | return; |
252 | 252 | ||
253 | prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_1); | 253 | prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_1); |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 89672551dce9..3ac6a0d2f143 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | |||
@@ -1003,11 +1003,19 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) | |||
1003 | static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode, | 1003 | static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode, |
1004 | u32 v_retval, u8 *msg, u16 msglen) | 1004 | u32 v_retval, u8 *msg, u16 msglen) |
1005 | { | 1005 | { |
1006 | struct i40e_pf *pf = vf->pf; | 1006 | struct i40e_pf *pf; |
1007 | struct i40e_hw *hw = &pf->hw; | 1007 | struct i40e_hw *hw; |
1008 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | 1008 | int abs_vf_id; |
1009 | i40e_status aq_ret; | 1009 | i40e_status aq_ret; |
1010 | 1010 | ||
1011 | /* validate the request */ | ||
1012 | if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs) | ||
1013 | return -EINVAL; | ||
1014 | |||
1015 | pf = vf->pf; | ||
1016 | hw = &pf->hw; | ||
1017 | abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1018 | |||
1011 | /* single place to detect unsuccessful return values */ | 1019 | /* single place to detect unsuccessful return values */ |
1012 | if (v_retval) { | 1020 | if (v_retval) { |
1013 | vf->num_invalid_msgs++; | 1021 | vf->num_invalid_msgs++; |
@@ -1928,17 +1936,20 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf, | |||
1928 | { | 1936 | { |
1929 | struct i40e_hw *hw = &pf->hw; | 1937 | struct i40e_hw *hw = &pf->hw; |
1930 | struct i40e_vf *vf = pf->vf; | 1938 | struct i40e_vf *vf = pf->vf; |
1931 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1932 | int i; | 1939 | int i; |
1933 | 1940 | ||
1934 | for (i = 0; i < pf->num_alloc_vfs; i++) { | 1941 | for (i = 0; i < pf->num_alloc_vfs; i++, vf++) { |
1942 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1943 | /* Not all vfs are enabled so skip the ones that are not */ | ||
1944 | if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) && | ||
1945 | !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) | ||
1946 | continue; | ||
1947 | |||
1935 | /* Ignore return value on purpose - a given VF may fail, but | 1948 | /* Ignore return value on purpose - a given VF may fail, but |
1936 | * we need to keep going and send to all of them | 1949 | * we need to keep going and send to all of them |
1937 | */ | 1950 | */ |
1938 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval, | 1951 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval, |
1939 | msg, msglen, NULL); | 1952 | msg, msglen, NULL); |
1940 | vf++; | ||
1941 | abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1942 | } | 1953 | } |
1943 | } | 1954 | } |
1944 | 1955 | ||
@@ -1954,12 +1965,12 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf) | |||
1954 | struct i40e_hw *hw = &pf->hw; | 1965 | struct i40e_hw *hw = &pf->hw; |
1955 | struct i40e_vf *vf = pf->vf; | 1966 | struct i40e_vf *vf = pf->vf; |
1956 | struct i40e_link_status *ls = &pf->hw.phy.link_info; | 1967 | struct i40e_link_status *ls = &pf->hw.phy.link_info; |
1957 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1958 | int i; | 1968 | int i; |
1959 | 1969 | ||
1960 | pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; | 1970 | pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; |
1961 | pfe.severity = I40E_PF_EVENT_SEVERITY_INFO; | 1971 | pfe.severity = I40E_PF_EVENT_SEVERITY_INFO; |
1962 | for (i = 0; i < pf->num_alloc_vfs; i++) { | 1972 | for (i = 0; i < pf->num_alloc_vfs; i++, vf++) { |
1973 | int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1963 | if (vf->link_forced) { | 1974 | if (vf->link_forced) { |
1964 | pfe.event_data.link_event.link_status = vf->link_up; | 1975 | pfe.event_data.link_event.link_status = vf->link_up; |
1965 | pfe.event_data.link_event.link_speed = | 1976 | pfe.event_data.link_event.link_speed = |
@@ -1972,8 +1983,6 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf) | |||
1972 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT, | 1983 | i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT, |
1973 | 0, (u8 *)&pfe, sizeof(pfe), | 1984 | 0, (u8 *)&pfe, sizeof(pfe), |
1974 | NULL); | 1985 | NULL); |
1975 | vf++; | ||
1976 | abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; | ||
1977 | } | 1986 | } |
1978 | } | 1987 | } |
1979 | 1988 | ||
@@ -2002,7 +2011,18 @@ void i40e_vc_notify_reset(struct i40e_pf *pf) | |||
2002 | void i40e_vc_notify_vf_reset(struct i40e_vf *vf) | 2011 | void i40e_vc_notify_vf_reset(struct i40e_vf *vf) |
2003 | { | 2012 | { |
2004 | struct i40e_virtchnl_pf_event pfe; | 2013 | struct i40e_virtchnl_pf_event pfe; |
2005 | int abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id; | 2014 | int abs_vf_id; |
2015 | |||
2016 | /* validate the request */ | ||
2017 | if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs) | ||
2018 | return; | ||
2019 | |||
2020 | /* verify if the VF is in either init or active before proceeding */ | ||
2021 | if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) && | ||
2022 | !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) | ||
2023 | return; | ||
2024 | |||
2025 | abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id; | ||
2006 | 2026 | ||
2007 | pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING; | 2027 | pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING; |
2008 | pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM; | 2028 | pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 16039d1497b8..b84f5ea3d659 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -268,7 +268,7 @@ struct qlcnic_fdt { | |||
268 | u16 cksum; | 268 | u16 cksum; |
269 | u16 unused; | 269 | u16 unused; |
270 | u8 model[16]; | 270 | u8 model[16]; |
271 | u16 mfg_id; | 271 | u8 mfg_id; |
272 | u16 id; | 272 | u16 id; |
273 | u8 flag; | 273 | u8 flag; |
274 | u8 erase_cmd; | 274 | u8 erase_cmd; |
@@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) | |||
2362 | return QLC_DEFAULT_VNIC_COUNT; | 2362 | return QLC_DEFAULT_VNIC_COUNT; |
2363 | } | 2363 | } |
2364 | 2364 | ||
2365 | static inline void qlcnic_swap32_buffer(u32 *buffer, int count) | ||
2366 | { | ||
2367 | #if defined(__BIG_ENDIAN) | ||
2368 | u32 *tmp = buffer; | ||
2369 | int i; | ||
2370 | |||
2371 | for (i = 0; i < count; i++) { | ||
2372 | *tmp = swab32(*tmp); | ||
2373 | tmp++; | ||
2374 | } | ||
2375 | #endif | ||
2376 | } | ||
2377 | |||
2365 | #ifdef CONFIG_QLCNIC_HWMON | 2378 | #ifdef CONFIG_QLCNIC_HWMON |
2366 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); | 2379 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); |
2367 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); | 2380 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index a4a4ec0b68f8..476e4998ef99 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -2603,7 +2603,7 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, | |||
2603 | } | 2603 | } |
2604 | 2604 | ||
2605 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW, | 2605 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW, |
2606 | (addr)); | 2606 | (addr & 0xFFFF0000)); |
2607 | 2607 | ||
2608 | range = flash_offset + (count * sizeof(u32)); | 2608 | range = flash_offset + (count * sizeof(u32)); |
2609 | /* Check if data is spread across multiple sectors */ | 2609 | /* Check if data is spread across multiple sectors */ |
@@ -2753,7 +2753,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter) | |||
2753 | ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION, | 2753 | ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION, |
2754 | (u8 *)&adapter->ahw->fdt, | 2754 | (u8 *)&adapter->ahw->fdt, |
2755 | count); | 2755 | count); |
2756 | 2756 | qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count); | |
2757 | qlcnic_83xx_unlock_flash(adapter); | 2757 | qlcnic_83xx_unlock_flash(adapter); |
2758 | return ret; | 2758 | return ret; |
2759 | } | 2759 | } |
@@ -2788,7 +2788,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter, | |||
2788 | 2788 | ||
2789 | addr1 = (sector_start_addr & 0xFF) << 16; | 2789 | addr1 = (sector_start_addr & 0xFF) << 16; |
2790 | addr2 = (sector_start_addr & 0xFF0000) >> 16; | 2790 | addr2 = (sector_start_addr & 0xFF0000) >> 16; |
2791 | reversed_addr = addr1 | addr2; | 2791 | reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00); |
2792 | 2792 | ||
2793 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, | 2793 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, |
2794 | reversed_addr); | 2794 | reversed_addr); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index f33559b72528..86783e1afcf7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -1378,31 +1378,45 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) | |||
1378 | { | 1378 | { |
1379 | struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; | 1379 | struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; |
1380 | const struct firmware *fw = fw_info->fw; | 1380 | const struct firmware *fw = fw_info->fw; |
1381 | u32 dest, *p_cache; | 1381 | u32 dest, *p_cache, *temp; |
1382 | int i, ret = -EIO; | 1382 | int i, ret = -EIO; |
1383 | __le32 *temp_le; | ||
1383 | u8 data[16]; | 1384 | u8 data[16]; |
1384 | size_t size; | 1385 | size_t size; |
1385 | u64 addr; | 1386 | u64 addr; |
1386 | 1387 | ||
1388 | temp = kzalloc(fw->size, GFP_KERNEL); | ||
1389 | if (!temp) { | ||
1390 | release_firmware(fw); | ||
1391 | fw_info->fw = NULL; | ||
1392 | return -ENOMEM; | ||
1393 | } | ||
1394 | |||
1395 | temp_le = (__le32 *)fw->data; | ||
1396 | |||
1397 | /* FW image in file is in little endian, swap the data to nullify | ||
1398 | * the effect of writel() operation on big endian platform. | ||
1399 | */ | ||
1400 | for (i = 0; i < fw->size / sizeof(u32); i++) | ||
1401 | temp[i] = __le32_to_cpu(temp_le[i]); | ||
1402 | |||
1387 | dest = QLCRDX(adapter->ahw, QLCNIC_FW_IMAGE_ADDR); | 1403 | dest = QLCRDX(adapter->ahw, QLCNIC_FW_IMAGE_ADDR); |
1388 | size = (fw->size & ~0xF); | 1404 | size = (fw->size & ~0xF); |
1389 | p_cache = (u32 *)fw->data; | 1405 | p_cache = temp; |
1390 | addr = (u64)dest; | 1406 | addr = (u64)dest; |
1391 | 1407 | ||
1392 | ret = qlcnic_ms_mem_write128(adapter, addr, | 1408 | ret = qlcnic_ms_mem_write128(adapter, addr, |
1393 | p_cache, size / 16); | 1409 | p_cache, size / 16); |
1394 | if (ret) { | 1410 | if (ret) { |
1395 | dev_err(&adapter->pdev->dev, "MS memory write failed\n"); | 1411 | dev_err(&adapter->pdev->dev, "MS memory write failed\n"); |
1396 | release_firmware(fw); | 1412 | goto exit; |
1397 | fw_info->fw = NULL; | ||
1398 | return -EIO; | ||
1399 | } | 1413 | } |
1400 | 1414 | ||
1401 | /* alignment check */ | 1415 | /* alignment check */ |
1402 | if (fw->size & 0xF) { | 1416 | if (fw->size & 0xF) { |
1403 | addr = dest + size; | 1417 | addr = dest + size; |
1404 | for (i = 0; i < (fw->size & 0xF); i++) | 1418 | for (i = 0; i < (fw->size & 0xF); i++) |
1405 | data[i] = fw->data[size + i]; | 1419 | data[i] = temp[size + i]; |
1406 | for (; i < 16; i++) | 1420 | for (; i < 16; i++) |
1407 | data[i] = 0; | 1421 | data[i] = 0; |
1408 | ret = qlcnic_ms_mem_write128(adapter, addr, | 1422 | ret = qlcnic_ms_mem_write128(adapter, addr, |
@@ -1410,15 +1424,16 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) | |||
1410 | if (ret) { | 1424 | if (ret) { |
1411 | dev_err(&adapter->pdev->dev, | 1425 | dev_err(&adapter->pdev->dev, |
1412 | "MS memory write failed\n"); | 1426 | "MS memory write failed\n"); |
1413 | release_firmware(fw); | 1427 | goto exit; |
1414 | fw_info->fw = NULL; | ||
1415 | return -EIO; | ||
1416 | } | 1428 | } |
1417 | } | 1429 | } |
1430 | |||
1431 | exit: | ||
1418 | release_firmware(fw); | 1432 | release_firmware(fw); |
1419 | fw_info->fw = NULL; | 1433 | fw_info->fw = NULL; |
1434 | kfree(temp); | ||
1420 | 1435 | ||
1421 | return 0; | 1436 | return ret; |
1422 | } | 1437 | } |
1423 | 1438 | ||
1424 | static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter) | 1439 | static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index e46fc39d425d..c9f57fb84b9e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | |||
@@ -47,15 +47,26 @@ struct qlcnic_common_entry_hdr { | |||
47 | u32 type; | 47 | u32 type; |
48 | u32 offset; | 48 | u32 offset; |
49 | u32 cap_size; | 49 | u32 cap_size; |
50 | #if defined(__LITTLE_ENDIAN) | ||
50 | u8 mask; | 51 | u8 mask; |
51 | u8 rsvd[2]; | 52 | u8 rsvd[2]; |
52 | u8 flags; | 53 | u8 flags; |
54 | #else | ||
55 | u8 flags; | ||
56 | u8 rsvd[2]; | ||
57 | u8 mask; | ||
58 | #endif | ||
53 | } __packed; | 59 | } __packed; |
54 | 60 | ||
55 | struct __crb { | 61 | struct __crb { |
56 | u32 addr; | 62 | u32 addr; |
63 | #if defined(__LITTLE_ENDIAN) | ||
57 | u8 stride; | 64 | u8 stride; |
58 | u8 rsvd1[3]; | 65 | u8 rsvd1[3]; |
66 | #else | ||
67 | u8 rsvd1[3]; | ||
68 | u8 stride; | ||
69 | #endif | ||
59 | u32 data_size; | 70 | u32 data_size; |
60 | u32 no_ops; | 71 | u32 no_ops; |
61 | u32 rsvd2[4]; | 72 | u32 rsvd2[4]; |
@@ -63,15 +74,28 @@ struct __crb { | |||
63 | 74 | ||
64 | struct __ctrl { | 75 | struct __ctrl { |
65 | u32 addr; | 76 | u32 addr; |
77 | #if defined(__LITTLE_ENDIAN) | ||
66 | u8 stride; | 78 | u8 stride; |
67 | u8 index_a; | 79 | u8 index_a; |
68 | u16 timeout; | 80 | u16 timeout; |
81 | #else | ||
82 | u16 timeout; | ||
83 | u8 index_a; | ||
84 | u8 stride; | ||
85 | #endif | ||
69 | u32 data_size; | 86 | u32 data_size; |
70 | u32 no_ops; | 87 | u32 no_ops; |
88 | #if defined(__LITTLE_ENDIAN) | ||
71 | u8 opcode; | 89 | u8 opcode; |
72 | u8 index_v; | 90 | u8 index_v; |
73 | u8 shl_val; | 91 | u8 shl_val; |
74 | u8 shr_val; | 92 | u8 shr_val; |
93 | #else | ||
94 | u8 shr_val; | ||
95 | u8 shl_val; | ||
96 | u8 index_v; | ||
97 | u8 opcode; | ||
98 | #endif | ||
75 | u32 val1; | 99 | u32 val1; |
76 | u32 val2; | 100 | u32 val2; |
77 | u32 val3; | 101 | u32 val3; |
@@ -79,16 +103,27 @@ struct __ctrl { | |||
79 | 103 | ||
80 | struct __cache { | 104 | struct __cache { |
81 | u32 addr; | 105 | u32 addr; |
106 | #if defined(__LITTLE_ENDIAN) | ||
82 | u16 stride; | 107 | u16 stride; |
83 | u16 init_tag_val; | 108 | u16 init_tag_val; |
109 | #else | ||
110 | u16 init_tag_val; | ||
111 | u16 stride; | ||
112 | #endif | ||
84 | u32 size; | 113 | u32 size; |
85 | u32 no_ops; | 114 | u32 no_ops; |
86 | u32 ctrl_addr; | 115 | u32 ctrl_addr; |
87 | u32 ctrl_val; | 116 | u32 ctrl_val; |
88 | u32 read_addr; | 117 | u32 read_addr; |
118 | #if defined(__LITTLE_ENDIAN) | ||
89 | u8 read_addr_stride; | 119 | u8 read_addr_stride; |
90 | u8 read_addr_num; | 120 | u8 read_addr_num; |
91 | u8 rsvd1[2]; | 121 | u8 rsvd1[2]; |
122 | #else | ||
123 | u8 rsvd1[2]; | ||
124 | u8 read_addr_num; | ||
125 | u8 read_addr_stride; | ||
126 | #endif | ||
92 | } __packed; | 127 | } __packed; |
93 | 128 | ||
94 | struct __ocm { | 129 | struct __ocm { |
@@ -122,23 +157,39 @@ struct __mux { | |||
122 | 157 | ||
123 | struct __queue { | 158 | struct __queue { |
124 | u32 sel_addr; | 159 | u32 sel_addr; |
160 | #if defined(__LITTLE_ENDIAN) | ||
125 | u16 stride; | 161 | u16 stride; |
126 | u8 rsvd[2]; | 162 | u8 rsvd[2]; |
163 | #else | ||
164 | u8 rsvd[2]; | ||
165 | u16 stride; | ||
166 | #endif | ||
127 | u32 size; | 167 | u32 size; |
128 | u32 no_ops; | 168 | u32 no_ops; |
129 | u8 rsvd2[8]; | 169 | u8 rsvd2[8]; |
130 | u32 read_addr; | 170 | u32 read_addr; |
171 | #if defined(__LITTLE_ENDIAN) | ||
131 | u8 read_addr_stride; | 172 | u8 read_addr_stride; |
132 | u8 read_addr_cnt; | 173 | u8 read_addr_cnt; |
133 | u8 rsvd3[2]; | 174 | u8 rsvd3[2]; |
175 | #else | ||
176 | u8 rsvd3[2]; | ||
177 | u8 read_addr_cnt; | ||
178 | u8 read_addr_stride; | ||
179 | #endif | ||
134 | } __packed; | 180 | } __packed; |
135 | 181 | ||
136 | struct __pollrd { | 182 | struct __pollrd { |
137 | u32 sel_addr; | 183 | u32 sel_addr; |
138 | u32 read_addr; | 184 | u32 read_addr; |
139 | u32 sel_val; | 185 | u32 sel_val; |
186 | #if defined(__LITTLE_ENDIAN) | ||
140 | u16 sel_val_stride; | 187 | u16 sel_val_stride; |
141 | u16 no_ops; | 188 | u16 no_ops; |
189 | #else | ||
190 | u16 no_ops; | ||
191 | u16 sel_val_stride; | ||
192 | #endif | ||
142 | u32 poll_wait; | 193 | u32 poll_wait; |
143 | u32 poll_mask; | 194 | u32 poll_mask; |
144 | u32 data_size; | 195 | u32 data_size; |
@@ -153,9 +204,15 @@ struct __mux2 { | |||
153 | u32 no_ops; | 204 | u32 no_ops; |
154 | u32 sel_val_mask; | 205 | u32 sel_val_mask; |
155 | u32 read_addr; | 206 | u32 read_addr; |
207 | #if defined(__LITTLE_ENDIAN) | ||
156 | u8 sel_val_stride; | 208 | u8 sel_val_stride; |
157 | u8 data_size; | 209 | u8 data_size; |
158 | u8 rsvd[2]; | 210 | u8 rsvd[2]; |
211 | #else | ||
212 | u8 rsvd[2]; | ||
213 | u8 data_size; | ||
214 | u8 sel_val_stride; | ||
215 | #endif | ||
159 | } __packed; | 216 | } __packed; |
160 | 217 | ||
161 | struct __pollrdmwr { | 218 | struct __pollrdmwr { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index f5786d5792df..59a721fba018 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, | |||
280 | if (ret != 0) | 280 | if (ret != 0) |
281 | return ret; | 281 | return ret; |
282 | qlcnic_read_crb(adapter, buf, offset, size); | 282 | qlcnic_read_crb(adapter, buf, offset, size); |
283 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
283 | 284 | ||
284 | return size; | 285 | return size; |
285 | } | 286 | } |
@@ -296,6 +297,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, | |||
296 | if (ret != 0) | 297 | if (ret != 0) |
297 | return ret; | 298 | return ret; |
298 | 299 | ||
300 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
299 | qlcnic_write_crb(adapter, buf, offset, size); | 301 | qlcnic_write_crb(adapter, buf, offset, size); |
300 | return size; | 302 | return size; |
301 | } | 303 | } |
@@ -329,6 +331,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, | |||
329 | return -EIO; | 331 | return -EIO; |
330 | 332 | ||
331 | memcpy(buf, &data, size); | 333 | memcpy(buf, &data, size); |
334 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
332 | 335 | ||
333 | return size; | 336 | return size; |
334 | } | 337 | } |
@@ -346,6 +349,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
346 | if (ret != 0) | 349 | if (ret != 0) |
347 | return ret; | 350 | return ret; |
348 | 351 | ||
352 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
349 | memcpy(&data, buf, size); | 353 | memcpy(&data, buf, size); |
350 | 354 | ||
351 | if (qlcnic_pci_mem_write_2M(adapter, offset, data)) | 355 | if (qlcnic_pci_mem_write_2M(adapter, offset, data)) |
@@ -412,6 +416,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
412 | if (rem) | 416 | if (rem) |
413 | return QL_STATUS_INVALID_PARAM; | 417 | return QL_STATUS_INVALID_PARAM; |
414 | 418 | ||
419 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
415 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; | 420 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
416 | ret = validate_pm_config(adapter, pm_cfg, count); | 421 | ret = validate_pm_config(adapter, pm_cfg, count); |
417 | 422 | ||
@@ -474,6 +479,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
474 | pm_cfg[pci_func].dest_npar = 0; | 479 | pm_cfg[pci_func].dest_npar = 0; |
475 | pm_cfg[pci_func].pci_func = i; | 480 | pm_cfg[pci_func].pci_func = i; |
476 | } | 481 | } |
482 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
477 | return size; | 483 | return size; |
478 | } | 484 | } |
479 | 485 | ||
@@ -555,6 +561,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
555 | if (rem) | 561 | if (rem) |
556 | return QL_STATUS_INVALID_PARAM; | 562 | return QL_STATUS_INVALID_PARAM; |
557 | 563 | ||
564 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
558 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; | 565 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; |
559 | ret = validate_esw_config(adapter, esw_cfg, count); | 566 | ret = validate_esw_config(adapter, esw_cfg, count); |
560 | if (ret) | 567 | if (ret) |
@@ -649,6 +656,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
649 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) | 656 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) |
650 | return QL_STATUS_INVALID_PARAM; | 657 | return QL_STATUS_INVALID_PARAM; |
651 | } | 658 | } |
659 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
652 | return size; | 660 | return size; |
653 | } | 661 | } |
654 | 662 | ||
@@ -688,6 +696,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
688 | if (rem) | 696 | if (rem) |
689 | return QL_STATUS_INVALID_PARAM; | 697 | return QL_STATUS_INVALID_PARAM; |
690 | 698 | ||
699 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
691 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; | 700 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; |
692 | ret = validate_npar_config(adapter, np_cfg, count); | 701 | ret = validate_npar_config(adapter, np_cfg, count); |
693 | if (ret) | 702 | if (ret) |
@@ -759,6 +768,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
759 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; | 768 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; |
760 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; | 769 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; |
761 | } | 770 | } |
771 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
762 | return size; | 772 | return size; |
763 | } | 773 | } |
764 | 774 | ||
@@ -916,6 +926,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
916 | 926 | ||
917 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; | 927 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; |
918 | count = size / sizeof(struct qlcnic_pci_func_cfg); | 928 | count = size / sizeof(struct qlcnic_pci_func_cfg); |
929 | qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32)); | ||
919 | for (i = 0; i < count; i++) { | 930 | for (i = 0; i < count; i++) { |
920 | pci_cfg[i].pci_func = pci_info[i].id; | 931 | pci_cfg[i].pci_func = pci_info[i].id; |
921 | pci_cfg[i].func_type = pci_info[i].type; | 932 | pci_cfg[i].func_type = pci_info[i].type; |
@@ -969,6 +980,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp, | |||
969 | } | 980 | } |
970 | 981 | ||
971 | qlcnic_83xx_unlock_flash(adapter); | 982 | qlcnic_83xx_unlock_flash(adapter); |
983 | qlcnic_swap32_buffer((u32 *)p_read_buf, count); | ||
972 | memcpy(buf, p_read_buf, size); | 984 | memcpy(buf, p_read_buf, size); |
973 | kfree(p_read_buf); | 985 | kfree(p_read_buf); |
974 | 986 | ||
@@ -986,9 +998,10 @@ static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter, | |||
986 | if (!p_cache) | 998 | if (!p_cache) |
987 | return -ENOMEM; | 999 | return -ENOMEM; |
988 | 1000 | ||
1001 | count = size / sizeof(u32); | ||
1002 | qlcnic_swap32_buffer((u32 *)buf, count); | ||
989 | memcpy(p_cache, buf, size); | 1003 | memcpy(p_cache, buf, size); |
990 | p_src = p_cache; | 1004 | p_src = p_cache; |
991 | count = size / sizeof(u32); | ||
992 | 1005 | ||
993 | if (qlcnic_83xx_lock_flash(adapter) != 0) { | 1006 | if (qlcnic_83xx_lock_flash(adapter) != 0) { |
994 | kfree(p_cache); | 1007 | kfree(p_cache); |
@@ -1053,6 +1066,7 @@ static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter, | |||
1053 | if (!p_cache) | 1066 | if (!p_cache) |
1054 | return -ENOMEM; | 1067 | return -ENOMEM; |
1055 | 1068 | ||
1069 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
1056 | memcpy(p_cache, buf, size); | 1070 | memcpy(p_cache, buf, size); |
1057 | p_src = p_cache; | 1071 | p_src = p_cache; |
1058 | count = size / sizeof(u32); | 1072 | count = size / sizeof(u32); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 60e4ca01ccbb..a96955597755 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -739,7 +739,10 @@ static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |||
739 | struct macvlan_dev *vlan = netdev_priv(dev); | 739 | struct macvlan_dev *vlan = netdev_priv(dev); |
740 | int err = -EINVAL; | 740 | int err = -EINVAL; |
741 | 741 | ||
742 | if (!vlan->port->passthru) | 742 | /* Support unicast filter only on passthru devices. |
743 | * Multicast filter should be allowed on all devices. | ||
744 | */ | ||
745 | if (!vlan->port->passthru && is_unicast_ether_addr(addr)) | ||
743 | return -EOPNOTSUPP; | 746 | return -EOPNOTSUPP; |
744 | 747 | ||
745 | if (flags & NLM_F_REPLACE) | 748 | if (flags & NLM_F_REPLACE) |
@@ -760,7 +763,10 @@ static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], | |||
760 | struct macvlan_dev *vlan = netdev_priv(dev); | 763 | struct macvlan_dev *vlan = netdev_priv(dev); |
761 | int err = -EINVAL; | 764 | int err = -EINVAL; |
762 | 765 | ||
763 | if (!vlan->port->passthru) | 766 | /* Support unicast filter only on passthru devices. |
767 | * Multicast filter should be allowed on all devices. | ||
768 | */ | ||
769 | if (!vlan->port->passthru && is_unicast_ether_addr(addr)) | ||
764 | return -EOPNOTSUPP; | 770 | return -EOPNOTSUPP; |
765 | 771 | ||
766 | if (is_unicast_ether_addr(addr)) | 772 | if (is_unicast_ether_addr(addr)) |
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 526b94cea569..fdce1ea28790 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c | |||
@@ -157,6 +157,23 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev) | |||
157 | return bcm7xxx_28nm_afe_config_init(phydev); | 157 | return bcm7xxx_28nm_afe_config_init(phydev); |
158 | } | 158 | } |
159 | 159 | ||
160 | static int bcm7xxx_28nm_resume(struct phy_device *phydev) | ||
161 | { | ||
162 | int ret; | ||
163 | |||
164 | /* Re-apply workarounds coming out suspend/resume */ | ||
165 | ret = bcm7xxx_28nm_config_init(phydev); | ||
166 | if (ret) | ||
167 | return ret; | ||
168 | |||
169 | /* 28nm Gigabit PHYs come out of reset without any half-duplex | ||
170 | * or "hub" compliant advertised mode, fix that. This does not | ||
171 | * cause any problems with the PHY library since genphy_config_aneg() | ||
172 | * gracefully handles auto-negotiated and forced modes. | ||
173 | */ | ||
174 | return genphy_config_aneg(phydev); | ||
175 | } | ||
176 | |||
160 | static int phy_set_clr_bits(struct phy_device *dev, int location, | 177 | static int phy_set_clr_bits(struct phy_device *dev, int location, |
161 | int set_mask, int clr_mask) | 178 | int set_mask, int clr_mask) |
162 | { | 179 | { |
@@ -212,7 +229,7 @@ static int bcm7xxx_config_init(struct phy_device *phydev) | |||
212 | } | 229 | } |
213 | 230 | ||
214 | /* Workaround for putting the PHY in IDDQ mode, required | 231 | /* Workaround for putting the PHY in IDDQ mode, required |
215 | * for all BCM7XXX PHYs | 232 | * for all BCM7XXX 40nm and 65nm PHYs |
216 | */ | 233 | */ |
217 | static int bcm7xxx_suspend(struct phy_device *phydev) | 234 | static int bcm7xxx_suspend(struct phy_device *phydev) |
218 | { | 235 | { |
@@ -257,8 +274,7 @@ static struct phy_driver bcm7xxx_driver[] = { | |||
257 | .config_init = bcm7xxx_28nm_afe_config_init, | 274 | .config_init = bcm7xxx_28nm_afe_config_init, |
258 | .config_aneg = genphy_config_aneg, | 275 | .config_aneg = genphy_config_aneg, |
259 | .read_status = genphy_read_status, | 276 | .read_status = genphy_read_status, |
260 | .suspend = bcm7xxx_suspend, | 277 | .resume = bcm7xxx_28nm_resume, |
261 | .resume = bcm7xxx_28nm_afe_config_init, | ||
262 | .driver = { .owner = THIS_MODULE }, | 278 | .driver = { .owner = THIS_MODULE }, |
263 | }, { | 279 | }, { |
264 | .phy_id = PHY_ID_BCM7439, | 280 | .phy_id = PHY_ID_BCM7439, |
@@ -270,8 +286,7 @@ static struct phy_driver bcm7xxx_driver[] = { | |||
270 | .config_init = bcm7xxx_28nm_afe_config_init, | 286 | .config_init = bcm7xxx_28nm_afe_config_init, |
271 | .config_aneg = genphy_config_aneg, | 287 | .config_aneg = genphy_config_aneg, |
272 | .read_status = genphy_read_status, | 288 | .read_status = genphy_read_status, |
273 | .suspend = bcm7xxx_suspend, | 289 | .resume = bcm7xxx_28nm_resume, |
274 | .resume = bcm7xxx_28nm_afe_config_init, | ||
275 | .driver = { .owner = THIS_MODULE }, | 290 | .driver = { .owner = THIS_MODULE }, |
276 | }, { | 291 | }, { |
277 | .phy_id = PHY_ID_BCM7445, | 292 | .phy_id = PHY_ID_BCM7445, |
@@ -283,21 +298,7 @@ static struct phy_driver bcm7xxx_driver[] = { | |||
283 | .config_init = bcm7xxx_28nm_config_init, | 298 | .config_init = bcm7xxx_28nm_config_init, |
284 | .config_aneg = genphy_config_aneg, | 299 | .config_aneg = genphy_config_aneg, |
285 | .read_status = genphy_read_status, | 300 | .read_status = genphy_read_status, |
286 | .suspend = bcm7xxx_suspend, | 301 | .resume = bcm7xxx_28nm_afe_config_init, |
287 | .resume = bcm7xxx_28nm_config_init, | ||
288 | .driver = { .owner = THIS_MODULE }, | ||
289 | }, { | ||
290 | .name = "Broadcom BCM7XXX 28nm", | ||
291 | .phy_id = PHY_ID_BCM7XXX_28, | ||
292 | .phy_id_mask = PHY_BCM_OUI_MASK, | ||
293 | .features = PHY_GBIT_FEATURES | | ||
294 | SUPPORTED_Pause | SUPPORTED_Asym_Pause, | ||
295 | .flags = PHY_IS_INTERNAL, | ||
296 | .config_init = bcm7xxx_28nm_config_init, | ||
297 | .config_aneg = genphy_config_aneg, | ||
298 | .read_status = genphy_read_status, | ||
299 | .suspend = bcm7xxx_suspend, | ||
300 | .resume = bcm7xxx_28nm_config_init, | ||
301 | .driver = { .owner = THIS_MODULE }, | 302 | .driver = { .owner = THIS_MODULE }, |
302 | }, { | 303 | }, { |
303 | .phy_id = PHY_BCM_OUI_4, | 304 | .phy_id = PHY_BCM_OUI_4, |
@@ -331,7 +332,6 @@ static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { | |||
331 | { PHY_ID_BCM7366, 0xfffffff0, }, | 332 | { PHY_ID_BCM7366, 0xfffffff0, }, |
332 | { PHY_ID_BCM7439, 0xfffffff0, }, | 333 | { PHY_ID_BCM7439, 0xfffffff0, }, |
333 | { PHY_ID_BCM7445, 0xfffffff0, }, | 334 | { PHY_ID_BCM7445, 0xfffffff0, }, |
334 | { PHY_ID_BCM7XXX_28, 0xfffffc00 }, | ||
335 | { PHY_BCM_OUI_4, 0xffff0000 }, | 335 | { PHY_BCM_OUI_4, 0xffff0000 }, |
336 | { PHY_BCM_OUI_5, 0xffffff00 }, | 336 | { PHY_BCM_OUI_5, 0xffffff00 }, |
337 | { } | 337 | { } |
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 180c49479c42..a4b08198fb9f 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c | |||
@@ -43,6 +43,22 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev) | |||
43 | 43 | ||
44 | static int smsc_phy_config_init(struct phy_device *phydev) | 44 | static int smsc_phy_config_init(struct phy_device *phydev) |
45 | { | 45 | { |
46 | int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); | ||
47 | |||
48 | if (rc < 0) | ||
49 | return rc; | ||
50 | |||
51 | /* Enable energy detect mode for this SMSC Transceivers */ | ||
52 | rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, | ||
53 | rc | MII_LAN83C185_EDPWRDOWN); | ||
54 | if (rc < 0) | ||
55 | return rc; | ||
56 | |||
57 | return smsc_phy_ack_interrupt(phydev); | ||
58 | } | ||
59 | |||
60 | static int smsc_phy_reset(struct phy_device *phydev) | ||
61 | { | ||
46 | int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES); | 62 | int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES); |
47 | if (rc < 0) | 63 | if (rc < 0) |
48 | return rc; | 64 | return rc; |
@@ -66,18 +82,7 @@ static int smsc_phy_config_init(struct phy_device *phydev) | |||
66 | rc = phy_read(phydev, MII_BMCR); | 82 | rc = phy_read(phydev, MII_BMCR); |
67 | } while (rc & BMCR_RESET); | 83 | } while (rc & BMCR_RESET); |
68 | } | 84 | } |
69 | 85 | return 0; | |
70 | rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); | ||
71 | if (rc < 0) | ||
72 | return rc; | ||
73 | |||
74 | /* Enable energy detect mode for this SMSC Transceivers */ | ||
75 | rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, | ||
76 | rc | MII_LAN83C185_EDPWRDOWN); | ||
77 | if (rc < 0) | ||
78 | return rc; | ||
79 | |||
80 | return smsc_phy_ack_interrupt (phydev); | ||
81 | } | 86 | } |
82 | 87 | ||
83 | static int lan911x_config_init(struct phy_device *phydev) | 88 | static int lan911x_config_init(struct phy_device *phydev) |
@@ -142,6 +147,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
142 | .config_aneg = genphy_config_aneg, | 147 | .config_aneg = genphy_config_aneg, |
143 | .read_status = genphy_read_status, | 148 | .read_status = genphy_read_status, |
144 | .config_init = smsc_phy_config_init, | 149 | .config_init = smsc_phy_config_init, |
150 | .soft_reset = smsc_phy_reset, | ||
145 | 151 | ||
146 | /* IRQ related */ | 152 | /* IRQ related */ |
147 | .ack_interrupt = smsc_phy_ack_interrupt, | 153 | .ack_interrupt = smsc_phy_ack_interrupt, |
@@ -164,6 +170,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
164 | .config_aneg = genphy_config_aneg, | 170 | .config_aneg = genphy_config_aneg, |
165 | .read_status = genphy_read_status, | 171 | .read_status = genphy_read_status, |
166 | .config_init = smsc_phy_config_init, | 172 | .config_init = smsc_phy_config_init, |
173 | .soft_reset = smsc_phy_reset, | ||
167 | 174 | ||
168 | /* IRQ related */ | 175 | /* IRQ related */ |
169 | .ack_interrupt = smsc_phy_ack_interrupt, | 176 | .ack_interrupt = smsc_phy_ack_interrupt, |
@@ -186,6 +193,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
186 | .config_aneg = genphy_config_aneg, | 193 | .config_aneg = genphy_config_aneg, |
187 | .read_status = genphy_read_status, | 194 | .read_status = genphy_read_status, |
188 | .config_init = smsc_phy_config_init, | 195 | .config_init = smsc_phy_config_init, |
196 | .soft_reset = smsc_phy_reset, | ||
189 | 197 | ||
190 | /* IRQ related */ | 198 | /* IRQ related */ |
191 | .ack_interrupt = smsc_phy_ack_interrupt, | 199 | .ack_interrupt = smsc_phy_ack_interrupt, |
@@ -230,6 +238,7 @@ static struct phy_driver smsc_phy_driver[] = { | |||
230 | .config_aneg = genphy_config_aneg, | 238 | .config_aneg = genphy_config_aneg, |
231 | .read_status = lan87xx_read_status, | 239 | .read_status = lan87xx_read_status, |
232 | .config_init = smsc_phy_config_init, | 240 | .config_init = smsc_phy_config_init, |
241 | .soft_reset = smsc_phy_reset, | ||
233 | 242 | ||
234 | /* IRQ related */ | 243 | /* IRQ related */ |
235 | .ack_interrupt = smsc_phy_ack_interrupt, | 244 | .ack_interrupt = smsc_phy_ack_interrupt, |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 1fb7b37d1402..beb377b2d4b7 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1327,7 +1327,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb) | |||
1327 | } else if (vxlan->flags & VXLAN_F_L3MISS) { | 1327 | } else if (vxlan->flags & VXLAN_F_L3MISS) { |
1328 | union vxlan_addr ipa = { | 1328 | union vxlan_addr ipa = { |
1329 | .sin.sin_addr.s_addr = tip, | 1329 | .sin.sin_addr.s_addr = tip, |
1330 | .sa.sa_family = AF_INET, | 1330 | .sin.sin_family = AF_INET, |
1331 | }; | 1331 | }; |
1332 | 1332 | ||
1333 | vxlan_ip_miss(dev, &ipa); | 1333 | vxlan_ip_miss(dev, &ipa); |
@@ -1488,7 +1488,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) | |||
1488 | } else if (vxlan->flags & VXLAN_F_L3MISS) { | 1488 | } else if (vxlan->flags & VXLAN_F_L3MISS) { |
1489 | union vxlan_addr ipa = { | 1489 | union vxlan_addr ipa = { |
1490 | .sin6.sin6_addr = msg->target, | 1490 | .sin6.sin6_addr = msg->target, |
1491 | .sa.sa_family = AF_INET6, | 1491 | .sin6.sin6_family = AF_INET6, |
1492 | }; | 1492 | }; |
1493 | 1493 | ||
1494 | vxlan_ip_miss(dev, &ipa); | 1494 | vxlan_ip_miss(dev, &ipa); |
@@ -1521,7 +1521,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) | |||
1521 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { | 1521 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { |
1522 | union vxlan_addr ipa = { | 1522 | union vxlan_addr ipa = { |
1523 | .sin.sin_addr.s_addr = pip->daddr, | 1523 | .sin.sin_addr.s_addr = pip->daddr, |
1524 | .sa.sa_family = AF_INET, | 1524 | .sin.sin_family = AF_INET, |
1525 | }; | 1525 | }; |
1526 | 1526 | ||
1527 | vxlan_ip_miss(dev, &ipa); | 1527 | vxlan_ip_miss(dev, &ipa); |
@@ -1542,7 +1542,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) | |||
1542 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { | 1542 | if (!n && (vxlan->flags & VXLAN_F_L3MISS)) { |
1543 | union vxlan_addr ipa = { | 1543 | union vxlan_addr ipa = { |
1544 | .sin6.sin6_addr = pip6->daddr, | 1544 | .sin6.sin6_addr = pip6->daddr, |
1545 | .sa.sa_family = AF_INET6, | 1545 | .sin6.sin6_family = AF_INET6, |
1546 | }; | 1546 | }; |
1547 | 1547 | ||
1548 | vxlan_ip_miss(dev, &ipa); | 1548 | vxlan_ip_miss(dev, &ipa); |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index f46a24ffa3fe..79cb8313c7d8 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -453,7 +453,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, | |||
453 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); | 453 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); |
454 | size = dt_mem_next_cell(dt_root_size_cells, &prop); | 454 | size = dt_mem_next_cell(dt_root_size_cells, &prop); |
455 | 455 | ||
456 | if (base && size && | 456 | if (size && |
457 | early_init_dt_reserve_memory_arch(base, size, nomap) == 0) | 457 | early_init_dt_reserve_memory_arch(base, size, nomap) == 0) |
458 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", | 458 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", |
459 | uname, &base, (unsigned long)size / SZ_1M); | 459 | uname, &base, (unsigned long)size / SZ_1M); |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 3e06a699352d..1471e0a223a5 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -301,16 +301,17 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar | |||
301 | /* Get the reg property (if any) */ | 301 | /* Get the reg property (if any) */ |
302 | addr = of_get_property(device, "reg", NULL); | 302 | addr = of_get_property(device, "reg", NULL); |
303 | 303 | ||
304 | /* Try the new-style interrupts-extended first */ | ||
305 | res = of_parse_phandle_with_args(device, "interrupts-extended", | ||
306 | "#interrupt-cells", index, out_irq); | ||
307 | if (!res) | ||
308 | return of_irq_parse_raw(addr, out_irq); | ||
309 | |||
304 | /* Get the interrupts property */ | 310 | /* Get the interrupts property */ |
305 | intspec = of_get_property(device, "interrupts", &intlen); | 311 | intspec = of_get_property(device, "interrupts", &intlen); |
306 | if (intspec == NULL) { | 312 | if (intspec == NULL) |
307 | /* Try the new-style interrupts-extended */ | 313 | return -EINVAL; |
308 | res = of_parse_phandle_with_args(device, "interrupts-extended", | 314 | |
309 | "#interrupt-cells", index, out_irq); | ||
310 | if (res) | ||
311 | return -EINVAL; | ||
312 | return of_irq_parse_raw(addr, out_irq); | ||
313 | } | ||
314 | intlen /= sizeof(*intspec); | 315 | intlen /= sizeof(*intspec); |
315 | 316 | ||
316 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); | 317 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index d41002667833..a737cb5974de 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -27,6 +27,7 @@ static struct selftest_results { | |||
27 | #define NO_OF_NODES 2 | 27 | #define NO_OF_NODES 2 |
28 | static struct device_node *nodes[NO_OF_NODES]; | 28 | static struct device_node *nodes[NO_OF_NODES]; |
29 | static int last_node_index; | 29 | static int last_node_index; |
30 | static bool selftest_live_tree; | ||
30 | 31 | ||
31 | #define selftest(result, fmt, ...) { \ | 32 | #define selftest(result, fmt, ...) { \ |
32 | if (!(result)) { \ | 33 | if (!(result)) { \ |
@@ -630,13 +631,6 @@ static int attach_node_and_children(struct device_node *np) | |||
630 | { | 631 | { |
631 | struct device_node *next, *root = np, *dup; | 632 | struct device_node *next, *root = np, *dup; |
632 | 633 | ||
633 | if (!np) { | ||
634 | pr_warn("%s: No tree to attach; not running tests\n", | ||
635 | __func__); | ||
636 | return -ENODATA; | ||
637 | } | ||
638 | |||
639 | |||
640 | /* skip root node */ | 634 | /* skip root node */ |
641 | np = np->child; | 635 | np = np->child; |
642 | /* storing a copy in temporary node */ | 636 | /* storing a copy in temporary node */ |
@@ -672,12 +666,12 @@ static int attach_node_and_children(struct device_node *np) | |||
672 | static int __init selftest_data_add(void) | 666 | static int __init selftest_data_add(void) |
673 | { | 667 | { |
674 | void *selftest_data; | 668 | void *selftest_data; |
675 | struct device_node *selftest_data_node; | 669 | struct device_node *selftest_data_node, *np; |
676 | extern uint8_t __dtb_testcases_begin[]; | 670 | extern uint8_t __dtb_testcases_begin[]; |
677 | extern uint8_t __dtb_testcases_end[]; | 671 | extern uint8_t __dtb_testcases_end[]; |
678 | const int size = __dtb_testcases_end - __dtb_testcases_begin; | 672 | const int size = __dtb_testcases_end - __dtb_testcases_begin; |
679 | 673 | ||
680 | if (!size || !of_allnodes) { | 674 | if (!size) { |
681 | pr_warn("%s: No testcase data to attach; not running tests\n", | 675 | pr_warn("%s: No testcase data to attach; not running tests\n", |
682 | __func__); | 676 | __func__); |
683 | return -ENODATA; | 677 | return -ENODATA; |
@@ -692,6 +686,22 @@ static int __init selftest_data_add(void) | |||
692 | return -ENOMEM; | 686 | return -ENOMEM; |
693 | } | 687 | } |
694 | of_fdt_unflatten_tree(selftest_data, &selftest_data_node); | 688 | of_fdt_unflatten_tree(selftest_data, &selftest_data_node); |
689 | if (!selftest_data_node) { | ||
690 | pr_warn("%s: No tree to attach; not running tests\n", __func__); | ||
691 | return -ENODATA; | ||
692 | } | ||
693 | |||
694 | if (!of_allnodes) { | ||
695 | /* enabling flag for removing nodes */ | ||
696 | selftest_live_tree = true; | ||
697 | of_allnodes = selftest_data_node; | ||
698 | |||
699 | for_each_of_allnodes(np) | ||
700 | __of_attach_node_sysfs(np); | ||
701 | of_aliases = of_find_node_by_path("/aliases"); | ||
702 | of_chosen = of_find_node_by_path("/chosen"); | ||
703 | return 0; | ||
704 | } | ||
695 | 705 | ||
696 | /* attach the sub-tree to live tree */ | 706 | /* attach the sub-tree to live tree */ |
697 | return attach_node_and_children(selftest_data_node); | 707 | return attach_node_and_children(selftest_data_node); |
@@ -723,6 +733,18 @@ static void selftest_data_remove(void) | |||
723 | struct device_node *np; | 733 | struct device_node *np; |
724 | struct property *prop; | 734 | struct property *prop; |
725 | 735 | ||
736 | if (selftest_live_tree) { | ||
737 | of_node_put(of_aliases); | ||
738 | of_node_put(of_chosen); | ||
739 | of_aliases = NULL; | ||
740 | of_chosen = NULL; | ||
741 | for_each_child_of_node(of_allnodes, np) | ||
742 | detach_node_and_children(np); | ||
743 | __of_detach_node_sysfs(of_allnodes); | ||
744 | of_allnodes = NULL; | ||
745 | return; | ||
746 | } | ||
747 | |||
726 | while (last_node_index >= 0) { | 748 | while (last_node_index >= 0) { |
727 | if (nodes[last_node_index]) { | 749 | if (nodes[last_node_index]) { |
728 | np = of_find_node_by_path(nodes[last_node_index]->full_name); | 750 | np = of_find_node_by_path(nodes[last_node_index]->full_name); |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 2d8a4d05d78f..8922c376456a 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -1,9 +1,18 @@ | |||
1 | menu "PCI host controller drivers" | 1 | menu "PCI host controller drivers" |
2 | depends on PCI | 2 | depends on PCI |
3 | 3 | ||
4 | config PCI_DRA7XX | ||
5 | bool "TI DRA7xx PCIe controller" | ||
6 | select PCIE_DW | ||
7 | depends on OF && HAS_IOMEM && TI_PIPE3 | ||
8 | help | ||
9 | Enables support for the PCIe controller in the DRA7xx SoC. There | ||
10 | are two instances of PCIe controller in DRA7xx. This controller can | ||
11 | act both as EP and RC. This reuses the Designware core. | ||
12 | |||
4 | config PCI_MVEBU | 13 | config PCI_MVEBU |
5 | bool "Marvell EBU PCIe controller" | 14 | bool "Marvell EBU PCIe controller" |
6 | depends on ARCH_MVEBU || ARCH_DOVE || ARCH_KIRKWOOD | 15 | depends on ARCH_MVEBU || ARCH_DOVE |
7 | depends on OF | 16 | depends on OF |
8 | 17 | ||
9 | config PCIE_DW | 18 | config PCIE_DW |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 0daec7941aba..d0e88f114ff9 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | obj-$(CONFIG_PCIE_DW) += pcie-designware.o | 1 | obj-$(CONFIG_PCIE_DW) += pcie-designware.o |
2 | obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o | ||
2 | obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o | 3 | obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o |
3 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o | 4 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o |
4 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o | 5 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o |
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c new file mode 100644 index 000000000000..52b34fee07fd --- /dev/null +++ b/drivers/pci/host/pci-dra7xx.c | |||
@@ -0,0 +1,458 @@ | |||
1 | /* | ||
2 | * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs | ||
3 | * | ||
4 | * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * | ||
6 | * Authors: Kishon Vijay Abraham I <kishon@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/irqdomain.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/phy/phy.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/pm_runtime.h> | ||
24 | #include <linux/resource.h> | ||
25 | #include <linux/types.h> | ||
26 | |||
27 | #include "pcie-designware.h" | ||
28 | |||
29 | /* PCIe controller wrapper DRA7XX configuration registers */ | ||
30 | |||
31 | #define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN 0x0024 | ||
32 | #define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN 0x0028 | ||
33 | #define ERR_SYS BIT(0) | ||
34 | #define ERR_FATAL BIT(1) | ||
35 | #define ERR_NONFATAL BIT(2) | ||
36 | #define ERR_COR BIT(3) | ||
37 | #define ERR_AXI BIT(4) | ||
38 | #define ERR_ECRC BIT(5) | ||
39 | #define PME_TURN_OFF BIT(8) | ||
40 | #define PME_TO_ACK BIT(9) | ||
41 | #define PM_PME BIT(10) | ||
42 | #define LINK_REQ_RST BIT(11) | ||
43 | #define LINK_UP_EVT BIT(12) | ||
44 | #define CFG_BME_EVT BIT(13) | ||
45 | #define CFG_MSE_EVT BIT(14) | ||
46 | #define INTERRUPTS (ERR_SYS | ERR_FATAL | ERR_NONFATAL | ERR_COR | ERR_AXI | \ | ||
47 | ERR_ECRC | PME_TURN_OFF | PME_TO_ACK | PM_PME | \ | ||
48 | LINK_REQ_RST | LINK_UP_EVT | CFG_BME_EVT | CFG_MSE_EVT) | ||
49 | |||
50 | #define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI 0x0034 | ||
51 | #define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI 0x0038 | ||
52 | #define INTA BIT(0) | ||
53 | #define INTB BIT(1) | ||
54 | #define INTC BIT(2) | ||
55 | #define INTD BIT(3) | ||
56 | #define MSI BIT(4) | ||
57 | #define LEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD) | ||
58 | |||
59 | #define PCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104 | ||
60 | #define LTSSM_EN 0x1 | ||
61 | |||
62 | #define PCIECTRL_DRA7XX_CONF_PHY_CS 0x010C | ||
63 | #define LINK_UP BIT(16) | ||
64 | |||
65 | struct dra7xx_pcie { | ||
66 | void __iomem *base; | ||
67 | struct phy **phy; | ||
68 | int phy_count; | ||
69 | struct device *dev; | ||
70 | struct pcie_port pp; | ||
71 | }; | ||
72 | |||
73 | #define to_dra7xx_pcie(x) container_of((x), struct dra7xx_pcie, pp) | ||
74 | |||
75 | static inline u32 dra7xx_pcie_readl(struct dra7xx_pcie *pcie, u32 offset) | ||
76 | { | ||
77 | return readl(pcie->base + offset); | ||
78 | } | ||
79 | |||
80 | static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset, | ||
81 | u32 value) | ||
82 | { | ||
83 | writel(value, pcie->base + offset); | ||
84 | } | ||
85 | |||
86 | static int dra7xx_pcie_link_up(struct pcie_port *pp) | ||
87 | { | ||
88 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
89 | u32 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS); | ||
90 | |||
91 | return !!(reg & LINK_UP); | ||
92 | } | ||
93 | |||
94 | static int dra7xx_pcie_establish_link(struct pcie_port *pp) | ||
95 | { | ||
96 | u32 reg; | ||
97 | unsigned int retries = 1000; | ||
98 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
99 | |||
100 | if (dw_pcie_link_up(pp)) { | ||
101 | dev_err(pp->dev, "link is already up\n"); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); | ||
106 | reg |= LTSSM_EN; | ||
107 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); | ||
108 | |||
109 | while (retries--) { | ||
110 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS); | ||
111 | if (reg & LINK_UP) | ||
112 | break; | ||
113 | usleep_range(10, 20); | ||
114 | } | ||
115 | |||
116 | if (retries == 0) { | ||
117 | dev_err(pp->dev, "link is not up\n"); | ||
118 | return -ETIMEDOUT; | ||
119 | } | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp) | ||
125 | { | ||
126 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
127 | |||
128 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN, | ||
129 | ~INTERRUPTS); | ||
130 | dra7xx_pcie_writel(dra7xx, | ||
131 | PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN, INTERRUPTS); | ||
132 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, | ||
133 | ~LEG_EP_INTERRUPTS & ~MSI); | ||
134 | |||
135 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
136 | dra7xx_pcie_writel(dra7xx, | ||
137 | PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, MSI); | ||
138 | else | ||
139 | dra7xx_pcie_writel(dra7xx, | ||
140 | PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, | ||
141 | LEG_EP_INTERRUPTS); | ||
142 | } | ||
143 | |||
144 | static void dra7xx_pcie_host_init(struct pcie_port *pp) | ||
145 | { | ||
146 | dw_pcie_setup_rc(pp); | ||
147 | dra7xx_pcie_establish_link(pp); | ||
148 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
149 | dw_pcie_msi_init(pp); | ||
150 | dra7xx_pcie_enable_interrupts(pp); | ||
151 | } | ||
152 | |||
153 | static struct pcie_host_ops dra7xx_pcie_host_ops = { | ||
154 | .link_up = dra7xx_pcie_link_up, | ||
155 | .host_init = dra7xx_pcie_host_init, | ||
156 | }; | ||
157 | |||
158 | static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | ||
159 | irq_hw_number_t hwirq) | ||
160 | { | ||
161 | irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); | ||
162 | irq_set_chip_data(irq, domain->host_data); | ||
163 | set_irq_flags(irq, IRQF_VALID); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static const struct irq_domain_ops intx_domain_ops = { | ||
169 | .map = dra7xx_pcie_intx_map, | ||
170 | }; | ||
171 | |||
172 | static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) | ||
173 | { | ||
174 | struct device *dev = pp->dev; | ||
175 | struct device_node *node = dev->of_node; | ||
176 | struct device_node *pcie_intc_node = of_get_next_child(node, NULL); | ||
177 | |||
178 | if (!pcie_intc_node) { | ||
179 | dev_err(dev, "No PCIe Intc node found\n"); | ||
180 | return PTR_ERR(pcie_intc_node); | ||
181 | } | ||
182 | |||
183 | pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | ||
184 | &intx_domain_ops, pp); | ||
185 | if (!pp->irq_domain) { | ||
186 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | ||
187 | return PTR_ERR(pp->irq_domain); | ||
188 | } | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg) | ||
194 | { | ||
195 | struct pcie_port *pp = arg; | ||
196 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); | ||
197 | u32 reg; | ||
198 | |||
199 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI); | ||
200 | |||
201 | switch (reg) { | ||
202 | case MSI: | ||
203 | dw_handle_msi_irq(pp); | ||
204 | break; | ||
205 | case INTA: | ||
206 | case INTB: | ||
207 | case INTC: | ||
208 | case INTD: | ||
209 | generic_handle_irq(irq_find_mapping(pp->irq_domain, ffs(reg))); | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg); | ||
214 | |||
215 | return IRQ_HANDLED; | ||
216 | } | ||
217 | |||
218 | |||
219 | static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) | ||
220 | { | ||
221 | struct dra7xx_pcie *dra7xx = arg; | ||
222 | u32 reg; | ||
223 | |||
224 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN); | ||
225 | |||
226 | if (reg & ERR_SYS) | ||
227 | dev_dbg(dra7xx->dev, "System Error\n"); | ||
228 | |||
229 | if (reg & ERR_FATAL) | ||
230 | dev_dbg(dra7xx->dev, "Fatal Error\n"); | ||
231 | |||
232 | if (reg & ERR_NONFATAL) | ||
233 | dev_dbg(dra7xx->dev, "Non Fatal Error\n"); | ||
234 | |||
235 | if (reg & ERR_COR) | ||
236 | dev_dbg(dra7xx->dev, "Correctable Error\n"); | ||
237 | |||
238 | if (reg & ERR_AXI) | ||
239 | dev_dbg(dra7xx->dev, "AXI tag lookup fatal Error\n"); | ||
240 | |||
241 | if (reg & ERR_ECRC) | ||
242 | dev_dbg(dra7xx->dev, "ECRC Error\n"); | ||
243 | |||
244 | if (reg & PME_TURN_OFF) | ||
245 | dev_dbg(dra7xx->dev, | ||
246 | "Power Management Event Turn-Off message received\n"); | ||
247 | |||
248 | if (reg & PME_TO_ACK) | ||
249 | dev_dbg(dra7xx->dev, | ||
250 | "Power Management Turn-Off Ack message received\n"); | ||
251 | |||
252 | if (reg & PM_PME) | ||
253 | dev_dbg(dra7xx->dev, | ||
254 | "PM Power Management Event message received\n"); | ||
255 | |||
256 | if (reg & LINK_REQ_RST) | ||
257 | dev_dbg(dra7xx->dev, "Link Request Reset\n"); | ||
258 | |||
259 | if (reg & LINK_UP_EVT) | ||
260 | dev_dbg(dra7xx->dev, "Link-up state change\n"); | ||
261 | |||
262 | if (reg & CFG_BME_EVT) | ||
263 | dev_dbg(dra7xx->dev, "CFG 'Bus Master Enable' change\n"); | ||
264 | |||
265 | if (reg & CFG_MSE_EVT) | ||
266 | dev_dbg(dra7xx->dev, "CFG 'Memory Space Enable' change\n"); | ||
267 | |||
268 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN, reg); | ||
269 | |||
270 | return IRQ_HANDLED; | ||
271 | } | ||
272 | |||
273 | static int add_pcie_port(struct dra7xx_pcie *dra7xx, | ||
274 | struct platform_device *pdev) | ||
275 | { | ||
276 | int ret; | ||
277 | struct pcie_port *pp; | ||
278 | struct resource *res; | ||
279 | struct device *dev = &pdev->dev; | ||
280 | |||
281 | pp = &dra7xx->pp; | ||
282 | pp->dev = dev; | ||
283 | pp->ops = &dra7xx_pcie_host_ops; | ||
284 | |||
285 | pp->irq = platform_get_irq(pdev, 1); | ||
286 | if (pp->irq < 0) { | ||
287 | dev_err(dev, "missing IRQ resource\n"); | ||
288 | return -EINVAL; | ||
289 | } | ||
290 | |||
291 | ret = devm_request_irq(&pdev->dev, pp->irq, | ||
292 | dra7xx_pcie_msi_irq_handler, IRQF_SHARED, | ||
293 | "dra7-pcie-msi", pp); | ||
294 | if (ret) { | ||
295 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | if (!IS_ENABLED(CONFIG_PCI_MSI)) { | ||
300 | ret = dra7xx_pcie_init_irq_domain(pp); | ||
301 | if (ret < 0) | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics"); | ||
306 | pp->dbi_base = devm_ioremap(dev, res->start, resource_size(res)); | ||
307 | if (!pp->dbi_base) | ||
308 | return -ENOMEM; | ||
309 | |||
310 | ret = dw_pcie_host_init(pp); | ||
311 | if (ret) { | ||
312 | dev_err(dra7xx->dev, "failed to initialize host\n"); | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static int __init dra7xx_pcie_probe(struct platform_device *pdev) | ||
320 | { | ||
321 | u32 reg; | ||
322 | int ret; | ||
323 | int irq; | ||
324 | int i; | ||
325 | int phy_count; | ||
326 | struct phy **phy; | ||
327 | void __iomem *base; | ||
328 | struct resource *res; | ||
329 | struct dra7xx_pcie *dra7xx; | ||
330 | struct device *dev = &pdev->dev; | ||
331 | struct device_node *np = dev->of_node; | ||
332 | char name[10]; | ||
333 | |||
334 | dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); | ||
335 | if (!dra7xx) | ||
336 | return -ENOMEM; | ||
337 | |||
338 | irq = platform_get_irq(pdev, 0); | ||
339 | if (irq < 0) { | ||
340 | dev_err(dev, "missing IRQ resource\n"); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler, | ||
345 | IRQF_SHARED, "dra7xx-pcie-main", dra7xx); | ||
346 | if (ret) { | ||
347 | dev_err(dev, "failed to request irq\n"); | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); | ||
352 | base = devm_ioremap_nocache(dev, res->start, resource_size(res)); | ||
353 | if (!base) | ||
354 | return -ENOMEM; | ||
355 | |||
356 | phy_count = of_property_count_strings(np, "phy-names"); | ||
357 | if (phy_count < 0) { | ||
358 | dev_err(dev, "unable to find the strings\n"); | ||
359 | return phy_count; | ||
360 | } | ||
361 | |||
362 | phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); | ||
363 | if (!phy) | ||
364 | return -ENOMEM; | ||
365 | |||
366 | for (i = 0; i < phy_count; i++) { | ||
367 | snprintf(name, sizeof(name), "pcie-phy%d", i); | ||
368 | phy[i] = devm_phy_get(dev, name); | ||
369 | if (IS_ERR(phy[i])) | ||
370 | return PTR_ERR(phy[i]); | ||
371 | |||
372 | ret = phy_init(phy[i]); | ||
373 | if (ret < 0) | ||
374 | goto err_phy; | ||
375 | |||
376 | ret = phy_power_on(phy[i]); | ||
377 | if (ret < 0) { | ||
378 | phy_exit(phy[i]); | ||
379 | goto err_phy; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | dra7xx->base = base; | ||
384 | dra7xx->phy = phy; | ||
385 | dra7xx->dev = dev; | ||
386 | dra7xx->phy_count = phy_count; | ||
387 | |||
388 | pm_runtime_enable(dev); | ||
389 | ret = pm_runtime_get_sync(dev); | ||
390 | if (IS_ERR_VALUE(ret)) { | ||
391 | dev_err(dev, "pm_runtime_get_sync failed\n"); | ||
392 | goto err_phy; | ||
393 | } | ||
394 | |||
395 | reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); | ||
396 | reg &= ~LTSSM_EN; | ||
397 | dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); | ||
398 | |||
399 | platform_set_drvdata(pdev, dra7xx); | ||
400 | |||
401 | ret = add_pcie_port(dra7xx, pdev); | ||
402 | if (ret < 0) | ||
403 | goto err_add_port; | ||
404 | |||
405 | return 0; | ||
406 | |||
407 | err_add_port: | ||
408 | pm_runtime_put(dev); | ||
409 | pm_runtime_disable(dev); | ||
410 | |||
411 | err_phy: | ||
412 | while (--i >= 0) { | ||
413 | phy_power_off(phy[i]); | ||
414 | phy_exit(phy[i]); | ||
415 | } | ||
416 | |||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | static int __exit dra7xx_pcie_remove(struct platform_device *pdev) | ||
421 | { | ||
422 | struct dra7xx_pcie *dra7xx = platform_get_drvdata(pdev); | ||
423 | struct pcie_port *pp = &dra7xx->pp; | ||
424 | struct device *dev = &pdev->dev; | ||
425 | int count = dra7xx->phy_count; | ||
426 | |||
427 | if (pp->irq_domain) | ||
428 | irq_domain_remove(pp->irq_domain); | ||
429 | pm_runtime_put(dev); | ||
430 | pm_runtime_disable(dev); | ||
431 | while (count--) { | ||
432 | phy_power_off(dra7xx->phy[count]); | ||
433 | phy_exit(dra7xx->phy[count]); | ||
434 | } | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static const struct of_device_id of_dra7xx_pcie_match[] = { | ||
440 | { .compatible = "ti,dra7-pcie", }, | ||
441 | {}, | ||
442 | }; | ||
443 | MODULE_DEVICE_TABLE(of, of_dra7xx_pcie_match); | ||
444 | |||
445 | static struct platform_driver dra7xx_pcie_driver = { | ||
446 | .remove = __exit_p(dra7xx_pcie_remove), | ||
447 | .driver = { | ||
448 | .name = "dra7-pcie", | ||
449 | .owner = THIS_MODULE, | ||
450 | .of_match_table = of_dra7xx_pcie_match, | ||
451 | }, | ||
452 | }; | ||
453 | |||
454 | module_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe); | ||
455 | |||
456 | MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); | ||
457 | MODULE_DESCRIPTION("TI PCIe controller driver"); | ||
458 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index abd65784618d..0fb0fdb223d5 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/debugfs.h> | ||
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <linux/export.h> | 30 | #include <linux/export.h> |
30 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
@@ -276,6 +277,7 @@ struct tegra_pcie { | |||
276 | unsigned int num_supplies; | 277 | unsigned int num_supplies; |
277 | 278 | ||
278 | const struct tegra_pcie_soc_data *soc_data; | 279 | const struct tegra_pcie_soc_data *soc_data; |
280 | struct dentry *debugfs; | ||
279 | }; | 281 | }; |
280 | 282 | ||
281 | struct tegra_pcie_port { | 283 | struct tegra_pcie_port { |
@@ -1739,6 +1741,115 @@ static const struct of_device_id tegra_pcie_of_match[] = { | |||
1739 | }; | 1741 | }; |
1740 | MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); | 1742 | MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); |
1741 | 1743 | ||
1744 | static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) | ||
1745 | { | ||
1746 | struct tegra_pcie *pcie = s->private; | ||
1747 | |||
1748 | if (list_empty(&pcie->ports)) | ||
1749 | return NULL; | ||
1750 | |||
1751 | seq_printf(s, "Index Status\n"); | ||
1752 | |||
1753 | return seq_list_start(&pcie->ports, *pos); | ||
1754 | } | ||
1755 | |||
1756 | static void *tegra_pcie_ports_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
1757 | { | ||
1758 | struct tegra_pcie *pcie = s->private; | ||
1759 | |||
1760 | return seq_list_next(v, &pcie->ports, pos); | ||
1761 | } | ||
1762 | |||
1763 | static void tegra_pcie_ports_seq_stop(struct seq_file *s, void *v) | ||
1764 | { | ||
1765 | } | ||
1766 | |||
1767 | static int tegra_pcie_ports_seq_show(struct seq_file *s, void *v) | ||
1768 | { | ||
1769 | bool up = false, active = false; | ||
1770 | struct tegra_pcie_port *port; | ||
1771 | unsigned int value; | ||
1772 | |||
1773 | port = list_entry(v, struct tegra_pcie_port, list); | ||
1774 | |||
1775 | value = readl(port->base + RP_VEND_XP); | ||
1776 | |||
1777 | if (value & RP_VEND_XP_DL_UP) | ||
1778 | up = true; | ||
1779 | |||
1780 | value = readl(port->base + RP_LINK_CONTROL_STATUS); | ||
1781 | |||
1782 | if (value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE) | ||
1783 | active = true; | ||
1784 | |||
1785 | seq_printf(s, "%2u ", port->index); | ||
1786 | |||
1787 | if (up) | ||
1788 | seq_printf(s, "up"); | ||
1789 | |||
1790 | if (active) { | ||
1791 | if (up) | ||
1792 | seq_printf(s, ", "); | ||
1793 | |||
1794 | seq_printf(s, "active"); | ||
1795 | } | ||
1796 | |||
1797 | seq_printf(s, "\n"); | ||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | static const struct seq_operations tegra_pcie_ports_seq_ops = { | ||
1802 | .start = tegra_pcie_ports_seq_start, | ||
1803 | .next = tegra_pcie_ports_seq_next, | ||
1804 | .stop = tegra_pcie_ports_seq_stop, | ||
1805 | .show = tegra_pcie_ports_seq_show, | ||
1806 | }; | ||
1807 | |||
1808 | static int tegra_pcie_ports_open(struct inode *inode, struct file *file) | ||
1809 | { | ||
1810 | struct tegra_pcie *pcie = inode->i_private; | ||
1811 | struct seq_file *s; | ||
1812 | int err; | ||
1813 | |||
1814 | err = seq_open(file, &tegra_pcie_ports_seq_ops); | ||
1815 | if (err) | ||
1816 | return err; | ||
1817 | |||
1818 | s = file->private_data; | ||
1819 | s->private = pcie; | ||
1820 | |||
1821 | return 0; | ||
1822 | } | ||
1823 | |||
1824 | static const struct file_operations tegra_pcie_ports_ops = { | ||
1825 | .owner = THIS_MODULE, | ||
1826 | .open = tegra_pcie_ports_open, | ||
1827 | .read = seq_read, | ||
1828 | .llseek = seq_lseek, | ||
1829 | .release = seq_release, | ||
1830 | }; | ||
1831 | |||
1832 | static int tegra_pcie_debugfs_init(struct tegra_pcie *pcie) | ||
1833 | { | ||
1834 | struct dentry *file; | ||
1835 | |||
1836 | pcie->debugfs = debugfs_create_dir("pcie", NULL); | ||
1837 | if (!pcie->debugfs) | ||
1838 | return -ENOMEM; | ||
1839 | |||
1840 | file = debugfs_create_file("ports", S_IFREG | S_IRUGO, pcie->debugfs, | ||
1841 | pcie, &tegra_pcie_ports_ops); | ||
1842 | if (!file) | ||
1843 | goto remove; | ||
1844 | |||
1845 | return 0; | ||
1846 | |||
1847 | remove: | ||
1848 | debugfs_remove_recursive(pcie->debugfs); | ||
1849 | pcie->debugfs = NULL; | ||
1850 | return -ENOMEM; | ||
1851 | } | ||
1852 | |||
1742 | static int tegra_pcie_probe(struct platform_device *pdev) | 1853 | static int tegra_pcie_probe(struct platform_device *pdev) |
1743 | { | 1854 | { |
1744 | const struct of_device_id *match; | 1855 | const struct of_device_id *match; |
@@ -1793,6 +1904,13 @@ static int tegra_pcie_probe(struct platform_device *pdev) | |||
1793 | goto disable_msi; | 1904 | goto disable_msi; |
1794 | } | 1905 | } |
1795 | 1906 | ||
1907 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { | ||
1908 | err = tegra_pcie_debugfs_init(pcie); | ||
1909 | if (err < 0) | ||
1910 | dev_err(&pdev->dev, "failed to setup debugfs: %d\n", | ||
1911 | err); | ||
1912 | } | ||
1913 | |||
1796 | platform_set_drvdata(pdev, pcie); | 1914 | platform_set_drvdata(pdev, pcie); |
1797 | return 0; | 1915 | return 0; |
1798 | 1916 | ||
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 1eaf4df3618a..52bd3a143563 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/pci_regs.h> | 22 | #include <linux/pci_regs.h> |
23 | #include <linux/platform_device.h> | ||
23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
24 | 25 | ||
25 | #include "pcie-designware.h" | 26 | #include "pcie-designware.h" |
@@ -217,27 +218,47 @@ static int find_valid_pos0(struct pcie_port *pp, int msgvec, int pos, int *pos0) | |||
217 | return 0; | 218 | return 0; |
218 | } | 219 | } |
219 | 220 | ||
221 | static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | ||
222 | { | ||
223 | unsigned int res, bit, val; | ||
224 | |||
225 | res = (irq / 32) * 12; | ||
226 | bit = irq % 32; | ||
227 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | ||
228 | val &= ~(1 << bit); | ||
229 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
230 | } | ||
231 | |||
220 | static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, | 232 | static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, |
221 | unsigned int nvec, unsigned int pos) | 233 | unsigned int nvec, unsigned int pos) |
222 | { | 234 | { |
223 | unsigned int i, res, bit, val; | 235 | unsigned int i; |
224 | 236 | ||
225 | for (i = 0; i < nvec; i++) { | 237 | for (i = 0; i < nvec; i++) { |
226 | irq_set_msi_desc_off(irq_base, i, NULL); | 238 | irq_set_msi_desc_off(irq_base, i, NULL); |
227 | clear_bit(pos + i, pp->msi_irq_in_use); | 239 | clear_bit(pos + i, pp->msi_irq_in_use); |
228 | /* Disable corresponding interrupt on MSI controller */ | 240 | /* Disable corresponding interrupt on MSI controller */ |
229 | res = ((pos + i) / 32) * 12; | 241 | if (pp->ops->msi_clear_irq) |
230 | bit = (pos + i) % 32; | 242 | pp->ops->msi_clear_irq(pp, pos + i); |
231 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | 243 | else |
232 | val &= ~(1 << bit); | 244 | dw_pcie_msi_clear_irq(pp, pos + i); |
233 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
234 | } | 245 | } |
235 | } | 246 | } |
236 | 247 | ||
248 | static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | ||
249 | { | ||
250 | unsigned int res, bit, val; | ||
251 | |||
252 | res = (irq / 32) * 12; | ||
253 | bit = irq % 32; | ||
254 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | ||
255 | val |= 1 << bit; | ||
256 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
257 | } | ||
258 | |||
237 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | 259 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) |
238 | { | 260 | { |
239 | int res, bit, irq, pos0, pos1, i; | 261 | int irq, pos0, pos1, i; |
240 | u32 val; | ||
241 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); | 262 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); |
242 | 263 | ||
243 | if (!pp) { | 264 | if (!pp) { |
@@ -281,11 +302,10 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | |||
281 | } | 302 | } |
282 | set_bit(pos0 + i, pp->msi_irq_in_use); | 303 | set_bit(pos0 + i, pp->msi_irq_in_use); |
283 | /*Enable corresponding interrupt in MSI interrupt controller */ | 304 | /*Enable corresponding interrupt in MSI interrupt controller */ |
284 | res = ((pos0 + i) / 32) * 12; | 305 | if (pp->ops->msi_set_irq) |
285 | bit = (pos0 + i) % 32; | 306 | pp->ops->msi_set_irq(pp, pos0 + i); |
286 | dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); | 307 | else |
287 | val |= 1 << bit; | 308 | dw_pcie_msi_set_irq(pp, pos0 + i); |
288 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); | ||
289 | } | 309 | } |
290 | 310 | ||
291 | *pos = pos0; | 311 | *pos = pos0; |
@@ -353,7 +373,10 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, | |||
353 | */ | 373 | */ |
354 | desc->msi_attrib.multiple = msgvec; | 374 | desc->msi_attrib.multiple = msgvec; |
355 | 375 | ||
356 | msg.address_lo = virt_to_phys((void *)pp->msi_data); | 376 | if (pp->ops->get_msi_data) |
377 | msg.address_lo = pp->ops->get_msi_data(pp); | ||
378 | else | ||
379 | msg.address_lo = virt_to_phys((void *)pp->msi_data); | ||
357 | msg.address_hi = 0x0; | 380 | msg.address_hi = 0x0; |
358 | msg.data = pos; | 381 | msg.data = pos; |
359 | write_msi_msg(irq, &msg); | 382 | write_msi_msg(irq, &msg); |
@@ -396,10 +419,35 @@ static const struct irq_domain_ops msi_domain_ops = { | |||
396 | int __init dw_pcie_host_init(struct pcie_port *pp) | 419 | int __init dw_pcie_host_init(struct pcie_port *pp) |
397 | { | 420 | { |
398 | struct device_node *np = pp->dev->of_node; | 421 | struct device_node *np = pp->dev->of_node; |
422 | struct platform_device *pdev = to_platform_device(pp->dev); | ||
399 | struct of_pci_range range; | 423 | struct of_pci_range range; |
400 | struct of_pci_range_parser parser; | 424 | struct of_pci_range_parser parser; |
401 | u32 val; | 425 | struct resource *cfg_res; |
402 | int i; | 426 | u32 val, na, ns; |
427 | const __be32 *addrp; | ||
428 | int i, index; | ||
429 | |||
430 | /* Find the address cell size and the number of cells in order to get | ||
431 | * the untranslated address. | ||
432 | */ | ||
433 | of_property_read_u32(np, "#address-cells", &na); | ||
434 | ns = of_n_size_cells(np); | ||
435 | |||
436 | cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); | ||
437 | if (cfg_res) { | ||
438 | pp->config.cfg0_size = resource_size(cfg_res)/2; | ||
439 | pp->config.cfg1_size = resource_size(cfg_res)/2; | ||
440 | pp->cfg0_base = cfg_res->start; | ||
441 | pp->cfg1_base = cfg_res->start + pp->config.cfg0_size; | ||
442 | |||
443 | /* Find the untranslated configuration space address */ | ||
444 | index = of_property_match_string(np, "reg-names", "config"); | ||
445 | addrp = of_get_address(np, index, false, false); | ||
446 | pp->cfg0_mod_base = of_read_number(addrp, ns); | ||
447 | pp->cfg1_mod_base = pp->cfg0_mod_base + pp->config.cfg0_size; | ||
448 | } else { | ||
449 | dev_err(pp->dev, "missing *config* reg space\n"); | ||
450 | } | ||
403 | 451 | ||
404 | if (of_pci_range_parser_init(&parser, np)) { | 452 | if (of_pci_range_parser_init(&parser, np)) { |
405 | dev_err(pp->dev, "missing ranges property\n"); | 453 | dev_err(pp->dev, "missing ranges property\n"); |
@@ -422,17 +470,33 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
422 | pp->config.io_size = resource_size(&pp->io); | 470 | pp->config.io_size = resource_size(&pp->io); |
423 | pp->config.io_bus_addr = range.pci_addr; | 471 | pp->config.io_bus_addr = range.pci_addr; |
424 | pp->io_base = range.cpu_addr; | 472 | pp->io_base = range.cpu_addr; |
473 | |||
474 | /* Find the untranslated IO space address */ | ||
475 | pp->io_mod_base = of_read_number(parser.range - | ||
476 | parser.np + na, ns); | ||
425 | } | 477 | } |
426 | if (restype == IORESOURCE_MEM) { | 478 | if (restype == IORESOURCE_MEM) { |
427 | of_pci_range_to_resource(&range, np, &pp->mem); | 479 | of_pci_range_to_resource(&range, np, &pp->mem); |
428 | pp->mem.name = "MEM"; | 480 | pp->mem.name = "MEM"; |
429 | pp->config.mem_size = resource_size(&pp->mem); | 481 | pp->config.mem_size = resource_size(&pp->mem); |
430 | pp->config.mem_bus_addr = range.pci_addr; | 482 | pp->config.mem_bus_addr = range.pci_addr; |
483 | |||
484 | /* Find the untranslated MEM space address */ | ||
485 | pp->mem_mod_base = of_read_number(parser.range - | ||
486 | parser.np + na, ns); | ||
431 | } | 487 | } |
432 | if (restype == 0) { | 488 | if (restype == 0) { |
433 | of_pci_range_to_resource(&range, np, &pp->cfg); | 489 | of_pci_range_to_resource(&range, np, &pp->cfg); |
434 | pp->config.cfg0_size = resource_size(&pp->cfg)/2; | 490 | pp->config.cfg0_size = resource_size(&pp->cfg)/2; |
435 | pp->config.cfg1_size = resource_size(&pp->cfg)/2; | 491 | pp->config.cfg1_size = resource_size(&pp->cfg)/2; |
492 | pp->cfg0_base = pp->cfg.start; | ||
493 | pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; | ||
494 | |||
495 | /* Find the untranslated configuration space address */ | ||
496 | pp->cfg0_mod_base = of_read_number(parser.range - | ||
497 | parser.np + na, ns); | ||
498 | pp->cfg1_mod_base = pp->cfg0_mod_base + | ||
499 | pp->config.cfg0_size; | ||
436 | } | 500 | } |
437 | } | 501 | } |
438 | 502 | ||
@@ -445,8 +509,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
445 | } | 509 | } |
446 | } | 510 | } |
447 | 511 | ||
448 | pp->cfg0_base = pp->cfg.start; | ||
449 | pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; | ||
450 | pp->mem_base = pp->mem.start; | 512 | pp->mem_base = pp->mem.start; |
451 | 513 | ||
452 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, | 514 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, |
@@ -509,9 +571,9 @@ static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev) | |||
509 | /* Program viewport 0 : OUTBOUND : CFG0 */ | 571 | /* Program viewport 0 : OUTBOUND : CFG0 */ |
510 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, | 572 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, |
511 | PCIE_ATU_VIEWPORT); | 573 | PCIE_ATU_VIEWPORT); |
512 | dw_pcie_writel_rc(pp, pp->cfg0_base, PCIE_ATU_LOWER_BASE); | 574 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base, PCIE_ATU_LOWER_BASE); |
513 | dw_pcie_writel_rc(pp, (pp->cfg0_base >> 32), PCIE_ATU_UPPER_BASE); | 575 | dw_pcie_writel_rc(pp, (pp->cfg0_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
514 | dw_pcie_writel_rc(pp, pp->cfg0_base + pp->config.cfg0_size - 1, | 576 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->config.cfg0_size - 1, |
515 | PCIE_ATU_LIMIT); | 577 | PCIE_ATU_LIMIT); |
516 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); | 578 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); |
517 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); | 579 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); |
@@ -525,9 +587,9 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) | |||
525 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, | 587 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, |
526 | PCIE_ATU_VIEWPORT); | 588 | PCIE_ATU_VIEWPORT); |
527 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); | 589 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); |
528 | dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE); | 590 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base, PCIE_ATU_LOWER_BASE); |
529 | dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE); | 591 | dw_pcie_writel_rc(pp, (pp->cfg1_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
530 | dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1, | 592 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->config.cfg1_size - 1, |
531 | PCIE_ATU_LIMIT); | 593 | PCIE_ATU_LIMIT); |
532 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); | 594 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); |
533 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); | 595 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); |
@@ -540,9 +602,9 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) | |||
540 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, | 602 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, |
541 | PCIE_ATU_VIEWPORT); | 603 | PCIE_ATU_VIEWPORT); |
542 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); | 604 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); |
543 | dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE); | 605 | dw_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE); |
544 | dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE); | 606 | dw_pcie_writel_rc(pp, (pp->mem_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
545 | dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1, | 607 | dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->config.mem_size - 1, |
546 | PCIE_ATU_LIMIT); | 608 | PCIE_ATU_LIMIT); |
547 | dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); | 609 | dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); |
548 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), | 610 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), |
@@ -556,9 +618,9 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) | |||
556 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, | 618 | dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, |
557 | PCIE_ATU_VIEWPORT); | 619 | PCIE_ATU_VIEWPORT); |
558 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); | 620 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); |
559 | dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE); | 621 | dw_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE); |
560 | dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE); | 622 | dw_pcie_writel_rc(pp, (pp->io_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
561 | dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1, | 623 | dw_pcie_writel_rc(pp, pp->io_mod_base + pp->config.io_size - 1, |
562 | PCIE_ATU_LIMIT); | 624 | PCIE_ATU_LIMIT); |
563 | dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); | 625 | dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); |
564 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), | 626 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), |
@@ -656,7 +718,11 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, | |||
656 | } | 718 | } |
657 | 719 | ||
658 | if (bus->number != pp->root_bus_nr) | 720 | if (bus->number != pp->root_bus_nr) |
659 | ret = dw_pcie_rd_other_conf(pp, bus, devfn, | 721 | if (pp->ops->rd_other_conf) |
722 | ret = pp->ops->rd_other_conf(pp, bus, devfn, | ||
723 | where, size, val); | ||
724 | else | ||
725 | ret = dw_pcie_rd_other_conf(pp, bus, devfn, | ||
660 | where, size, val); | 726 | where, size, val); |
661 | else | 727 | else |
662 | ret = dw_pcie_rd_own_conf(pp, where, size, val); | 728 | ret = dw_pcie_rd_own_conf(pp, where, size, val); |
@@ -679,7 +745,11 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, | |||
679 | return PCIBIOS_DEVICE_NOT_FOUND; | 745 | return PCIBIOS_DEVICE_NOT_FOUND; |
680 | 746 | ||
681 | if (bus->number != pp->root_bus_nr) | 747 | if (bus->number != pp->root_bus_nr) |
682 | ret = dw_pcie_wr_other_conf(pp, bus, devfn, | 748 | if (pp->ops->wr_other_conf) |
749 | ret = pp->ops->wr_other_conf(pp, bus, devfn, | ||
750 | where, size, val); | ||
751 | else | ||
752 | ret = dw_pcie_wr_other_conf(pp, bus, devfn, | ||
683 | where, size, val); | 753 | where, size, val); |
684 | else | 754 | else |
685 | ret = dw_pcie_wr_own_conf(pp, where, size, val); | 755 | ret = dw_pcie_wr_own_conf(pp, where, size, val); |
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index 77f592faa7bf..daf81f922cda 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h | |||
@@ -36,11 +36,15 @@ struct pcie_port { | |||
36 | u8 root_bus_nr; | 36 | u8 root_bus_nr; |
37 | void __iomem *dbi_base; | 37 | void __iomem *dbi_base; |
38 | u64 cfg0_base; | 38 | u64 cfg0_base; |
39 | u64 cfg0_mod_base; | ||
39 | void __iomem *va_cfg0_base; | 40 | void __iomem *va_cfg0_base; |
40 | u64 cfg1_base; | 41 | u64 cfg1_base; |
42 | u64 cfg1_mod_base; | ||
41 | void __iomem *va_cfg1_base; | 43 | void __iomem *va_cfg1_base; |
42 | u64 io_base; | 44 | u64 io_base; |
45 | u64 io_mod_base; | ||
43 | u64 mem_base; | 46 | u64 mem_base; |
47 | u64 mem_mod_base; | ||
44 | struct resource cfg; | 48 | struct resource cfg; |
45 | struct resource io; | 49 | struct resource io; |
46 | struct resource mem; | 50 | struct resource mem; |
@@ -61,8 +65,15 @@ struct pcie_host_ops { | |||
61 | u32 val, void __iomem *dbi_base); | 65 | u32 val, void __iomem *dbi_base); |
62 | int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val); | 66 | int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val); |
63 | int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val); | 67 | int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val); |
68 | int (*rd_other_conf)(struct pcie_port *pp, struct pci_bus *bus, | ||
69 | unsigned int devfn, int where, int size, u32 *val); | ||
70 | int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus, | ||
71 | unsigned int devfn, int where, int size, u32 val); | ||
64 | int (*link_up)(struct pcie_port *pp); | 72 | int (*link_up)(struct pcie_port *pp); |
65 | void (*host_init)(struct pcie_port *pp); | 73 | void (*host_init)(struct pcie_port *pp); |
74 | void (*msi_set_irq)(struct pcie_port *pp, int irq); | ||
75 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); | ||
76 | u32 (*get_msi_data)(struct pcie_port *pp); | ||
66 | }; | 77 | }; |
67 | 78 | ||
68 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); | 79 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 172f26ce59ac..3bbcbf12c1fb 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -652,6 +652,25 @@ config TOSHIBA_BT_RFKILL | |||
652 | If you have a modern Toshiba laptop with a Bluetooth and an | 652 | If you have a modern Toshiba laptop with a Bluetooth and an |
653 | RFKill switch (such as the Portege R500), say Y. | 653 | RFKill switch (such as the Portege R500), say Y. |
654 | 654 | ||
655 | config TOSHIBA_HAPS | ||
656 | tristate "Toshiba HDD Active Protection Sensor" | ||
657 | depends on ACPI | ||
658 | ---help--- | ||
659 | This driver adds support for the built-in accelerometer | ||
660 | found on recent Toshiba laptops equiped with HID TOS620A | ||
661 | device. | ||
662 | |||
663 | This driver receives ACPI notify events 0x80 when the sensor | ||
664 | detects a sudden move or a harsh vibration, as well as an | ||
665 | ACPI notify event 0x81 whenever the movement or vibration has | ||
666 | been stabilized. | ||
667 | |||
668 | Also provides sysfs entries to get/set the desired protection | ||
669 | level and reseting the HDD protection interface. | ||
670 | |||
671 | If you have a recent Toshiba laptop with a built-in accelerometer | ||
672 | device, say Y. | ||
673 | |||
655 | config ACPI_CMPC | 674 | config ACPI_CMPC |
656 | tristate "CMPC Laptop Extras" | 675 | tristate "CMPC Laptop Extras" |
657 | depends on X86 && ACPI | 676 | depends on X86 && ACPI |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index c4ca428fd3db..f82232b1fc4d 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -38,6 +38,7 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o | |||
38 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o | 38 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o |
39 | 39 | ||
40 | obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o | 40 | obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o |
41 | obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o | ||
41 | obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o | 42 | obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o |
42 | obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o | 43 | obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o |
43 | obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o | 44 | obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index bbf78b2d6d93..96a0b75c52c9 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -96,7 +96,7 @@ enum acer_wmi_event_ids { | |||
96 | WMID_ACCEL_EVENT = 0x5, | 96 | WMID_ACCEL_EVENT = 0x5, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static const struct key_entry acer_wmi_keymap[] = { | 99 | static const struct key_entry acer_wmi_keymap[] __initconst = { |
100 | {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ | 100 | {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ |
101 | {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ | 101 | {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ |
102 | {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ | 102 | {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ |
@@ -294,7 +294,7 @@ struct quirk_entry { | |||
294 | 294 | ||
295 | static struct quirk_entry *quirks; | 295 | static struct quirk_entry *quirks; |
296 | 296 | ||
297 | static void set_quirks(void) | 297 | static void __init set_quirks(void) |
298 | { | 298 | { |
299 | if (!interface) | 299 | if (!interface) |
300 | return; | 300 | return; |
@@ -306,7 +306,7 @@ static void set_quirks(void) | |||
306 | interface->capability |= ACER_CAP_BRIGHTNESS; | 306 | interface->capability |= ACER_CAP_BRIGHTNESS; |
307 | } | 307 | } |
308 | 308 | ||
309 | static int dmi_matched(const struct dmi_system_id *dmi) | 309 | static int __init dmi_matched(const struct dmi_system_id *dmi) |
310 | { | 310 | { |
311 | quirks = dmi->driver_data; | 311 | quirks = dmi->driver_data; |
312 | return 1; | 312 | return 1; |
@@ -337,7 +337,7 @@ static struct quirk_entry quirk_lenovo_ideapad_s205 = { | |||
337 | }; | 337 | }; |
338 | 338 | ||
339 | /* The Aspire One has a dummy ACPI-WMI interface - disable it */ | 339 | /* The Aspire One has a dummy ACPI-WMI interface - disable it */ |
340 | static struct dmi_system_id acer_blacklist[] = { | 340 | static const struct dmi_system_id acer_blacklist[] __initconst = { |
341 | { | 341 | { |
342 | .ident = "Acer Aspire One (SSD)", | 342 | .ident = "Acer Aspire One (SSD)", |
343 | .matches = { | 343 | .matches = { |
@@ -355,7 +355,7 @@ static struct dmi_system_id acer_blacklist[] = { | |||
355 | {} | 355 | {} |
356 | }; | 356 | }; |
357 | 357 | ||
358 | static struct dmi_system_id acer_quirks[] = { | 358 | static const struct dmi_system_id acer_quirks[] __initconst = { |
359 | { | 359 | { |
360 | .callback = dmi_matched, | 360 | .callback = dmi_matched, |
361 | .ident = "Acer Aspire 1360", | 361 | .ident = "Acer Aspire 1360", |
@@ -530,14 +530,15 @@ static struct dmi_system_id acer_quirks[] = { | |||
530 | {} | 530 | {} |
531 | }; | 531 | }; |
532 | 532 | ||
533 | static int video_set_backlight_video_vendor(const struct dmi_system_id *d) | 533 | static int __init |
534 | video_set_backlight_video_vendor(const struct dmi_system_id *d) | ||
534 | { | 535 | { |
535 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | 536 | interface->capability &= ~ACER_CAP_BRIGHTNESS; |
536 | pr_info("Brightness must be controlled by generic video driver\n"); | 537 | pr_info("Brightness must be controlled by generic video driver\n"); |
537 | return 0; | 538 | return 0; |
538 | } | 539 | } |
539 | 540 | ||
540 | static const struct dmi_system_id video_vendor_dmi_table[] = { | 541 | static const struct dmi_system_id video_vendor_dmi_table[] __initconst = { |
541 | { | 542 | { |
542 | .callback = video_set_backlight_video_vendor, | 543 | .callback = video_set_backlight_video_vendor, |
543 | .ident = "Acer TravelMate 4750", | 544 | .ident = "Acer TravelMate 4750", |
@@ -582,7 +583,7 @@ static const struct dmi_system_id video_vendor_dmi_table[] = { | |||
582 | }; | 583 | }; |
583 | 584 | ||
584 | /* Find which quirks are needed for a particular vendor/ model pair */ | 585 | /* Find which quirks are needed for a particular vendor/ model pair */ |
585 | static void find_quirks(void) | 586 | static void __init find_quirks(void) |
586 | { | 587 | { |
587 | if (!force_series) { | 588 | if (!force_series) { |
588 | dmi_check_system(acer_quirks); | 589 | dmi_check_system(acer_quirks); |
@@ -749,7 +750,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap) | |||
749 | return wmab_execute(&args, NULL); | 750 | return wmab_execute(&args, NULL); |
750 | } | 751 | } |
751 | 752 | ||
752 | static acpi_status AMW0_find_mailled(void) | 753 | static acpi_status __init AMW0_find_mailled(void) |
753 | { | 754 | { |
754 | struct wmab_args args; | 755 | struct wmab_args args; |
755 | struct wmab_ret ret; | 756 | struct wmab_ret ret; |
@@ -781,16 +782,16 @@ static acpi_status AMW0_find_mailled(void) | |||
781 | return AE_OK; | 782 | return AE_OK; |
782 | } | 783 | } |
783 | 784 | ||
784 | static int AMW0_set_cap_acpi_check_device_found; | 785 | static int AMW0_set_cap_acpi_check_device_found __initdata; |
785 | 786 | ||
786 | static acpi_status AMW0_set_cap_acpi_check_device_cb(acpi_handle handle, | 787 | static acpi_status __init AMW0_set_cap_acpi_check_device_cb(acpi_handle handle, |
787 | u32 level, void *context, void **retval) | 788 | u32 level, void *context, void **retval) |
788 | { | 789 | { |
789 | AMW0_set_cap_acpi_check_device_found = 1; | 790 | AMW0_set_cap_acpi_check_device_found = 1; |
790 | return AE_OK; | 791 | return AE_OK; |
791 | } | 792 | } |
792 | 793 | ||
793 | static const struct acpi_device_id norfkill_ids[] = { | 794 | static const struct acpi_device_id norfkill_ids[] __initconst = { |
794 | { "VPC2004", 0}, | 795 | { "VPC2004", 0}, |
795 | { "IBM0068", 0}, | 796 | { "IBM0068", 0}, |
796 | { "LEN0068", 0}, | 797 | { "LEN0068", 0}, |
@@ -798,7 +799,7 @@ static const struct acpi_device_id norfkill_ids[] = { | |||
798 | { "", 0}, | 799 | { "", 0}, |
799 | }; | 800 | }; |
800 | 801 | ||
801 | static int AMW0_set_cap_acpi_check_device(void) | 802 | static int __init AMW0_set_cap_acpi_check_device(void) |
802 | { | 803 | { |
803 | const struct acpi_device_id *id; | 804 | const struct acpi_device_id *id; |
804 | 805 | ||
@@ -808,7 +809,7 @@ static int AMW0_set_cap_acpi_check_device(void) | |||
808 | return AMW0_set_cap_acpi_check_device_found; | 809 | return AMW0_set_cap_acpi_check_device_found; |
809 | } | 810 | } |
810 | 811 | ||
811 | static acpi_status AMW0_set_capabilities(void) | 812 | static acpi_status __init AMW0_set_capabilities(void) |
812 | { | 813 | { |
813 | struct wmab_args args; | 814 | struct wmab_args args; |
814 | struct wmab_ret ret; | 815 | struct wmab_ret ret; |
@@ -1184,7 +1185,7 @@ static acpi_status wmid_v2_set_u32(u32 value, u32 cap) | |||
1184 | return wmid3_set_device_status(value, device); | 1185 | return wmid3_set_device_status(value, device); |
1185 | } | 1186 | } |
1186 | 1187 | ||
1187 | static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) | 1188 | static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) |
1188 | { | 1189 | { |
1189 | struct hotkey_function_type_aa *type_aa; | 1190 | struct hotkey_function_type_aa *type_aa; |
1190 | 1191 | ||
@@ -1209,7 +1210,7 @@ static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) | |||
1209 | commun_fn_key_number = type_aa->commun_fn_key_number; | 1210 | commun_fn_key_number = type_aa->commun_fn_key_number; |
1210 | } | 1211 | } |
1211 | 1212 | ||
1212 | static acpi_status WMID_set_capabilities(void) | 1213 | static acpi_status __init WMID_set_capabilities(void) |
1213 | { | 1214 | { |
1214 | struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; | 1215 | struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; |
1215 | union acpi_object *obj; | 1216 | union acpi_object *obj; |
@@ -1658,7 +1659,7 @@ static ssize_t show_bool_threeg(struct device *dev, | |||
1658 | u32 result; \ | 1659 | u32 result; \ |
1659 | acpi_status status; | 1660 | acpi_status status; |
1660 | 1661 | ||
1661 | pr_info("This threeg sysfs will be removed in 2012 - used by: %s\n", | 1662 | pr_info("This threeg sysfs will be removed in 2014 - used by: %s\n", |
1662 | current->comm); | 1663 | current->comm); |
1663 | status = get_u32(&result, ACER_CAP_THREEG); | 1664 | status = get_u32(&result, ACER_CAP_THREEG); |
1664 | if (ACPI_SUCCESS(status)) | 1665 | if (ACPI_SUCCESS(status)) |
@@ -1671,7 +1672,7 @@ static ssize_t set_bool_threeg(struct device *dev, | |||
1671 | { | 1672 | { |
1672 | u32 tmp = simple_strtoul(buf, NULL, 10); | 1673 | u32 tmp = simple_strtoul(buf, NULL, 10); |
1673 | acpi_status status = set_u32(tmp, ACER_CAP_THREEG); | 1674 | acpi_status status = set_u32(tmp, ACER_CAP_THREEG); |
1674 | pr_info("This threeg sysfs will be removed in 2012 - used by: %s\n", | 1675 | pr_info("This threeg sysfs will be removed in 2014 - used by: %s\n", |
1675 | current->comm); | 1676 | current->comm); |
1676 | if (ACPI_FAILURE(status)) | 1677 | if (ACPI_FAILURE(status)) |
1677 | return -EINVAL; | 1678 | return -EINVAL; |
@@ -1683,7 +1684,7 @@ static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg, | |||
1683 | static ssize_t show_interface(struct device *dev, struct device_attribute *attr, | 1684 | static ssize_t show_interface(struct device *dev, struct device_attribute *attr, |
1684 | char *buf) | 1685 | char *buf) |
1685 | { | 1686 | { |
1686 | pr_info("This interface sysfs will be removed in 2012 - used by: %s\n", | 1687 | pr_info("This interface sysfs will be removed in 2014 - used by: %s\n", |
1687 | current->comm); | 1688 | current->comm); |
1688 | switch (interface->type) { | 1689 | switch (interface->type) { |
1689 | case ACER_AMW0: | 1690 | case ACER_AMW0: |
@@ -1777,7 +1778,7 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1777 | } | 1778 | } |
1778 | } | 1779 | } |
1779 | 1780 | ||
1780 | static acpi_status | 1781 | static acpi_status __init |
1781 | wmid3_set_lm_mode(struct lm_input_params *params, | 1782 | wmid3_set_lm_mode(struct lm_input_params *params, |
1782 | struct lm_return_value *return_value) | 1783 | struct lm_return_value *return_value) |
1783 | { | 1784 | { |
@@ -1811,7 +1812,7 @@ wmid3_set_lm_mode(struct lm_input_params *params, | |||
1811 | return status; | 1812 | return status; |
1812 | } | 1813 | } |
1813 | 1814 | ||
1814 | static int acer_wmi_enable_ec_raw(void) | 1815 | static int __init acer_wmi_enable_ec_raw(void) |
1815 | { | 1816 | { |
1816 | struct lm_return_value return_value; | 1817 | struct lm_return_value return_value; |
1817 | acpi_status status; | 1818 | acpi_status status; |
@@ -1834,7 +1835,7 @@ static int acer_wmi_enable_ec_raw(void) | |||
1834 | return status; | 1835 | return status; |
1835 | } | 1836 | } |
1836 | 1837 | ||
1837 | static int acer_wmi_enable_lm(void) | 1838 | static int __init acer_wmi_enable_lm(void) |
1838 | { | 1839 | { |
1839 | struct lm_return_value return_value; | 1840 | struct lm_return_value return_value; |
1840 | acpi_status status; | 1841 | acpi_status status; |
@@ -2043,6 +2044,7 @@ static int acer_platform_remove(struct platform_device *device) | |||
2043 | return 0; | 2044 | return 0; |
2044 | } | 2045 | } |
2045 | 2046 | ||
2047 | #ifdef CONFIG_PM_SLEEP | ||
2046 | static int acer_suspend(struct device *dev) | 2048 | static int acer_suspend(struct device *dev) |
2047 | { | 2049 | { |
2048 | u32 value; | 2050 | u32 value; |
@@ -2083,6 +2085,10 @@ static int acer_resume(struct device *dev) | |||
2083 | 2085 | ||
2084 | return 0; | 2086 | return 0; |
2085 | } | 2087 | } |
2088 | #else | ||
2089 | #define acer_suspend NULL | ||
2090 | #define acer_resume NULL | ||
2091 | #endif | ||
2086 | 2092 | ||
2087 | static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); | 2093 | static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); |
2088 | 2094 | ||
@@ -2120,7 +2126,7 @@ static int remove_sysfs(struct platform_device *device) | |||
2120 | return 0; | 2126 | return 0; |
2121 | } | 2127 | } |
2122 | 2128 | ||
2123 | static int create_sysfs(void) | 2129 | static int __init create_sysfs(void) |
2124 | { | 2130 | { |
2125 | int retval = -ENOMEM; | 2131 | int retval = -ENOMEM; |
2126 | 2132 | ||
@@ -2149,7 +2155,7 @@ static void remove_debugfs(void) | |||
2149 | debugfs_remove(interface->debug.root); | 2155 | debugfs_remove(interface->debug.root); |
2150 | } | 2156 | } |
2151 | 2157 | ||
2152 | static int create_debugfs(void) | 2158 | static int __init create_debugfs(void) |
2153 | { | 2159 | { |
2154 | interface->debug.root = debugfs_create_dir("acer-wmi", NULL); | 2160 | interface->debug.root = debugfs_create_dir("acer-wmi", NULL); |
2155 | if (!interface->debug.root) { | 2161 | if (!interface->debug.root) { |
diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index 297b6640213f..c5af23b64438 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c | |||
@@ -59,25 +59,33 @@ enum WMAX_CONTROL_STATES { | |||
59 | 59 | ||
60 | struct quirk_entry { | 60 | struct quirk_entry { |
61 | u8 num_zones; | 61 | u8 num_zones; |
62 | u8 hdmi_mux; | ||
62 | }; | 63 | }; |
63 | 64 | ||
64 | static struct quirk_entry *quirks; | 65 | static struct quirk_entry *quirks; |
65 | 66 | ||
66 | static struct quirk_entry quirk_unknown = { | 67 | static struct quirk_entry quirk_unknown = { |
67 | .num_zones = 2, | 68 | .num_zones = 2, |
69 | .hdmi_mux = 0, | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | static struct quirk_entry quirk_x51_family = { | 72 | static struct quirk_entry quirk_x51_family = { |
71 | .num_zones = 3, | 73 | .num_zones = 3, |
74 | .hdmi_mux = 0. | ||
72 | }; | 75 | }; |
73 | 76 | ||
74 | static int dmi_matched(const struct dmi_system_id *dmi) | 77 | static struct quirk_entry quirk_asm100 = { |
78 | .num_zones = 2, | ||
79 | .hdmi_mux = 1, | ||
80 | }; | ||
81 | |||
82 | static int __init dmi_matched(const struct dmi_system_id *dmi) | ||
75 | { | 83 | { |
76 | quirks = dmi->driver_data; | 84 | quirks = dmi->driver_data; |
77 | return 1; | 85 | return 1; |
78 | } | 86 | } |
79 | 87 | ||
80 | static struct dmi_system_id alienware_quirks[] = { | 88 | static const struct dmi_system_id alienware_quirks[] __initconst = { |
81 | { | 89 | { |
82 | .callback = dmi_matched, | 90 | .callback = dmi_matched, |
83 | .ident = "Alienware X51 R1", | 91 | .ident = "Alienware X51 R1", |
@@ -96,6 +104,15 @@ static struct dmi_system_id alienware_quirks[] = { | |||
96 | }, | 104 | }, |
97 | .driver_data = &quirk_x51_family, | 105 | .driver_data = &quirk_x51_family, |
98 | }, | 106 | }, |
107 | { | ||
108 | .callback = dmi_matched, | ||
109 | .ident = "Alienware ASM100", | ||
110 | .matches = { | ||
111 | DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), | ||
112 | DMI_MATCH(DMI_PRODUCT_NAME, "ASM100"), | ||
113 | }, | ||
114 | .driver_data = &quirk_asm100, | ||
115 | }, | ||
99 | {} | 116 | {} |
100 | }; | 117 | }; |
101 | 118 | ||
@@ -537,7 +554,8 @@ static struct attribute_group hdmi_attribute_group = { | |||
537 | 554 | ||
538 | static void remove_hdmi(struct platform_device *dev) | 555 | static void remove_hdmi(struct platform_device *dev) |
539 | { | 556 | { |
540 | sysfs_remove_group(&dev->dev.kobj, &hdmi_attribute_group); | 557 | if (quirks->hdmi_mux > 0) |
558 | sysfs_remove_group(&dev->dev.kobj, &hdmi_attribute_group); | ||
541 | } | 559 | } |
542 | 560 | ||
543 | static int create_hdmi(struct platform_device *dev) | 561 | static int create_hdmi(struct platform_device *dev) |
@@ -583,7 +601,7 @@ static int __init alienware_wmi_init(void) | |||
583 | if (ret) | 601 | if (ret) |
584 | goto fail_platform_device2; | 602 | goto fail_platform_device2; |
585 | 603 | ||
586 | if (interface == WMAX) { | 604 | if (quirks->hdmi_mux > 0) { |
587 | ret = create_hdmi(platform_device); | 605 | ret = create_hdmi(platform_device); |
588 | if (ret) | 606 | if (ret) |
589 | goto fail_prep_hdmi; | 607 | goto fail_prep_hdmi; |
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index ddf0eefd862c..3a4951f46065 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c | |||
@@ -70,17 +70,35 @@ static struct quirk_entry quirk_asus_x55u = { | |||
70 | .no_display_toggle = true, | 70 | .no_display_toggle = true, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static struct quirk_entry quirk_asus_x401u = { | 73 | static struct quirk_entry quirk_asus_wapf4 = { |
74 | .wapf = 4, | 74 | .wapf = 4, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct quirk_entry quirk_asus_x200ca = { | ||
78 | .wapf = 2, | ||
79 | }; | ||
80 | |||
77 | static int dmi_matched(const struct dmi_system_id *dmi) | 81 | static int dmi_matched(const struct dmi_system_id *dmi) |
78 | { | 82 | { |
79 | quirks = dmi->driver_data; | 83 | quirks = dmi->driver_data; |
80 | return 1; | 84 | return 1; |
81 | } | 85 | } |
82 | 86 | ||
83 | static struct dmi_system_id asus_quirks[] = { | 87 | static const struct dmi_system_id asus_quirks[] = { |
88 | { | ||
89 | .callback = dmi_matched, | ||
90 | .ident = "ASUSTeK COMPUTER INC. U32U", | ||
91 | .matches = { | ||
92 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
93 | DMI_MATCH(DMI_PRODUCT_NAME, "U32U"), | ||
94 | }, | ||
95 | /* | ||
96 | * Note this machine has a Brazos APU, and most Brazos Asus | ||
97 | * machines need quirk_asus_x55u / wmi_backlight_power but | ||
98 | * here acpi-video seems to work fine for backlight control. | ||
99 | */ | ||
100 | .driver_data = &quirk_asus_wapf4, | ||
101 | }, | ||
84 | { | 102 | { |
85 | .callback = dmi_matched, | 103 | .callback = dmi_matched, |
86 | .ident = "ASUSTeK COMPUTER INC. X401U", | 104 | .ident = "ASUSTeK COMPUTER INC. X401U", |
@@ -97,7 +115,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
97 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 115 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
98 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A"), | 116 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A"), |
99 | }, | 117 | }, |
100 | .driver_data = &quirk_asus_x401u, | 118 | .driver_data = &quirk_asus_wapf4, |
101 | }, | 119 | }, |
102 | { | 120 | { |
103 | .callback = dmi_matched, | 121 | .callback = dmi_matched, |
@@ -106,7 +124,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
106 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 124 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
107 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), | 125 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), |
108 | }, | 126 | }, |
109 | .driver_data = &quirk_asus_x401u, | 127 | .driver_data = &quirk_asus_wapf4, |
110 | }, | 128 | }, |
111 | { | 129 | { |
112 | .callback = dmi_matched, | 130 | .callback = dmi_matched, |
@@ -124,7 +142,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
124 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 142 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
125 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A"), | 143 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A"), |
126 | }, | 144 | }, |
127 | .driver_data = &quirk_asus_x401u, | 145 | .driver_data = &quirk_asus_wapf4, |
128 | }, | 146 | }, |
129 | { | 147 | { |
130 | .callback = dmi_matched, | 148 | .callback = dmi_matched, |
@@ -133,7 +151,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
133 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 151 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
134 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), | 152 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), |
135 | }, | 153 | }, |
136 | .driver_data = &quirk_asus_x401u, | 154 | .driver_data = &quirk_asus_wapf4, |
137 | }, | 155 | }, |
138 | { | 156 | { |
139 | .callback = dmi_matched, | 157 | .callback = dmi_matched, |
@@ -142,7 +160,25 @@ static struct dmi_system_id asus_quirks[] = { | |||
142 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 160 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
143 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"), | 161 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"), |
144 | }, | 162 | }, |
145 | .driver_data = &quirk_asus_x401u, | 163 | .driver_data = &quirk_asus_wapf4, |
164 | }, | ||
165 | { | ||
166 | .callback = dmi_matched, | ||
167 | .ident = "ASUSTeK COMPUTER INC. X550CC", | ||
168 | .matches = { | ||
169 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
170 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"), | ||
171 | }, | ||
172 | .driver_data = &quirk_asus_wapf4, | ||
173 | }, | ||
174 | { | ||
175 | .callback = dmi_matched, | ||
176 | .ident = "ASUSTeK COMPUTER INC. X550CL", | ||
177 | .matches = { | ||
178 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
179 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"), | ||
180 | }, | ||
181 | .driver_data = &quirk_asus_wapf4, | ||
146 | }, | 182 | }, |
147 | { | 183 | { |
148 | .callback = dmi_matched, | 184 | .callback = dmi_matched, |
@@ -151,7 +187,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
151 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 187 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
152 | DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), | 188 | DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), |
153 | }, | 189 | }, |
154 | .driver_data = &quirk_asus_x401u, | 190 | .driver_data = &quirk_asus_wapf4, |
155 | }, | 191 | }, |
156 | { | 192 | { |
157 | .callback = dmi_matched, | 193 | .callback = dmi_matched, |
@@ -160,7 +196,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
160 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 196 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
161 | DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), | 197 | DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), |
162 | }, | 198 | }, |
163 | .driver_data = &quirk_asus_x401u, | 199 | .driver_data = &quirk_asus_wapf4, |
164 | }, | 200 | }, |
165 | { | 201 | { |
166 | .callback = dmi_matched, | 202 | .callback = dmi_matched, |
@@ -178,7 +214,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
178 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 214 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
179 | DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), | 215 | DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), |
180 | }, | 216 | }, |
181 | .driver_data = &quirk_asus_x401u, | 217 | .driver_data = &quirk_asus_wapf4, |
182 | }, | 218 | }, |
183 | { | 219 | { |
184 | .callback = dmi_matched, | 220 | .callback = dmi_matched, |
@@ -187,7 +223,16 @@ static struct dmi_system_id asus_quirks[] = { | |||
187 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 223 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
188 | DMI_MATCH(DMI_PRODUCT_NAME, "X75A"), | 224 | DMI_MATCH(DMI_PRODUCT_NAME, "X75A"), |
189 | }, | 225 | }, |
190 | .driver_data = &quirk_asus_x401u, | 226 | .driver_data = &quirk_asus_wapf4, |
227 | }, | ||
228 | { | ||
229 | .callback = dmi_matched, | ||
230 | .ident = "ASUSTeK COMPUTER INC. X75VBP", | ||
231 | .matches = { | ||
232 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
233 | DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"), | ||
234 | }, | ||
235 | .driver_data = &quirk_asus_wapf4, | ||
191 | }, | 236 | }, |
192 | { | 237 | { |
193 | .callback = dmi_matched, | 238 | .callback = dmi_matched, |
@@ -196,7 +241,7 @@ static struct dmi_system_id asus_quirks[] = { | |||
196 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 241 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
197 | DMI_MATCH(DMI_PRODUCT_NAME, "1015E"), | 242 | DMI_MATCH(DMI_PRODUCT_NAME, "1015E"), |
198 | }, | 243 | }, |
199 | .driver_data = &quirk_asus_x401u, | 244 | .driver_data = &quirk_asus_wapf4, |
200 | }, | 245 | }, |
201 | { | 246 | { |
202 | .callback = dmi_matched, | 247 | .callback = dmi_matched, |
@@ -205,7 +250,16 @@ static struct dmi_system_id asus_quirks[] = { | |||
205 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 250 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
206 | DMI_MATCH(DMI_PRODUCT_NAME, "1015U"), | 251 | DMI_MATCH(DMI_PRODUCT_NAME, "1015U"), |
207 | }, | 252 | }, |
208 | .driver_data = &quirk_asus_x401u, | 253 | .driver_data = &quirk_asus_wapf4, |
254 | }, | ||
255 | { | ||
256 | .callback = dmi_matched, | ||
257 | .ident = "ASUSTeK COMPUTER INC. X200CA", | ||
258 | .matches = { | ||
259 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
260 | DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"), | ||
261 | }, | ||
262 | .driver_data = &quirk_asus_x200ca, | ||
209 | }, | 263 | }, |
210 | {}, | 264 | {}, |
211 | }; | 265 | }; |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 3c6ccedc82b6..21fc932da3a1 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
47 | #include <linux/thermal.h> | 47 | #include <linux/thermal.h> |
48 | #include <linux/acpi.h> | 48 | #include <linux/acpi.h> |
49 | #include <linux/dmi.h> | ||
49 | #include <acpi/video.h> | 50 | #include <acpi/video.h> |
50 | 51 | ||
51 | #include "asus-wmi.h" | 52 | #include "asus-wmi.h" |
@@ -554,7 +555,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) | |||
554 | goto error; | 555 | goto error; |
555 | } | 556 | } |
556 | 557 | ||
557 | if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) { | 558 | if (wlan_led_presence(asus) && (asus->driver->quirks->wapf > 0)) { |
558 | INIT_WORK(&asus->wlan_led_work, wlan_led_update); | 559 | INIT_WORK(&asus->wlan_led_work, wlan_led_update); |
559 | 560 | ||
560 | asus->wlan_led.name = "asus::wlan"; | 561 | asus->wlan_led.name = "asus::wlan"; |
@@ -884,7 +885,7 @@ static int asus_new_rfkill(struct asus_wmi *asus, | |||
884 | return -EINVAL; | 885 | return -EINVAL; |
885 | 886 | ||
886 | if ((dev_id == ASUS_WMI_DEVID_WLAN) && | 887 | if ((dev_id == ASUS_WMI_DEVID_WLAN) && |
887 | (asus->driver->quirks->wapf == 4)) | 888 | (asus->driver->quirks->wapf > 0)) |
888 | rfkill_set_led_trigger_name(*rfkill, "asus-wlan"); | 889 | rfkill_set_led_trigger_name(*rfkill, "asus-wlan"); |
889 | 890 | ||
890 | rfkill_init_sw_state(*rfkill, !result); | 891 | rfkill_init_sw_state(*rfkill, !result); |
@@ -1270,10 +1271,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus) | |||
1270 | int power; | 1271 | int power; |
1271 | 1272 | ||
1272 | max = read_brightness_max(asus); | 1273 | max = read_brightness_max(asus); |
1273 | 1274 | if (max < 0) | |
1274 | if (max == -ENODEV) | ||
1275 | max = 0; | ||
1276 | else if (max < 0) | ||
1277 | return max; | 1275 | return max; |
1278 | 1276 | ||
1279 | power = read_backlight_power(asus); | 1277 | power = read_backlight_power(asus); |
@@ -1734,6 +1732,7 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1734 | struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); | 1732 | struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); |
1735 | struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); | 1733 | struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); |
1736 | struct asus_wmi *asus; | 1734 | struct asus_wmi *asus; |
1735 | const char *chassis_type; | ||
1737 | acpi_status status; | 1736 | acpi_status status; |
1738 | int err; | 1737 | int err; |
1739 | u32 result; | 1738 | u32 result; |
@@ -1770,6 +1769,11 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1770 | if (err) | 1769 | if (err) |
1771 | goto fail_rfkill; | 1770 | goto fail_rfkill; |
1772 | 1771 | ||
1772 | /* Some Asus desktop boards export an acpi-video backlight interface, | ||
1773 | stop this from showing up */ | ||
1774 | chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); | ||
1775 | if (chassis_type && !strcmp(chassis_type, "3")) | ||
1776 | acpi_video_dmi_promote_vendor(); | ||
1773 | if (asus->driver->quirks->wmi_backlight_power) | 1777 | if (asus->driver->quirks->wmi_backlight_power) |
1774 | acpi_video_dmi_promote_vendor(); | 1778 | acpi_video_dmi_promote_vendor(); |
1775 | if (!acpi_video_backlight_support()) { | 1779 | if (!acpi_video_backlight_support()) { |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 7297df2ebf50..26bfd7bb5c13 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -1028,7 +1028,7 @@ static int compal_probe(struct platform_device *pdev) | |||
1028 | return err; | 1028 | return err; |
1029 | 1029 | ||
1030 | hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, | 1030 | hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, |
1031 | DRIVER_NAME, data, | 1031 | "compal", data, |
1032 | compal_hwmon_groups); | 1032 | compal_hwmon_groups); |
1033 | if (IS_ERR(hwmon_dev)) { | 1033 | if (IS_ERR(hwmon_dev)) { |
1034 | err = PTR_ERR(hwmon_dev); | 1034 | err = PTR_ERR(hwmon_dev); |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index fed4111ac31a..233d2ee598a6 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -70,7 +70,7 @@ static struct quirk_entry quirk_dell_vostro_v130 = { | |||
70 | .touchpad_led = 1, | 70 | .touchpad_led = 1, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static int dmi_matched(const struct dmi_system_id *dmi) | 73 | static int __init dmi_matched(const struct dmi_system_id *dmi) |
74 | { | 74 | { |
75 | quirks = dmi->driver_data; | 75 | quirks = dmi->driver_data; |
76 | return 1; | 76 | return 1; |
@@ -123,7 +123,7 @@ static const struct dmi_system_id dell_device_table[] __initconst = { | |||
123 | }; | 123 | }; |
124 | MODULE_DEVICE_TABLE(dmi, dell_device_table); | 124 | MODULE_DEVICE_TABLE(dmi, dell_device_table); |
125 | 125 | ||
126 | static struct dmi_system_id dell_quirks[] = { | 126 | static const struct dmi_system_id dell_quirks[] __initconst = { |
127 | { | 127 | { |
128 | .callback = dmi_matched, | 128 | .callback = dmi_matched, |
129 | .ident = "Dell Vostro V130", | 129 | .ident = "Dell Vostro V130", |
@@ -780,7 +780,7 @@ static struct led_classdev touchpad_led = { | |||
780 | .flags = LED_CORE_SUSPENDRESUME, | 780 | .flags = LED_CORE_SUSPENDRESUME, |
781 | }; | 781 | }; |
782 | 782 | ||
783 | static int touchpad_led_init(struct device *dev) | 783 | static int __init touchpad_led_init(struct device *dev) |
784 | { | 784 | { |
785 | return led_classdev_register(dev, &touchpad_led); | 785 | return led_classdev_register(dev, &touchpad_led); |
786 | } | 786 | } |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9b0c57cd1d4a..bd533c22be57 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -1053,20 +1053,20 @@ static ssize_t show_sys_hwmon(int (*get)(void), char *buf) | |||
1053 | return sprintf(buf, "%d\n", get()); | 1053 | return sprintf(buf, "%d\n", get()); |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \ | 1056 | #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _get, _set) \ |
1057 | static ssize_t show_##_name(struct device *dev, \ | 1057 | static ssize_t show_##_name(struct device *dev, \ |
1058 | struct device_attribute *attr, \ | 1058 | struct device_attribute *attr, \ |
1059 | char *buf) \ | 1059 | char *buf) \ |
1060 | { \ | 1060 | { \ |
1061 | return show_sys_hwmon(_set, buf); \ | 1061 | return show_sys_hwmon(_get, buf); \ |
1062 | } \ | 1062 | } \ |
1063 | static ssize_t store_##_name(struct device *dev, \ | 1063 | static ssize_t store_##_name(struct device *dev, \ |
1064 | struct device_attribute *attr, \ | 1064 | struct device_attribute *attr, \ |
1065 | const char *buf, size_t count) \ | 1065 | const char *buf, size_t count) \ |
1066 | { \ | 1066 | { \ |
1067 | return store_sys_hwmon(_get, buf, count); \ | 1067 | return store_sys_hwmon(_set, buf, count); \ |
1068 | } \ | 1068 | } \ |
1069 | static DEVICE_ATTR(_name, _mode, show_##_name, store_##_name); | 1069 | static DEVICE_ATTR(_name, _mode, show_##_name, store_##_name) |
1070 | 1070 | ||
1071 | EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL); | 1071 | EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL); |
1072 | EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, | 1072 | EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, |
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 6112933f6278..14fd2ecb06a1 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -145,7 +145,7 @@ static int dmi_matched(const struct dmi_system_id *dmi) | |||
145 | return 1; | 145 | return 1; |
146 | } | 146 | } |
147 | 147 | ||
148 | static struct dmi_system_id asus_quirks[] = { | 148 | static const struct dmi_system_id asus_quirks[] = { |
149 | { | 149 | { |
150 | .callback = dmi_matched, | 150 | .callback = dmi_matched, |
151 | .ident = "ASUSTeK Computer INC. 1000H", | 151 | .ident = "ASUSTeK Computer INC. 1000H", |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index e6f336270c21..87aa28c4280f 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -129,15 +129,14 @@ | |||
129 | #define FUJLAPTOP_DBG_INFO 0x0004 | 129 | #define FUJLAPTOP_DBG_INFO 0x0004 |
130 | #define FUJLAPTOP_DBG_TRACE 0x0008 | 130 | #define FUJLAPTOP_DBG_TRACE 0x0008 |
131 | 131 | ||
132 | #define dbg_printk(a_dbg_level, format, arg...) \ | 132 | #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG |
133 | #define vdbg_printk(a_dbg_level, format, arg...) \ | ||
133 | do { if (dbg_level & a_dbg_level) \ | 134 | do { if (dbg_level & a_dbg_level) \ |
134 | printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \ | 135 | printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \ |
135 | } while (0) | 136 | } while (0) |
136 | #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG | ||
137 | #define vdbg_printk(a_dbg_level, format, arg...) \ | ||
138 | dbg_printk(a_dbg_level, format, ## arg) | ||
139 | #else | 137 | #else |
140 | #define vdbg_printk(a_dbg_level, format, arg...) | 138 | #define vdbg_printk(a_dbg_level, format, arg...) \ |
139 | do { } while (0) | ||
141 | #endif | 140 | #endif |
142 | 141 | ||
143 | /* Device controlling the backlight and associated keys */ | 142 | /* Device controlling the backlight and associated keys */ |
@@ -564,7 +563,7 @@ static struct platform_driver fujitsupf_driver = { | |||
564 | } | 563 | } |
565 | }; | 564 | }; |
566 | 565 | ||
567 | static void dmi_check_cb_common(const struct dmi_system_id *id) | 566 | static void __init dmi_check_cb_common(const struct dmi_system_id *id) |
568 | { | 567 | { |
569 | pr_info("Identified laptop model '%s'\n", id->ident); | 568 | pr_info("Identified laptop model '%s'\n", id->ident); |
570 | if (use_alt_lcd_levels == -1) { | 569 | if (use_alt_lcd_levels == -1) { |
@@ -578,7 +577,7 @@ static void dmi_check_cb_common(const struct dmi_system_id *id) | |||
578 | } | 577 | } |
579 | } | 578 | } |
580 | 579 | ||
581 | static int dmi_check_cb_s6410(const struct dmi_system_id *id) | 580 | static int __init dmi_check_cb_s6410(const struct dmi_system_id *id) |
582 | { | 581 | { |
583 | dmi_check_cb_common(id); | 582 | dmi_check_cb_common(id); |
584 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | 583 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ |
@@ -586,7 +585,7 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id) | |||
586 | return 1; | 585 | return 1; |
587 | } | 586 | } |
588 | 587 | ||
589 | static int dmi_check_cb_s6420(const struct dmi_system_id *id) | 588 | static int __init dmi_check_cb_s6420(const struct dmi_system_id *id) |
590 | { | 589 | { |
591 | dmi_check_cb_common(id); | 590 | dmi_check_cb_common(id); |
592 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | 591 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ |
@@ -594,7 +593,7 @@ static int dmi_check_cb_s6420(const struct dmi_system_id *id) | |||
594 | return 1; | 593 | return 1; |
595 | } | 594 | } |
596 | 595 | ||
597 | static int dmi_check_cb_p8010(const struct dmi_system_id *id) | 596 | static int __init dmi_check_cb_p8010(const struct dmi_system_id *id) |
598 | { | 597 | { |
599 | dmi_check_cb_common(id); | 598 | dmi_check_cb_common(id); |
600 | fujitsu->keycode1 = KEY_HELP; /* "Support" */ | 599 | fujitsu->keycode1 = KEY_HELP; /* "Support" */ |
@@ -603,7 +602,7 @@ static int dmi_check_cb_p8010(const struct dmi_system_id *id) | |||
603 | return 1; | 602 | return 1; |
604 | } | 603 | } |
605 | 604 | ||
606 | static struct dmi_system_id fujitsu_dmi_table[] = { | 605 | static const struct dmi_system_id fujitsu_dmi_table[] __initconst = { |
607 | { | 606 | { |
608 | .ident = "Fujitsu Siemens S6410", | 607 | .ident = "Fujitsu Siemens S6410", |
609 | .matches = { | 608 | .matches = { |
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index c3784baceae3..53bdbb01bd3f 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c | |||
@@ -315,21 +315,21 @@ static irqreturn_t fujitsu_interrupt(int irq, void *dev_id) | |||
315 | return IRQ_HANDLED; | 315 | return IRQ_HANDLED; |
316 | } | 316 | } |
317 | 317 | ||
318 | static void fujitsu_dmi_common(const struct dmi_system_id *dmi) | 318 | static void __init fujitsu_dmi_common(const struct dmi_system_id *dmi) |
319 | { | 319 | { |
320 | pr_info("%s\n", dmi->ident); | 320 | pr_info("%s\n", dmi->ident); |
321 | memcpy(fujitsu.config.keymap, dmi->driver_data, | 321 | memcpy(fujitsu.config.keymap, dmi->driver_data, |
322 | sizeof(fujitsu.config.keymap)); | 322 | sizeof(fujitsu.config.keymap)); |
323 | } | 323 | } |
324 | 324 | ||
325 | static int fujitsu_dmi_lifebook(const struct dmi_system_id *dmi) | 325 | static int __init fujitsu_dmi_lifebook(const struct dmi_system_id *dmi) |
326 | { | 326 | { |
327 | fujitsu_dmi_common(dmi); | 327 | fujitsu_dmi_common(dmi); |
328 | fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT; | 328 | fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT; |
329 | return 1; | 329 | return 1; |
330 | } | 330 | } |
331 | 331 | ||
332 | static int fujitsu_dmi_stylistic(const struct dmi_system_id *dmi) | 332 | static int __init fujitsu_dmi_stylistic(const struct dmi_system_id *dmi) |
333 | { | 333 | { |
334 | fujitsu_dmi_common(dmi); | 334 | fujitsu_dmi_common(dmi); |
335 | fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK; | 335 | fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK; |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 484a8673b835..4c559640dcba 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -295,7 +295,7 @@ static int hp_wmi_tablet_state(void) | |||
295 | return (state & 0x4) ? 1 : 0; | 295 | return (state & 0x4) ? 1 : 0; |
296 | } | 296 | } |
297 | 297 | ||
298 | static int hp_wmi_bios_2009_later(void) | 298 | static int __init hp_wmi_bios_2009_later(void) |
299 | { | 299 | { |
300 | int state = 0; | 300 | int state = 0; |
301 | int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state, | 301 | int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state, |
@@ -704,7 +704,7 @@ static void cleanup_sysfs(struct platform_device *device) | |||
704 | device_remove_file(&device->dev, &dev_attr_postcode); | 704 | device_remove_file(&device->dev, &dev_attr_postcode); |
705 | } | 705 | } |
706 | 706 | ||
707 | static int hp_wmi_rfkill_setup(struct platform_device *device) | 707 | static int __init hp_wmi_rfkill_setup(struct platform_device *device) |
708 | { | 708 | { |
709 | int err; | 709 | int err; |
710 | int wireless = 0; | 710 | int wireless = 0; |
@@ -806,7 +806,7 @@ register_wifi_error: | |||
806 | return err; | 806 | return err; |
807 | } | 807 | } |
808 | 808 | ||
809 | static int hp_wmi_rfkill2_setup(struct platform_device *device) | 809 | static int __init hp_wmi_rfkill2_setup(struct platform_device *device) |
810 | { | 810 | { |
811 | int err, i; | 811 | int err, i; |
812 | struct bios_rfkill2_state state; | 812 | struct bios_rfkill2_state state; |
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 3dc934438c28..13e14ec1d3d7 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -74,7 +74,7 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev, | |||
74 | /* HP-specific accelerometer driver ------------------------------------ */ | 74 | /* HP-specific accelerometer driver ------------------------------------ */ |
75 | 75 | ||
76 | /* For automatic insertion of the module */ | 76 | /* For automatic insertion of the module */ |
77 | static struct acpi_device_id lis3lv02d_device_ids[] = { | 77 | static const struct acpi_device_id lis3lv02d_device_ids[] = { |
78 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ | 78 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ |
79 | {"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */ | 79 | {"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */ |
80 | {"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */ | 80 | {"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */ |
@@ -192,7 +192,7 @@ DEFINE_CONV(xy_swap_yz_inverted, 2, -1, -3); | |||
192 | }, \ | 192 | }, \ |
193 | .driver_data = &lis3lv02d_axis_##_axis \ | 193 | .driver_data = &lis3lv02d_axis_##_axis \ |
194 | } | 194 | } |
195 | static struct dmi_system_id lis3lv02d_dmi_ids[] = { | 195 | static const struct dmi_system_id lis3lv02d_dmi_ids[] = { |
196 | /* product names are truncated to match all kinds of a same model */ | 196 | /* product names are truncated to match all kinds of a same model */ |
197 | AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), | 197 | AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), |
198 | AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted), | 198 | AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted), |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index b4c495a62eec..fc468a3d95ce 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -87,6 +87,8 @@ struct ideapad_private { | |||
87 | struct backlight_device *blightdev; | 87 | struct backlight_device *blightdev; |
88 | struct dentry *debug; | 88 | struct dentry *debug; |
89 | unsigned long cfg; | 89 | unsigned long cfg; |
90 | bool has_hw_rfkill_switch; | ||
91 | bool has_touchpad_control; | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | static bool no_bt_rfkill; | 94 | static bool no_bt_rfkill; |
@@ -439,7 +441,7 @@ static umode_t ideapad_is_visible(struct kobject *kobj, | |||
439 | return supported ? attr->mode : 0; | 441 | return supported ? attr->mode : 0; |
440 | } | 442 | } |
441 | 443 | ||
442 | static struct attribute_group ideapad_attribute_group = { | 444 | static const struct attribute_group ideapad_attribute_group = { |
443 | .is_visible = ideapad_is_visible, | 445 | .is_visible = ideapad_is_visible, |
444 | .attrs = ideapad_attributes | 446 | .attrs = ideapad_attributes |
445 | }; | 447 | }; |
@@ -454,7 +456,7 @@ struct ideapad_rfk_data { | |||
454 | int type; | 456 | int type; |
455 | }; | 457 | }; |
456 | 458 | ||
457 | const struct ideapad_rfk_data ideapad_rfk_data[] = { | 459 | const const struct ideapad_rfk_data ideapad_rfk_data[] = { |
458 | { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, | 460 | { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, |
459 | { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, | 461 | { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, |
460 | { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, | 462 | { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, |
@@ -473,12 +475,14 @@ static struct rfkill_ops ideapad_rfk_ops = { | |||
473 | 475 | ||
474 | static void ideapad_sync_rfk_state(struct ideapad_private *priv) | 476 | static void ideapad_sync_rfk_state(struct ideapad_private *priv) |
475 | { | 477 | { |
476 | unsigned long hw_blocked; | 478 | unsigned long hw_blocked = 0; |
477 | int i; | 479 | int i; |
478 | 480 | ||
479 | if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) | 481 | if (priv->has_hw_rfkill_switch) { |
480 | return; | 482 | if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) |
481 | hw_blocked = !hw_blocked; | 483 | return; |
484 | hw_blocked = !hw_blocked; | ||
485 | } | ||
482 | 486 | ||
483 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) | 487 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) |
484 | if (priv->rfk[i]) | 488 | if (priv->rfk[i]) |
@@ -763,6 +767,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) | |||
763 | { | 767 | { |
764 | unsigned long value; | 768 | unsigned long value; |
765 | 769 | ||
770 | if (!priv->has_touchpad_control) | ||
771 | return; | ||
772 | |||
766 | /* Without reading from EC touchpad LED doesn't switch state */ | 773 | /* Without reading from EC touchpad LED doesn't switch state */ |
767 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { | 774 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { |
768 | /* Some IdeaPads don't really turn off touchpad - they only | 775 | /* Some IdeaPads don't really turn off touchpad - they only |
@@ -821,14 +828,39 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) | |||
821 | } | 828 | } |
822 | } | 829 | } |
823 | 830 | ||
824 | /* Blacklist for devices where the ideapad rfkill interface does not work */ | 831 | /* |
825 | static struct dmi_system_id rfkill_blacklist[] = { | 832 | * Some ideapads don't have a hardware rfkill switch, reading VPCCMD_R_RF |
826 | /* The Lenovo Yoga 2 11 always reports everything as blocked */ | 833 | * always results in 0 on these models, causing ideapad_laptop to wrongly |
834 | * report all radios as hardware-blocked. | ||
835 | */ | ||
836 | static struct dmi_system_id no_hw_rfkill_list[] = { | ||
827 | { | 837 | { |
828 | .ident = "Lenovo Yoga 2 11", | 838 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", |
829 | .matches = { | 839 | .matches = { |
830 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 840 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
831 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), | 841 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), |
842 | }, | ||
843 | }, | ||
844 | {} | ||
845 | }; | ||
846 | |||
847 | /* | ||
848 | * Some models don't offer touchpad ctrl through the ideapad interface, causing | ||
849 | * ideapad_sync_touchpad_state to send wrong touchpad enable/disable events. | ||
850 | */ | ||
851 | static struct dmi_system_id no_touchpad_ctrl_list[] = { | ||
852 | { | ||
853 | .ident = "Lenovo Yoga 1 series", | ||
854 | .matches = { | ||
855 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
856 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga"), | ||
857 | }, | ||
858 | }, | ||
859 | { | ||
860 | .ident = "Lenovo Yoga 2 11 / 13 / Pro", | ||
861 | .matches = { | ||
862 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
863 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), | ||
832 | }, | 864 | }, |
833 | }, | 865 | }, |
834 | {} | 866 | {} |
@@ -856,6 +888,8 @@ static int ideapad_acpi_add(struct platform_device *pdev) | |||
856 | priv->cfg = cfg; | 888 | priv->cfg = cfg; |
857 | priv->adev = adev; | 889 | priv->adev = adev; |
858 | priv->platform_device = pdev; | 890 | priv->platform_device = pdev; |
891 | priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list); | ||
892 | priv->has_touchpad_control = !dmi_check_system(no_touchpad_ctrl_list); | ||
859 | 893 | ||
860 | ret = ideapad_sysfs_init(priv); | 894 | ret = ideapad_sysfs_init(priv); |
861 | if (ret) | 895 | if (ret) |
@@ -869,11 +903,17 @@ static int ideapad_acpi_add(struct platform_device *pdev) | |||
869 | if (ret) | 903 | if (ret) |
870 | goto input_failed; | 904 | goto input_failed; |
871 | 905 | ||
872 | if (!dmi_check_system(rfkill_blacklist)) { | 906 | /* |
873 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) | 907 | * On some models without a hw-switch (the yoga 2 13 at least) |
874 | if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) | 908 | * VPCCMD_W_RF must be explicitly set to 1 for the wifi to work. |
875 | ideapad_register_rfkill(priv, i); | 909 | */ |
876 | } | 910 | if (!priv->has_hw_rfkill_switch) |
911 | write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1); | ||
912 | |||
913 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) | ||
914 | if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) | ||
915 | ideapad_register_rfkill(priv, i); | ||
916 | |||
877 | ideapad_sync_rfk_state(priv); | 917 | ideapad_sync_rfk_state(priv); |
878 | ideapad_sync_touchpad_state(priv); | 918 | ideapad_sync_touchpad_state(priv); |
879 | 919 | ||
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index a0d1f576cf40..c0242ed13d9e 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -269,7 +269,7 @@ struct ips_mcp_limits { | |||
269 | 269 | ||
270 | /* Max temps are -10 degrees C to avoid PROCHOT# */ | 270 | /* Max temps are -10 degrees C to avoid PROCHOT# */ |
271 | 271 | ||
272 | struct ips_mcp_limits ips_sv_limits = { | 272 | static struct ips_mcp_limits ips_sv_limits = { |
273 | .mcp_power_limit = 35000, | 273 | .mcp_power_limit = 35000, |
274 | .core_power_limit = 29000, | 274 | .core_power_limit = 29000, |
275 | .mch_power_limit = 20000, | 275 | .mch_power_limit = 20000, |
@@ -277,7 +277,7 @@ struct ips_mcp_limits ips_sv_limits = { | |||
277 | .mch_temp_limit = 90 | 277 | .mch_temp_limit = 90 |
278 | }; | 278 | }; |
279 | 279 | ||
280 | struct ips_mcp_limits ips_lv_limits = { | 280 | static struct ips_mcp_limits ips_lv_limits = { |
281 | .mcp_power_limit = 25000, | 281 | .mcp_power_limit = 25000, |
282 | .core_power_limit = 21000, | 282 | .core_power_limit = 21000, |
283 | .mch_power_limit = 13000, | 283 | .mch_power_limit = 13000, |
@@ -285,7 +285,7 @@ struct ips_mcp_limits ips_lv_limits = { | |||
285 | .mch_temp_limit = 90 | 285 | .mch_temp_limit = 90 |
286 | }; | 286 | }; |
287 | 287 | ||
288 | struct ips_mcp_limits ips_ulv_limits = { | 288 | static struct ips_mcp_limits ips_ulv_limits = { |
289 | .mcp_power_limit = 18000, | 289 | .mcp_power_limit = 18000, |
290 | .core_power_limit = 14000, | 290 | .core_power_limit = 14000, |
291 | .mch_power_limit = 11000, | 291 | .mch_power_limit = 11000, |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 9c5a07417b2b..26ad9ff12ac5 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -2389,7 +2389,7 @@ static int sony_nc_lid_resume_setup(struct platform_device *pd, | |||
2389 | lid_ctl->attrs[LID_RESUME_S3].store = sony_nc_lid_resume_store; | 2389 | lid_ctl->attrs[LID_RESUME_S3].store = sony_nc_lid_resume_store; |
2390 | } | 2390 | } |
2391 | for (i = 0; i < LID_RESUME_MAX && | 2391 | for (i = 0; i < LID_RESUME_MAX && |
2392 | lid_ctl->attrs[LID_RESUME_S3].attr.name; i++) { | 2392 | lid_ctl->attrs[i].attr.name; i++) { |
2393 | result = device_create_file(&pd->dev, &lid_ctl->attrs[i]); | 2393 | result = device_create_file(&pd->dev, &lid_ctl->attrs[i]); |
2394 | if (result) | 2394 | if (result) |
2395 | goto liderror; | 2395 | goto liderror; |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d82f196e3cfe..3bbc6eb60de5 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -3174,7 +3174,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3174 | KEY_UNKNOWN, | 3174 | KEY_UNKNOWN, |
3175 | 3175 | ||
3176 | /* Extra keys in use since the X240 / T440 / T540 */ | 3176 | /* Extra keys in use since the X240 / T440 / T540 */ |
3177 | KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_COMPUTER, | 3177 | KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_FILE, |
3178 | }, | 3178 | }, |
3179 | }; | 3179 | }; |
3180 | 3180 | ||
@@ -6144,7 +6144,7 @@ static int brightness_set(unsigned int value) | |||
6144 | { | 6144 | { |
6145 | int res; | 6145 | int res; |
6146 | 6146 | ||
6147 | if (value > bright_maxlvl || value < 0) | 6147 | if (value > bright_maxlvl) |
6148 | return -EINVAL; | 6148 | return -EINVAL; |
6149 | 6149 | ||
6150 | vdbg_printk(TPACPI_DBG_BRGHT, | 6150 | vdbg_printk(TPACPI_DBG_BRGHT, |
@@ -6860,7 +6860,7 @@ static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, | |||
6860 | return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); | 6860 | return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); |
6861 | } | 6861 | } |
6862 | 6862 | ||
6863 | static struct snd_kcontrol_new volume_alsa_control_vol = { | 6863 | static struct snd_kcontrol_new volume_alsa_control_vol __initdata = { |
6864 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 6864 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
6865 | .name = "Console Playback Volume", | 6865 | .name = "Console Playback Volume", |
6866 | .index = 0, | 6866 | .index = 0, |
@@ -6869,7 +6869,7 @@ static struct snd_kcontrol_new volume_alsa_control_vol = { | |||
6869 | .get = volume_alsa_vol_get, | 6869 | .get = volume_alsa_vol_get, |
6870 | }; | 6870 | }; |
6871 | 6871 | ||
6872 | static struct snd_kcontrol_new volume_alsa_control_mute = { | 6872 | static struct snd_kcontrol_new volume_alsa_control_mute __initdata = { |
6873 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 6873 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
6874 | .name = "Console Playback Switch", | 6874 | .name = "Console Playback Switch", |
6875 | .index = 0, | 6875 | .index = 0, |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 76441dcbe5ff..b062d3d7b373 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -222,6 +222,12 @@ static const struct dmi_system_id toshiba_alt_keymap_dmi[] = { | |||
222 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M840"), | 222 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M840"), |
223 | }, | 223 | }, |
224 | }, | 224 | }, |
225 | { | ||
226 | .matches = { | ||
227 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
228 | DMI_MATCH(DMI_PRODUCT_NAME, "Qosmio X75-A"), | ||
229 | }, | ||
230 | }, | ||
225 | {} | 231 | {} |
226 | }; | 232 | }; |
227 | 233 | ||
@@ -229,6 +235,7 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = { | |||
229 | { KE_KEY, 0x157, { KEY_MUTE } }, | 235 | { KE_KEY, 0x157, { KEY_MUTE } }, |
230 | { KE_KEY, 0x102, { KEY_ZOOMOUT } }, | 236 | { KE_KEY, 0x102, { KEY_ZOOMOUT } }, |
231 | { KE_KEY, 0x103, { KEY_ZOOMIN } }, | 237 | { KE_KEY, 0x103, { KEY_ZOOMIN } }, |
238 | { KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } }, | ||
232 | { KE_KEY, 0x139, { KEY_ZOOMRESET } }, | 239 | { KE_KEY, 0x139, { KEY_ZOOMRESET } }, |
233 | { KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } }, | 240 | { KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } }, |
234 | { KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } }, | 241 | { KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } }, |
@@ -872,7 +879,9 @@ static int lcd_proc_open(struct inode *inode, struct file *file) | |||
872 | 879 | ||
873 | static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) | 880 | static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) |
874 | { | 881 | { |
875 | u32 hci_result; | 882 | u32 in[HCI_WORDS] = { HCI_SET, HCI_LCD_BRIGHTNESS, 0, 0, 0, 0 }; |
883 | u32 out[HCI_WORDS]; | ||
884 | acpi_status status; | ||
876 | 885 | ||
877 | if (dev->tr_backlight_supported) { | 886 | if (dev->tr_backlight_supported) { |
878 | bool enable = !value; | 887 | bool enable = !value; |
@@ -883,9 +892,20 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) | |||
883 | value--; | 892 | value--; |
884 | } | 893 | } |
885 | 894 | ||
886 | value = value << HCI_LCD_BRIGHTNESS_SHIFT; | 895 | in[2] = value << HCI_LCD_BRIGHTNESS_SHIFT; |
887 | hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result); | 896 | status = hci_raw(dev, in, out); |
888 | return hci_result == HCI_SUCCESS ? 0 : -EIO; | 897 | if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) { |
898 | pr_err("ACPI call to set brightness failed"); | ||
899 | return -EIO; | ||
900 | } | ||
901 | /* Extra check for "incomplete" backlight method, where the AML code | ||
902 | * doesn't check for HCI_SET or HCI_GET and returns HCI_SUCCESS, | ||
903 | * the actual brightness, and in some cases the max brightness. | ||
904 | */ | ||
905 | if (out[2] > 0 || out[3] == 0xE000) | ||
906 | return -ENODEV; | ||
907 | |||
908 | return out[0] == HCI_SUCCESS ? 0 : -EIO; | ||
889 | } | 909 | } |
890 | 910 | ||
891 | static int set_lcd_status(struct backlight_device *bd) | 911 | static int set_lcd_status(struct backlight_device *bd) |
diff --git a/drivers/platform/x86/toshiba_haps.c b/drivers/platform/x86/toshiba_haps.c new file mode 100644 index 000000000000..65300b6a84b9 --- /dev/null +++ b/drivers/platform/x86/toshiba_haps.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /* | ||
2 | * Toshiba HDD Active Protection Sensor (HAPS) driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Azael Avalos <coproscefalo@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/acpi.h> | ||
25 | |||
26 | MODULE_AUTHOR("Azael Avalos <coproscefalo@gmail.com>"); | ||
27 | MODULE_DESCRIPTION("Toshiba HDD Active Protection Sensor"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | struct toshiba_haps_dev { | ||
31 | struct acpi_device *acpi_dev; | ||
32 | |||
33 | int protection_level; | ||
34 | }; | ||
35 | |||
36 | static struct toshiba_haps_dev *toshiba_haps; | ||
37 | |||
38 | /* HAPS functions */ | ||
39 | static int toshiba_haps_reset_protection(acpi_handle handle) | ||
40 | { | ||
41 | acpi_status status; | ||
42 | |||
43 | status = acpi_evaluate_object(handle, "RSSS", NULL, NULL); | ||
44 | if (ACPI_FAILURE(status)) { | ||
45 | pr_err("Unable to reset the HDD protection\n"); | ||
46 | return -EIO; | ||
47 | } | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static int toshiba_haps_protection_level(acpi_handle handle, int level) | ||
53 | { | ||
54 | acpi_status status; | ||
55 | |||
56 | status = acpi_execute_simple_method(handle, "PTLV", level); | ||
57 | if (ACPI_FAILURE(status)) { | ||
58 | pr_err("Error while setting the protection level\n"); | ||
59 | return -EIO; | ||
60 | } | ||
61 | |||
62 | pr_info("HDD protection level set to: %d\n", level); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | /* sysfs files */ | ||
68 | static ssize_t protection_level_show(struct device *dev, | ||
69 | struct device_attribute *attr, char *buf) | ||
70 | { | ||
71 | struct toshiba_haps_dev *haps = dev_get_drvdata(dev); | ||
72 | |||
73 | return sprintf(buf, "%i\n", haps->protection_level); | ||
74 | } | ||
75 | |||
76 | static ssize_t protection_level_store(struct device *dev, | ||
77 | struct device_attribute *attr, | ||
78 | const char *buf, size_t count) | ||
79 | { | ||
80 | struct toshiba_haps_dev *haps = dev_get_drvdata(dev); | ||
81 | int level, ret; | ||
82 | |||
83 | if (sscanf(buf, "%d", &level) != 1 || level < 0 || level > 3) | ||
84 | return -EINVAL; | ||
85 | |||
86 | /* Set the sensor level. | ||
87 | * Acceptable levels are: | ||
88 | * 0 - Disabled | 1 - Low | 2 - Medium | 3 - High | ||
89 | */ | ||
90 | ret = toshiba_haps_protection_level(haps->acpi_dev->handle, level); | ||
91 | if (ret != 0) | ||
92 | return ret; | ||
93 | |||
94 | haps->protection_level = level; | ||
95 | |||
96 | return count; | ||
97 | } | ||
98 | |||
99 | static ssize_t reset_protection_store(struct device *dev, | ||
100 | struct device_attribute *attr, | ||
101 | const char *buf, size_t count) | ||
102 | { | ||
103 | struct toshiba_haps_dev *haps = dev_get_drvdata(dev); | ||
104 | int reset, ret; | ||
105 | |||
106 | if (sscanf(buf, "%d", &reset) != 1 || reset != 1) | ||
107 | return -EINVAL; | ||
108 | |||
109 | /* Reset the protection interface */ | ||
110 | ret = toshiba_haps_reset_protection(haps->acpi_dev->handle); | ||
111 | if (ret != 0) | ||
112 | return ret; | ||
113 | |||
114 | return count; | ||
115 | } | ||
116 | |||
117 | static DEVICE_ATTR(protection_level, S_IRUGO | S_IWUSR, | ||
118 | protection_level_show, protection_level_store); | ||
119 | static DEVICE_ATTR(reset_protection, S_IWUSR, NULL, reset_protection_store); | ||
120 | |||
121 | static struct attribute *haps_attributes[] = { | ||
122 | &dev_attr_protection_level.attr, | ||
123 | &dev_attr_reset_protection.attr, | ||
124 | NULL, | ||
125 | }; | ||
126 | |||
127 | static struct attribute_group haps_attr_group = { | ||
128 | .attrs = haps_attributes, | ||
129 | }; | ||
130 | |||
131 | /* | ||
132 | * ACPI stuff | ||
133 | */ | ||
134 | static void toshiba_haps_notify(struct acpi_device *device, u32 event) | ||
135 | { | ||
136 | pr_info("Received event: 0x%x", event); | ||
137 | |||
138 | acpi_bus_generate_netlink_event(device->pnp.device_class, | ||
139 | dev_name(&device->dev), | ||
140 | event, 0); | ||
141 | } | ||
142 | |||
143 | static int toshiba_haps_remove(struct acpi_device *device) | ||
144 | { | ||
145 | sysfs_remove_group(&device->dev.kobj, &haps_attr_group); | ||
146 | |||
147 | if (toshiba_haps) | ||
148 | toshiba_haps = NULL; | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | /* Helper function */ | ||
154 | static int toshiba_haps_available(acpi_handle handle) | ||
155 | { | ||
156 | acpi_status status; | ||
157 | u64 hdd_present; | ||
158 | |||
159 | /* | ||
160 | * A non existent device as well as having (only) | ||
161 | * Solid State Drives can cause the call to fail. | ||
162 | */ | ||
163 | status = acpi_evaluate_integer(handle, "_STA", NULL, | ||
164 | &hdd_present); | ||
165 | if (ACPI_FAILURE(status) || !hdd_present) { | ||
166 | pr_info("HDD protection not available or using SSD\n"); | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | return 1; | ||
171 | } | ||
172 | |||
173 | static int toshiba_haps_add(struct acpi_device *acpi_dev) | ||
174 | { | ||
175 | struct toshiba_haps_dev *haps; | ||
176 | int ret; | ||
177 | |||
178 | if (toshiba_haps) | ||
179 | return -EBUSY; | ||
180 | |||
181 | if (!toshiba_haps_available(acpi_dev->handle)) | ||
182 | return -ENODEV; | ||
183 | |||
184 | pr_info("Toshiba HDD Active Protection Sensor device\n"); | ||
185 | |||
186 | haps = kzalloc(sizeof(struct toshiba_haps_dev), GFP_KERNEL); | ||
187 | if (!haps) | ||
188 | return -ENOMEM; | ||
189 | |||
190 | haps->acpi_dev = acpi_dev; | ||
191 | haps->protection_level = 2; | ||
192 | acpi_dev->driver_data = haps; | ||
193 | dev_set_drvdata(&acpi_dev->dev, haps); | ||
194 | |||
195 | /* Set the protection level, currently at level 2 (Medium) */ | ||
196 | ret = toshiba_haps_protection_level(acpi_dev->handle, 2); | ||
197 | if (ret != 0) | ||
198 | return ret; | ||
199 | |||
200 | ret = sysfs_create_group(&acpi_dev->dev.kobj, &haps_attr_group); | ||
201 | if (ret) | ||
202 | return ret; | ||
203 | |||
204 | toshiba_haps = haps; | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | #ifdef CONFIG_PM_SLEEP | ||
210 | static int toshiba_haps_suspend(struct device *device) | ||
211 | { | ||
212 | struct toshiba_haps_dev *haps; | ||
213 | int ret; | ||
214 | |||
215 | haps = acpi_driver_data(to_acpi_device(device)); | ||
216 | |||
217 | /* Deactivate the protection on suspend */ | ||
218 | ret = toshiba_haps_protection_level(haps->acpi_dev->handle, 0); | ||
219 | |||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int toshiba_haps_resume(struct device *device) | ||
224 | { | ||
225 | struct toshiba_haps_dev *haps; | ||
226 | int ret; | ||
227 | |||
228 | haps = acpi_driver_data(to_acpi_device(device)); | ||
229 | |||
230 | /* Set the stored protection level */ | ||
231 | ret = toshiba_haps_protection_level(haps->acpi_dev->handle, | ||
232 | haps->protection_level); | ||
233 | |||
234 | /* Reset the protection on resume */ | ||
235 | ret = toshiba_haps_reset_protection(haps->acpi_dev->handle); | ||
236 | if (ret != 0) | ||
237 | return ret; | ||
238 | |||
239 | return ret; | ||
240 | } | ||
241 | #endif | ||
242 | |||
243 | static SIMPLE_DEV_PM_OPS(toshiba_haps_pm, | ||
244 | toshiba_haps_suspend, toshiba_haps_resume); | ||
245 | |||
246 | static const struct acpi_device_id haps_device_ids[] = { | ||
247 | {"TOS620A", 0}, | ||
248 | {"", 0}, | ||
249 | }; | ||
250 | MODULE_DEVICE_TABLE(acpi, haps_device_ids); | ||
251 | |||
252 | static struct acpi_driver toshiba_haps_driver = { | ||
253 | .name = "Toshiba HAPS", | ||
254 | .owner = THIS_MODULE, | ||
255 | .ids = haps_device_ids, | ||
256 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
257 | .ops = { | ||
258 | .add = toshiba_haps_add, | ||
259 | .remove = toshiba_haps_remove, | ||
260 | .notify = toshiba_haps_notify, | ||
261 | }, | ||
262 | .drv.pm = &toshiba_haps_pm, | ||
263 | }; | ||
264 | |||
265 | module_acpi_driver(toshiba_haps_driver); | ||
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 43d13295e63d..737e56d46f61 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -256,10 +256,6 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) | |||
256 | block = &wblock->gblock; | 256 | block = &wblock->gblock; |
257 | handle = wblock->handle; | 257 | handle = wblock->handle; |
258 | 258 | ||
259 | if (!block) | ||
260 | return AE_NOT_EXIST; | ||
261 | |||
262 | |||
263 | snprintf(method, 5, "WE%02X", block->notify_id); | 259 | snprintf(method, 5, "WE%02X", block->notify_id); |
264 | status = acpi_execute_simple_method(handle, method, enable); | 260 | status = acpi_execute_simple_method(handle, method, enable); |
265 | 261 | ||
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 4b66bf09ee55..d2c35920ff08 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
@@ -606,6 +606,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
606 | unsigned int best = 0; | 606 | unsigned int best = 0; |
607 | struct pwm_lookup *p; | 607 | struct pwm_lookup *p; |
608 | unsigned int match; | 608 | unsigned int match; |
609 | unsigned int period; | ||
610 | enum pwm_polarity polarity; | ||
609 | 611 | ||
610 | /* look up via DT first */ | 612 | /* look up via DT first */ |
611 | if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) | 613 | if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) |
@@ -653,6 +655,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
653 | if (match > best) { | 655 | if (match > best) { |
654 | chip = pwmchip_find_by_name(p->provider); | 656 | chip = pwmchip_find_by_name(p->provider); |
655 | index = p->index; | 657 | index = p->index; |
658 | period = p->period; | ||
659 | polarity = p->polarity; | ||
656 | 660 | ||
657 | if (match != 3) | 661 | if (match != 3) |
658 | best = match; | 662 | best = match; |
@@ -668,8 +672,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
668 | if (IS_ERR(pwm)) | 672 | if (IS_ERR(pwm)) |
669 | return pwm; | 673 | return pwm; |
670 | 674 | ||
671 | pwm_set_period(pwm, p->period); | 675 | pwm_set_period(pwm, period); |
672 | pwm_set_polarity(pwm, p->polarity); | 676 | pwm_set_polarity(pwm, polarity); |
673 | 677 | ||
674 | 678 | ||
675 | return pwm; | 679 | return pwm; |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index f9f3a1224dfa..ea025e4806b6 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -2097,7 +2097,7 @@ static void iscsi_check_transport_timeouts(unsigned long data) | |||
2097 | conn->ping_timeout, conn->recv_timeout, | 2097 | conn->ping_timeout, conn->recv_timeout, |
2098 | last_recv, conn->last_ping, jiffies); | 2098 | last_recv, conn->last_ping, jiffies); |
2099 | spin_unlock(&session->frwd_lock); | 2099 | spin_unlock(&session->frwd_lock); |
2100 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 2100 | iscsi_conn_failure(conn, ISCSI_ERR_NOP_TIMEDOUT); |
2101 | return; | 2101 | return; |
2102 | } | 2102 | } |
2103 | 2103 | ||
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index d3a08aea0948..7abbf284da1a 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c | |||
@@ -526,18 +526,19 @@ static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha) | |||
526 | { | 526 | { |
527 | struct pm8001_ioctl_payload *payload; | 527 | struct pm8001_ioctl_payload *payload; |
528 | DECLARE_COMPLETION_ONSTACK(completion); | 528 | DECLARE_COMPLETION_ONSTACK(completion); |
529 | u8 *ioctlbuffer = NULL; | 529 | u8 *ioctlbuffer; |
530 | u32 length = 0; | 530 | u32 ret; |
531 | u32 ret = 0; | 531 | u32 length = 1024 * 5 + sizeof(*payload) - 1; |
532 | |||
533 | if (pm8001_ha->fw_image->size > 4096) { | ||
534 | pm8001_ha->fw_status = FAIL_FILE_SIZE; | ||
535 | return -EFAULT; | ||
536 | } | ||
532 | 537 | ||
533 | length = 1024 * 5 + sizeof(*payload) - 1; | ||
534 | ioctlbuffer = kzalloc(length, GFP_KERNEL); | 538 | ioctlbuffer = kzalloc(length, GFP_KERNEL); |
535 | if (!ioctlbuffer) | 539 | if (!ioctlbuffer) { |
540 | pm8001_ha->fw_status = FAIL_OUT_MEMORY; | ||
536 | return -ENOMEM; | 541 | return -ENOMEM; |
537 | if ((pm8001_ha->fw_image->size <= 0) || | ||
538 | (pm8001_ha->fw_image->size > 4096)) { | ||
539 | ret = FAIL_FILE_SIZE; | ||
540 | goto out; | ||
541 | } | 542 | } |
542 | payload = (struct pm8001_ioctl_payload *)ioctlbuffer; | 543 | payload = (struct pm8001_ioctl_payload *)ioctlbuffer; |
543 | memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data, | 544 | memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data, |
@@ -547,6 +548,10 @@ static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha) | |||
547 | payload->minor_function = 0x1; | 548 | payload->minor_function = 0x1; |
548 | pm8001_ha->nvmd_completion = &completion; | 549 | pm8001_ha->nvmd_completion = &completion; |
549 | ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload); | 550 | ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload); |
551 | if (ret) { | ||
552 | pm8001_ha->fw_status = FAIL_OUT_MEMORY; | ||
553 | goto out; | ||
554 | } | ||
550 | wait_for_completion(&completion); | 555 | wait_for_completion(&completion); |
551 | out: | 556 | out: |
552 | kfree(ioctlbuffer); | 557 | kfree(ioctlbuffer); |
@@ -557,35 +562,31 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha) | |||
557 | { | 562 | { |
558 | struct pm8001_ioctl_payload *payload; | 563 | struct pm8001_ioctl_payload *payload; |
559 | DECLARE_COMPLETION_ONSTACK(completion); | 564 | DECLARE_COMPLETION_ONSTACK(completion); |
560 | u8 *ioctlbuffer = NULL; | 565 | u8 *ioctlbuffer; |
561 | u32 length = 0; | ||
562 | struct fw_control_info *fwControl; | 566 | struct fw_control_info *fwControl; |
563 | u32 loopNumber, loopcount = 0; | ||
564 | u32 sizeRead = 0; | ||
565 | u32 partitionSize, partitionSizeTmp; | 567 | u32 partitionSize, partitionSizeTmp; |
566 | u32 ret = 0; | 568 | u32 loopNumber, loopcount; |
567 | u32 partitionNumber = 0; | ||
568 | struct pm8001_fw_image_header *image_hdr; | 569 | struct pm8001_fw_image_header *image_hdr; |
570 | u32 sizeRead = 0; | ||
571 | u32 ret = 0; | ||
572 | u32 length = 1024 * 16 + sizeof(*payload) - 1; | ||
569 | 573 | ||
570 | length = 1024 * 16 + sizeof(*payload) - 1; | 574 | if (pm8001_ha->fw_image->size < 28) { |
575 | pm8001_ha->fw_status = FAIL_FILE_SIZE; | ||
576 | return -EFAULT; | ||
577 | } | ||
571 | ioctlbuffer = kzalloc(length, GFP_KERNEL); | 578 | ioctlbuffer = kzalloc(length, GFP_KERNEL); |
572 | image_hdr = (struct pm8001_fw_image_header *)pm8001_ha->fw_image->data; | 579 | if (!ioctlbuffer) { |
573 | if (!ioctlbuffer) | 580 | pm8001_ha->fw_status = FAIL_OUT_MEMORY; |
574 | return -ENOMEM; | 581 | return -ENOMEM; |
575 | if (pm8001_ha->fw_image->size < 28) { | ||
576 | ret = FAIL_FILE_SIZE; | ||
577 | goto out; | ||
578 | } | 582 | } |
579 | 583 | image_hdr = (struct pm8001_fw_image_header *)pm8001_ha->fw_image->data; | |
580 | while (sizeRead < pm8001_ha->fw_image->size) { | 584 | while (sizeRead < pm8001_ha->fw_image->size) { |
581 | partitionSizeTmp = | 585 | partitionSizeTmp = |
582 | *(u32 *)((u8 *)&image_hdr->image_length + sizeRead); | 586 | *(u32 *)((u8 *)&image_hdr->image_length + sizeRead); |
583 | partitionSize = be32_to_cpu(partitionSizeTmp); | 587 | partitionSize = be32_to_cpu(partitionSizeTmp); |
584 | loopcount = (partitionSize + HEADER_LEN)/IOCTL_BUF_SIZE; | 588 | loopcount = DIV_ROUND_UP(partitionSize + HEADER_LEN, |
585 | if (loopcount % IOCTL_BUF_SIZE) | 589 | IOCTL_BUF_SIZE); |
586 | loopcount++; | ||
587 | if (loopcount == 0) | ||
588 | loopcount++; | ||
589 | for (loopNumber = 0; loopNumber < loopcount; loopNumber++) { | 590 | for (loopNumber = 0; loopNumber < loopcount; loopNumber++) { |
590 | payload = (struct pm8001_ioctl_payload *)ioctlbuffer; | 591 | payload = (struct pm8001_ioctl_payload *)ioctlbuffer; |
591 | payload->length = 1024*16; | 592 | payload->length = 1024*16; |
@@ -617,18 +618,18 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha) | |||
617 | 618 | ||
618 | pm8001_ha->nvmd_completion = &completion; | 619 | pm8001_ha->nvmd_completion = &completion; |
619 | ret = PM8001_CHIP_DISP->fw_flash_update_req(pm8001_ha, payload); | 620 | ret = PM8001_CHIP_DISP->fw_flash_update_req(pm8001_ha, payload); |
620 | if (ret) | 621 | if (ret) { |
621 | break; | 622 | pm8001_ha->fw_status = FAIL_OUT_MEMORY; |
623 | goto out; | ||
624 | } | ||
622 | wait_for_completion(&completion); | 625 | wait_for_completion(&completion); |
623 | if (fwControl->retcode > FLASH_UPDATE_IN_PROGRESS) { | 626 | if (fwControl->retcode > FLASH_UPDATE_IN_PROGRESS) { |
624 | ret = fwControl->retcode; | 627 | pm8001_ha->fw_status = fwControl->retcode; |
625 | break; | 628 | ret = -EFAULT; |
629 | goto out; | ||
630 | } | ||
626 | } | 631 | } |
627 | } | 632 | } |
628 | if (ret) | ||
629 | break; | ||
630 | partitionNumber++; | ||
631 | } | ||
632 | out: | 633 | out: |
633 | kfree(ioctlbuffer); | 634 | kfree(ioctlbuffer); |
634 | return ret; | 635 | return ret; |
@@ -643,22 +644,29 @@ static ssize_t pm8001_store_update_fw(struct device *cdev, | |||
643 | char *cmd_ptr, *filename_ptr; | 644 | char *cmd_ptr, *filename_ptr; |
644 | int res, i; | 645 | int res, i; |
645 | int flash_command = FLASH_CMD_NONE; | 646 | int flash_command = FLASH_CMD_NONE; |
646 | int err = 0; | 647 | int ret; |
648 | |||
647 | if (!capable(CAP_SYS_ADMIN)) | 649 | if (!capable(CAP_SYS_ADMIN)) |
648 | return -EACCES; | 650 | return -EACCES; |
649 | 651 | ||
650 | cmd_ptr = kzalloc(count*2, GFP_KERNEL); | 652 | /* this test protects us from running two flash processes at once, |
653 | * so we should start with this test */ | ||
654 | if (pm8001_ha->fw_status == FLASH_IN_PROGRESS) | ||
655 | return -EINPROGRESS; | ||
656 | pm8001_ha->fw_status = FLASH_IN_PROGRESS; | ||
651 | 657 | ||
658 | cmd_ptr = kzalloc(count*2, GFP_KERNEL); | ||
652 | if (!cmd_ptr) { | 659 | if (!cmd_ptr) { |
653 | err = FAIL_OUT_MEMORY; | 660 | pm8001_ha->fw_status = FAIL_OUT_MEMORY; |
654 | goto out; | 661 | return -ENOMEM; |
655 | } | 662 | } |
656 | 663 | ||
657 | filename_ptr = cmd_ptr + count; | 664 | filename_ptr = cmd_ptr + count; |
658 | res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr); | 665 | res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr); |
659 | if (res != 2) { | 666 | if (res != 2) { |
660 | err = FAIL_PARAMETERS; | 667 | pm8001_ha->fw_status = FAIL_PARAMETERS; |
661 | goto out1; | 668 | ret = -EINVAL; |
669 | goto out; | ||
662 | } | 670 | } |
663 | 671 | ||
664 | for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) { | 672 | for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) { |
@@ -669,50 +677,38 @@ static ssize_t pm8001_store_update_fw(struct device *cdev, | |||
669 | } | 677 | } |
670 | } | 678 | } |
671 | if (flash_command == FLASH_CMD_NONE) { | 679 | if (flash_command == FLASH_CMD_NONE) { |
672 | err = FAIL_PARAMETERS; | 680 | pm8001_ha->fw_status = FAIL_PARAMETERS; |
673 | goto out1; | 681 | ret = -EINVAL; |
682 | goto out; | ||
674 | } | 683 | } |
675 | 684 | ||
676 | if (pm8001_ha->fw_status == FLASH_IN_PROGRESS) { | 685 | ret = request_firmware(&pm8001_ha->fw_image, |
677 | err = FLASH_IN_PROGRESS; | ||
678 | goto out1; | ||
679 | } | ||
680 | err = request_firmware(&pm8001_ha->fw_image, | ||
681 | filename_ptr, | 686 | filename_ptr, |
682 | pm8001_ha->dev); | 687 | pm8001_ha->dev); |
683 | 688 | ||
684 | if (err) { | 689 | if (ret) { |
685 | PM8001_FAIL_DBG(pm8001_ha, | 690 | PM8001_FAIL_DBG(pm8001_ha, |
686 | pm8001_printk("Failed to load firmware image file %s," | 691 | pm8001_printk( |
687 | " error %d\n", filename_ptr, err)); | 692 | "Failed to load firmware image file %s, error %d\n", |
688 | err = FAIL_OPEN_BIOS_FILE; | 693 | filename_ptr, ret)); |
689 | goto out1; | 694 | pm8001_ha->fw_status = FAIL_OPEN_BIOS_FILE; |
695 | goto out; | ||
690 | } | 696 | } |
691 | 697 | ||
692 | switch (flash_command) { | 698 | if (FLASH_CMD_UPDATE == flash_command) |
693 | case FLASH_CMD_UPDATE: | 699 | ret = pm8001_update_flash(pm8001_ha); |
694 | pm8001_ha->fw_status = FLASH_IN_PROGRESS; | 700 | else |
695 | err = pm8001_update_flash(pm8001_ha); | 701 | ret = pm8001_set_nvmd(pm8001_ha); |
696 | break; | 702 | |
697 | case FLASH_CMD_SET_NVMD: | ||
698 | pm8001_ha->fw_status = FLASH_IN_PROGRESS; | ||
699 | err = pm8001_set_nvmd(pm8001_ha); | ||
700 | break; | ||
701 | default: | ||
702 | pm8001_ha->fw_status = FAIL_PARAMETERS; | ||
703 | err = FAIL_PARAMETERS; | ||
704 | break; | ||
705 | } | ||
706 | release_firmware(pm8001_ha->fw_image); | 703 | release_firmware(pm8001_ha->fw_image); |
707 | out1: | ||
708 | kfree(cmd_ptr); | ||
709 | out: | 704 | out: |
710 | pm8001_ha->fw_status = err; | 705 | kfree(cmd_ptr); |
711 | 706 | ||
712 | if (!err) | 707 | if (ret) |
713 | return count; | 708 | return ret; |
714 | else | 709 | |
715 | return -err; | 710 | pm8001_ha->fw_status = FLASH_OK; |
711 | return count; | ||
716 | } | 712 | } |
717 | 713 | ||
718 | static ssize_t pm8001_show_update_fw(struct device *cdev, | 714 | static ssize_t pm8001_show_update_fw(struct device *cdev, |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 173831016f5f..dd12c6fe57a6 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
@@ -4824,7 +4824,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, | |||
4824 | rc = pm8001_tag_alloc(pm8001_ha, &tag); | 4824 | rc = pm8001_tag_alloc(pm8001_ha, &tag); |
4825 | if (rc) { | 4825 | if (rc) { |
4826 | kfree(fw_control_context); | 4826 | kfree(fw_control_context); |
4827 | return rc; | 4827 | return -EBUSY; |
4828 | } | 4828 | } |
4829 | ccb = &pm8001_ha->ccb_info[tag]; | 4829 | ccb = &pm8001_ha->ccb_info[tag]; |
4830 | ccb->fw_control_context = fw_control_context; | 4830 | ccb->fw_control_context = fw_control_context; |
@@ -4946,7 +4946,7 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, | |||
4946 | rc = pm8001_tag_alloc(pm8001_ha, &tag); | 4946 | rc = pm8001_tag_alloc(pm8001_ha, &tag); |
4947 | if (rc) { | 4947 | if (rc) { |
4948 | kfree(fw_control_context); | 4948 | kfree(fw_control_context); |
4949 | return rc; | 4949 | return -EBUSY; |
4950 | } | 4950 | } |
4951 | ccb = &pm8001_ha->ccb_info[tag]; | 4951 | ccb = &pm8001_ha->ccb_info[tag]; |
4952 | ccb->fw_control_context = fw_control_context; | 4952 | ccb->fw_control_context = fw_control_context; |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index e49623a897a7..666bf5af06e2 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
@@ -748,34 +748,35 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) | |||
748 | sizeof(pm8001_ha->msix_entries[0]); | 748 | sizeof(pm8001_ha->msix_entries[0]); |
749 | for (i = 0; i < max_entry ; i++) | 749 | for (i = 0; i < max_entry ; i++) |
750 | pm8001_ha->msix_entries[i].entry = i; | 750 | pm8001_ha->msix_entries[i].entry = i; |
751 | rc = pci_enable_msix(pm8001_ha->pdev, pm8001_ha->msix_entries, | 751 | rc = pci_enable_msix_exact(pm8001_ha->pdev, pm8001_ha->msix_entries, |
752 | number_of_intr); | 752 | number_of_intr); |
753 | pm8001_ha->number_of_intr = number_of_intr; | 753 | pm8001_ha->number_of_intr = number_of_intr; |
754 | if (!rc) { | 754 | if (rc) |
755 | PM8001_INIT_DBG(pm8001_ha, pm8001_printk( | 755 | return rc; |
756 | "pci_enable_msix request ret:%d no of intr %d\n", | ||
757 | rc, pm8001_ha->number_of_intr)); | ||
758 | 756 | ||
757 | PM8001_INIT_DBG(pm8001_ha, pm8001_printk( | ||
758 | "pci_enable_msix_exact request ret:%d no of intr %d\n", | ||
759 | rc, pm8001_ha->number_of_intr)); | ||
759 | 760 | ||
760 | for (i = 0; i < number_of_intr; i++) { | 761 | for (i = 0; i < number_of_intr; i++) { |
761 | snprintf(intr_drvname[i], sizeof(intr_drvname[0]), | 762 | snprintf(intr_drvname[i], sizeof(intr_drvname[0]), |
762 | DRV_NAME"%d", i); | 763 | DRV_NAME"%d", i); |
763 | pm8001_ha->irq_vector[i].irq_id = i; | 764 | pm8001_ha->irq_vector[i].irq_id = i; |
764 | pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; | 765 | pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; |
765 | 766 | ||
766 | rc = request_irq(pm8001_ha->msix_entries[i].vector, | 767 | rc = request_irq(pm8001_ha->msix_entries[i].vector, |
767 | pm8001_interrupt_handler_msix, flag, | 768 | pm8001_interrupt_handler_msix, flag, |
768 | intr_drvname[i], &(pm8001_ha->irq_vector[i])); | 769 | intr_drvname[i], &(pm8001_ha->irq_vector[i])); |
769 | if (rc) { | 770 | if (rc) { |
770 | for (j = 0; j < i; j++) | 771 | for (j = 0; j < i; j++) { |
771 | free_irq( | 772 | free_irq(pm8001_ha->msix_entries[j].vector, |
772 | pm8001_ha->msix_entries[j].vector, | ||
773 | &(pm8001_ha->irq_vector[i])); | 773 | &(pm8001_ha->irq_vector[i])); |
774 | pci_disable_msix(pm8001_ha->pdev); | ||
775 | break; | ||
776 | } | 774 | } |
775 | pci_disable_msix(pm8001_ha->pdev); | ||
776 | break; | ||
777 | } | 777 | } |
778 | } | 778 | } |
779 | |||
779 | return rc; | 780 | return rc; |
780 | } | 781 | } |
781 | #endif | 782 | #endif |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 6f12f859b11d..4180d6d9fe78 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -334,6 +334,12 @@ void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha) | |||
334 | /* Allocate memory for saving the template */ | 334 | /* Allocate memory for saving the template */ |
335 | md_tmp = dma_alloc_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size, | 335 | md_tmp = dma_alloc_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size, |
336 | &md_tmp_dma, GFP_KERNEL); | 336 | &md_tmp_dma, GFP_KERNEL); |
337 | if (!md_tmp) { | ||
338 | ql4_printk(KERN_INFO, ha, | ||
339 | "scsi%ld: Failed to allocate DMA memory\n", | ||
340 | ha->host_no); | ||
341 | return; | ||
342 | } | ||
337 | 343 | ||
338 | /* Request template */ | 344 | /* Request template */ |
339 | status = qla4xxx_get_minidump_template(ha, md_tmp_dma); | 345 | status = qla4xxx_get_minidump_template(ha, md_tmp_dma); |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index fdfae79924ac..c291fdff1b33 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -1620,8 +1620,8 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password, | |||
1620 | goto exit_get_chap; | 1620 | goto exit_get_chap; |
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | strncpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN); | 1623 | strlcpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN); |
1624 | strncpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN); | 1624 | strlcpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN); |
1625 | chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); | 1625 | chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); |
1626 | 1626 | ||
1627 | exit_get_chap: | 1627 | exit_get_chap: |
@@ -1663,8 +1663,8 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password, | |||
1663 | else | 1663 | else |
1664 | chap_table->flags |= BIT_7; /* local */ | 1664 | chap_table->flags |= BIT_7; /* local */ |
1665 | chap_table->secret_len = strlen(password); | 1665 | chap_table->secret_len = strlen(password); |
1666 | strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN); | 1666 | strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN - 1); |
1667 | strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN); | 1667 | strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN - 1); |
1668 | chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); | 1668 | chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); |
1669 | 1669 | ||
1670 | if (is_qla40XX(ha)) { | 1670 | if (is_qla40XX(ha)) { |
@@ -1742,8 +1742,8 @@ int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username, | |||
1742 | goto exit_unlock_uni_chap; | 1742 | goto exit_unlock_uni_chap; |
1743 | } | 1743 | } |
1744 | 1744 | ||
1745 | strncpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN); | 1745 | strlcpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN); |
1746 | strncpy(username, chap_table->name, MAX_CHAP_NAME_LEN); | 1746 | strlcpy(username, chap_table->name, MAX_CHAP_NAME_LEN); |
1747 | 1747 | ||
1748 | rval = QLA_SUCCESS; | 1748 | rval = QLA_SUCCESS; |
1749 | 1749 | ||
@@ -2295,7 +2295,7 @@ int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param) | |||
2295 | if (param == SET_DRVR_VERSION) { | 2295 | if (param == SET_DRVR_VERSION) { |
2296 | mbox_cmd[1] = SET_DRVR_VERSION; | 2296 | mbox_cmd[1] = SET_DRVR_VERSION; |
2297 | strncpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION, | 2297 | strncpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION, |
2298 | MAX_DRVR_VER_LEN); | 2298 | MAX_DRVR_VER_LEN - 1); |
2299 | } else { | 2299 | } else { |
2300 | ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n", | 2300 | ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n", |
2301 | __func__, param); | 2301 | __func__, param); |
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 9dbdb4be2d8f..7c3365864242 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c | |||
@@ -4221,7 +4221,7 @@ qla4_8xxx_enable_msix(struct scsi_qla_host *ha) | |||
4221 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) | 4221 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) |
4222 | entries[i].entry = qla4_8xxx_msix_entries[i].entry; | 4222 | entries[i].entry = qla4_8xxx_msix_entries[i].entry; |
4223 | 4223 | ||
4224 | ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries)); | 4224 | ret = pci_enable_msix_exact(ha->pdev, entries, ARRAY_SIZE(entries)); |
4225 | if (ret) { | 4225 | if (ret) { |
4226 | ql4_printk(KERN_WARNING, ha, | 4226 | ql4_printk(KERN_WARNING, ha, |
4227 | "MSI-X: Failed to enable support -- %d/%d\n", | 4227 | "MSI-X: Failed to enable support -- %d/%d\n", |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index c5d9564d455c..199fcf79a051 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -756,9 +756,9 @@ static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx, | |||
756 | continue; | 756 | continue; |
757 | 757 | ||
758 | chap_rec->chap_tbl_idx = i; | 758 | chap_rec->chap_tbl_idx = i; |
759 | strncpy(chap_rec->username, chap_table->name, | 759 | strlcpy(chap_rec->username, chap_table->name, |
760 | ISCSI_CHAP_AUTH_NAME_MAX_LEN); | 760 | ISCSI_CHAP_AUTH_NAME_MAX_LEN); |
761 | strncpy(chap_rec->password, chap_table->secret, | 761 | strlcpy(chap_rec->password, chap_table->secret, |
762 | QL4_CHAP_MAX_SECRET_LEN); | 762 | QL4_CHAP_MAX_SECRET_LEN); |
763 | chap_rec->password_length = chap_table->secret_len; | 763 | chap_rec->password_length = chap_table->secret_len; |
764 | 764 | ||
@@ -1050,6 +1050,7 @@ static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len) | |||
1050 | if (!ql_iscsi_stats) { | 1050 | if (!ql_iscsi_stats) { |
1051 | ql4_printk(KERN_ERR, ha, | 1051 | ql4_printk(KERN_ERR, ha, |
1052 | "Unable to allocate memory for iscsi stats\n"); | 1052 | "Unable to allocate memory for iscsi stats\n"); |
1053 | ret = -ENOMEM; | ||
1053 | goto exit_host_stats; | 1054 | goto exit_host_stats; |
1054 | } | 1055 | } |
1055 | 1056 | ||
@@ -1058,6 +1059,7 @@ static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len) | |||
1058 | if (ret != QLA_SUCCESS) { | 1059 | if (ret != QLA_SUCCESS) { |
1059 | ql4_printk(KERN_ERR, ha, | 1060 | ql4_printk(KERN_ERR, ha, |
1060 | "Unable to retrieve iscsi stats\n"); | 1061 | "Unable to retrieve iscsi stats\n"); |
1062 | ret = -EIO; | ||
1061 | goto exit_host_stats; | 1063 | goto exit_host_stats; |
1062 | } | 1064 | } |
1063 | host_stats->mactx_frames = le64_to_cpu(ql_iscsi_stats->mac_tx_frames); | 1065 | host_stats->mactx_frames = le64_to_cpu(ql_iscsi_stats->mac_tx_frames); |
@@ -6027,8 +6029,8 @@ static int qla4xxx_get_bidi_chap(struct scsi_qla_host *ha, char *username, | |||
6027 | if (!(chap_table->flags & BIT_6)) /* Not BIDI */ | 6029 | if (!(chap_table->flags & BIT_6)) /* Not BIDI */ |
6028 | continue; | 6030 | continue; |
6029 | 6031 | ||
6030 | strncpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN); | 6032 | strlcpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN); |
6031 | strncpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN); | 6033 | strlcpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN); |
6032 | ret = 0; | 6034 | ret = 0; |
6033 | break; | 6035 | break; |
6034 | } | 6036 | } |
@@ -6258,8 +6260,8 @@ static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry, | |||
6258 | 6260 | ||
6259 | tddb->tpgt = sess->tpgt; | 6261 | tddb->tpgt = sess->tpgt; |
6260 | tddb->port = conn->persistent_port; | 6262 | tddb->port = conn->persistent_port; |
6261 | strncpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE); | 6263 | strlcpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE); |
6262 | strncpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN); | 6264 | strlcpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN); |
6263 | } | 6265 | } |
6264 | 6266 | ||
6265 | static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry, | 6267 | static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry, |
@@ -7764,7 +7766,7 @@ static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess, | |||
7764 | goto exit_ddb_logout; | 7766 | goto exit_ddb_logout; |
7765 | } | 7767 | } |
7766 | 7768 | ||
7767 | strncpy(flash_tddb->iscsi_name, fnode_sess->targetname, | 7769 | strlcpy(flash_tddb->iscsi_name, fnode_sess->targetname, |
7768 | ISCSI_NAME_SIZE); | 7770 | ISCSI_NAME_SIZE); |
7769 | 7771 | ||
7770 | if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4)) | 7772 | if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4)) |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index df3306019a7e..d81f3cc43ff1 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -377,6 +377,10 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost) | |||
377 | pool->slab_flags |= SLAB_CACHE_DMA; | 377 | pool->slab_flags |= SLAB_CACHE_DMA; |
378 | pool->gfp_mask = __GFP_DMA; | 378 | pool->gfp_mask = __GFP_DMA; |
379 | } | 379 | } |
380 | |||
381 | if (hostt->cmd_size) | ||
382 | hostt->cmd_pool = pool; | ||
383 | |||
380 | return pool; | 384 | return pool; |
381 | } | 385 | } |
382 | 386 | ||
@@ -421,8 +425,10 @@ out: | |||
421 | out_free_slab: | 425 | out_free_slab: |
422 | kmem_cache_destroy(pool->cmd_slab); | 426 | kmem_cache_destroy(pool->cmd_slab); |
423 | out_free_pool: | 427 | out_free_pool: |
424 | if (hostt->cmd_size) | 428 | if (hostt->cmd_size) { |
425 | scsi_free_host_cmd_pool(pool); | 429 | scsi_free_host_cmd_pool(pool); |
430 | hostt->cmd_pool = NULL; | ||
431 | } | ||
426 | goto out; | 432 | goto out; |
427 | } | 433 | } |
428 | 434 | ||
@@ -444,8 +450,10 @@ static void scsi_put_host_cmd_pool(struct Scsi_Host *shost) | |||
444 | if (!--pool->users) { | 450 | if (!--pool->users) { |
445 | kmem_cache_destroy(pool->cmd_slab); | 451 | kmem_cache_destroy(pool->cmd_slab); |
446 | kmem_cache_destroy(pool->sense_slab); | 452 | kmem_cache_destroy(pool->sense_slab); |
447 | if (hostt->cmd_size) | 453 | if (hostt->cmd_size) { |
448 | scsi_free_host_cmd_pool(pool); | 454 | scsi_free_host_cmd_pool(pool); |
455 | hostt->cmd_pool = NULL; | ||
456 | } | ||
449 | } | 457 | } |
450 | mutex_unlock(&host_cmd_pool_mutex); | 458 | mutex_unlock(&host_cmd_pool_mutex); |
451 | } | 459 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9c44392b748f..ce62e8798cc8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1774,7 +1774,7 @@ static void scsi_request_fn(struct request_queue *q) | |||
1774 | blk_requeue_request(q, req); | 1774 | blk_requeue_request(q, req); |
1775 | atomic_dec(&sdev->device_busy); | 1775 | atomic_dec(&sdev->device_busy); |
1776 | out_delay: | 1776 | out_delay: |
1777 | if (atomic_read(&sdev->device_busy) && !scsi_device_blocked(sdev)) | 1777 | if (!atomic_read(&sdev->device_busy) && !scsi_device_blocked(sdev)) |
1778 | blk_delay_queue(q, SCSI_QUEUE_DELAY); | 1778 | blk_delay_queue(q, SCSI_QUEUE_DELAY); |
1779 | } | 1779 | } |
1780 | 1780 | ||
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index b481e62a12cc..67d43e35693d 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -3429,7 +3429,7 @@ iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
3429 | char *buf; | 3429 | char *buf; |
3430 | 3430 | ||
3431 | if (!transport->get_host_stats) | 3431 | if (!transport->get_host_stats) |
3432 | return -EINVAL; | 3432 | return -ENOSYS; |
3433 | 3433 | ||
3434 | priv = iscsi_if_transport_lookup(transport); | 3434 | priv = iscsi_if_transport_lookup(transport); |
3435 | if (!priv) | 3435 | if (!priv) |
@@ -3467,6 +3467,10 @@ iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
3467 | memset(buf, 0, host_stats_size); | 3467 | memset(buf, 0, host_stats_size); |
3468 | 3468 | ||
3469 | err = transport->get_host_stats(shost, buf, host_stats_size); | 3469 | err = transport->get_host_stats(shost, buf, host_stats_size); |
3470 | if (err) { | ||
3471 | kfree_skb(skbhost_stats); | ||
3472 | goto exit_host_stats; | ||
3473 | } | ||
3470 | 3474 | ||
3471 | actual_size = nlmsg_total_size(sizeof(*ev) + host_stats_size); | 3475 | actual_size = nlmsg_total_size(sizeof(*ev) + host_stats_size); |
3472 | skb_trim(skbhost_stats, NLMSG_ALIGN(actual_size)); | 3476 | skb_trim(skbhost_stats, NLMSG_ALIGN(actual_size)); |
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 4e76fe863fc4..d8dcf36aed11 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c | |||
@@ -1006,7 +1006,7 @@ static int port_detect \ | |||
1006 | sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue); | 1006 | sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue); |
1007 | 1007 | ||
1008 | if (sh[j]->max_id > 8 || sh[j]->max_lun > 8) | 1008 | if (sh[j]->max_id > 8 || sh[j]->max_lun > 8) |
1009 | printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", | 1009 | printk("%s: wide SCSI support enabled, max_id %u, max_lun %llu.\n", |
1010 | BN(j), sh[j]->max_id, sh[j]->max_lun); | 1010 | BN(j), sh[j]->max_id, sh[j]->max_lun); |
1011 | 1011 | ||
1012 | for (i = 0; i <= sh[j]->max_channel; i++) | 1012 | for (i = 0; i <= sh[j]->max_channel; i++) |
@@ -1285,7 +1285,7 @@ static int u14_34f_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct | |||
1285 | cpp->cpp_index = i; | 1285 | cpp->cpp_index = i; |
1286 | SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index; | 1286 | SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index; |
1287 | 1287 | ||
1288 | if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%llu.\n", | 1288 | if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%u.\n", |
1289 | BN(j), i, SCpnt->device->channel, SCpnt->device->id, | 1289 | BN(j), i, SCpnt->device->channel, SCpnt->device->id, |
1290 | (u8)SCpnt->device->lun); | 1290 | (u8)SCpnt->device->lun); |
1291 | 1291 | ||
@@ -192,7 +192,6 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | file->f_flags = O_RDWR; | 194 | file->f_flags = O_RDWR; |
195 | file->private_data = ctx; | ||
196 | return file; | 195 | return file; |
197 | } | 196 | } |
198 | 197 | ||
@@ -202,7 +201,7 @@ static struct dentry *aio_mount(struct file_system_type *fs_type, | |||
202 | static const struct dentry_operations ops = { | 201 | static const struct dentry_operations ops = { |
203 | .d_dname = simple_dname, | 202 | .d_dname = simple_dname, |
204 | }; | 203 | }; |
205 | return mount_pseudo(fs_type, "aio:", NULL, &ops, 0xa10a10a1); | 204 | return mount_pseudo(fs_type, "aio:", NULL, &ops, AIO_RING_MAGIC); |
206 | } | 205 | } |
207 | 206 | ||
208 | /* aio_setup | 207 | /* aio_setup |
@@ -556,8 +555,7 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) | |||
556 | struct aio_ring *ring; | 555 | struct aio_ring *ring; |
557 | 556 | ||
558 | spin_lock(&mm->ioctx_lock); | 557 | spin_lock(&mm->ioctx_lock); |
559 | rcu_read_lock(); | 558 | table = rcu_dereference_raw(mm->ioctx_table); |
560 | table = rcu_dereference(mm->ioctx_table); | ||
561 | 559 | ||
562 | while (1) { | 560 | while (1) { |
563 | if (table) | 561 | if (table) |
@@ -565,7 +563,6 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) | |||
565 | if (!table->table[i]) { | 563 | if (!table->table[i]) { |
566 | ctx->id = i; | 564 | ctx->id = i; |
567 | table->table[i] = ctx; | 565 | table->table[i] = ctx; |
568 | rcu_read_unlock(); | ||
569 | spin_unlock(&mm->ioctx_lock); | 566 | spin_unlock(&mm->ioctx_lock); |
570 | 567 | ||
571 | /* While kioctx setup is in progress, | 568 | /* While kioctx setup is in progress, |
@@ -579,8 +576,6 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) | |||
579 | } | 576 | } |
580 | 577 | ||
581 | new_nr = (table ? table->nr : 1) * 4; | 578 | new_nr = (table ? table->nr : 1) * 4; |
582 | |||
583 | rcu_read_unlock(); | ||
584 | spin_unlock(&mm->ioctx_lock); | 579 | spin_unlock(&mm->ioctx_lock); |
585 | 580 | ||
586 | table = kzalloc(sizeof(*table) + sizeof(struct kioctx *) * | 581 | table = kzalloc(sizeof(*table) + sizeof(struct kioctx *) * |
@@ -591,8 +586,7 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) | |||
591 | table->nr = new_nr; | 586 | table->nr = new_nr; |
592 | 587 | ||
593 | spin_lock(&mm->ioctx_lock); | 588 | spin_lock(&mm->ioctx_lock); |
594 | rcu_read_lock(); | 589 | old = rcu_dereference_raw(mm->ioctx_table); |
595 | old = rcu_dereference(mm->ioctx_table); | ||
596 | 590 | ||
597 | if (!old) { | 591 | if (!old) { |
598 | rcu_assign_pointer(mm->ioctx_table, table); | 592 | rcu_assign_pointer(mm->ioctx_table, table); |
@@ -739,12 +733,9 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, | |||
739 | 733 | ||
740 | 734 | ||
741 | spin_lock(&mm->ioctx_lock); | 735 | spin_lock(&mm->ioctx_lock); |
742 | rcu_read_lock(); | 736 | table = rcu_dereference_raw(mm->ioctx_table); |
743 | table = rcu_dereference(mm->ioctx_table); | ||
744 | |||
745 | WARN_ON(ctx != table->table[ctx->id]); | 737 | WARN_ON(ctx != table->table[ctx->id]); |
746 | table->table[ctx->id] = NULL; | 738 | table->table[ctx->id] = NULL; |
747 | rcu_read_unlock(); | ||
748 | spin_unlock(&mm->ioctx_lock); | 739 | spin_unlock(&mm->ioctx_lock); |
749 | 740 | ||
750 | /* percpu_ref_kill() will do the necessary call_rcu() */ | 741 | /* percpu_ref_kill() will do the necessary call_rcu() */ |
@@ -793,40 +784,30 @@ EXPORT_SYMBOL(wait_on_sync_kiocb); | |||
793 | */ | 784 | */ |
794 | void exit_aio(struct mm_struct *mm) | 785 | void exit_aio(struct mm_struct *mm) |
795 | { | 786 | { |
796 | struct kioctx_table *table; | 787 | struct kioctx_table *table = rcu_dereference_raw(mm->ioctx_table); |
797 | struct kioctx *ctx; | 788 | int i; |
798 | unsigned i = 0; | ||
799 | |||
800 | while (1) { | ||
801 | rcu_read_lock(); | ||
802 | table = rcu_dereference(mm->ioctx_table); | ||
803 | |||
804 | do { | ||
805 | if (!table || i >= table->nr) { | ||
806 | rcu_read_unlock(); | ||
807 | rcu_assign_pointer(mm->ioctx_table, NULL); | ||
808 | if (table) | ||
809 | kfree(table); | ||
810 | return; | ||
811 | } | ||
812 | 789 | ||
813 | ctx = table->table[i++]; | 790 | if (!table) |
814 | } while (!ctx); | 791 | return; |
815 | 792 | ||
816 | rcu_read_unlock(); | 793 | for (i = 0; i < table->nr; ++i) { |
794 | struct kioctx *ctx = table->table[i]; | ||
817 | 795 | ||
796 | if (!ctx) | ||
797 | continue; | ||
818 | /* | 798 | /* |
819 | * We don't need to bother with munmap() here - | 799 | * We don't need to bother with munmap() here - exit_mmap(mm) |
820 | * exit_mmap(mm) is coming and it'll unmap everything. | 800 | * is coming and it'll unmap everything. And we simply can't, |
821 | * Since aio_free_ring() uses non-zero ->mmap_size | 801 | * this is not necessarily our ->mm. |
822 | * as indicator that it needs to unmap the area, | 802 | * Since kill_ioctx() uses non-zero ->mmap_size as indicator |
823 | * just set it to 0; aio_free_ring() is the only | 803 | * that it needs to unmap the area, just set it to 0. |
824 | * place that uses ->mmap_size, so it's safe. | ||
825 | */ | 804 | */ |
826 | ctx->mmap_size = 0; | 805 | ctx->mmap_size = 0; |
827 | |||
828 | kill_ioctx(mm, ctx, NULL); | 806 | kill_ioctx(mm, ctx, NULL); |
829 | } | 807 | } |
808 | |||
809 | RCU_INIT_POINTER(mm->ioctx_table, NULL); | ||
810 | kfree(table); | ||
830 | } | 811 | } |
831 | 812 | ||
832 | static void put_reqs_available(struct kioctx *ctx, unsigned nr) | 813 | static void put_reqs_available(struct kioctx *ctx, unsigned nr) |
@@ -834,10 +815,8 @@ static void put_reqs_available(struct kioctx *ctx, unsigned nr) | |||
834 | struct kioctx_cpu *kcpu; | 815 | struct kioctx_cpu *kcpu; |
835 | unsigned long flags; | 816 | unsigned long flags; |
836 | 817 | ||
837 | preempt_disable(); | ||
838 | kcpu = this_cpu_ptr(ctx->cpu); | ||
839 | |||
840 | local_irq_save(flags); | 818 | local_irq_save(flags); |
819 | kcpu = this_cpu_ptr(ctx->cpu); | ||
841 | kcpu->reqs_available += nr; | 820 | kcpu->reqs_available += nr; |
842 | 821 | ||
843 | while (kcpu->reqs_available >= ctx->req_batch * 2) { | 822 | while (kcpu->reqs_available >= ctx->req_batch * 2) { |
@@ -846,7 +825,6 @@ static void put_reqs_available(struct kioctx *ctx, unsigned nr) | |||
846 | } | 825 | } |
847 | 826 | ||
848 | local_irq_restore(flags); | 827 | local_irq_restore(flags); |
849 | preempt_enable(); | ||
850 | } | 828 | } |
851 | 829 | ||
852 | static bool get_reqs_available(struct kioctx *ctx) | 830 | static bool get_reqs_available(struct kioctx *ctx) |
@@ -855,10 +833,8 @@ static bool get_reqs_available(struct kioctx *ctx) | |||
855 | bool ret = false; | 833 | bool ret = false; |
856 | unsigned long flags; | 834 | unsigned long flags; |
857 | 835 | ||
858 | preempt_disable(); | ||
859 | kcpu = this_cpu_ptr(ctx->cpu); | ||
860 | |||
861 | local_irq_save(flags); | 836 | local_irq_save(flags); |
837 | kcpu = this_cpu_ptr(ctx->cpu); | ||
862 | if (!kcpu->reqs_available) { | 838 | if (!kcpu->reqs_available) { |
863 | int old, avail = atomic_read(&ctx->reqs_available); | 839 | int old, avail = atomic_read(&ctx->reqs_available); |
864 | 840 | ||
@@ -878,7 +854,6 @@ static bool get_reqs_available(struct kioctx *ctx) | |||
878 | kcpu->reqs_available--; | 854 | kcpu->reqs_available--; |
879 | out: | 855 | out: |
880 | local_irq_restore(flags); | 856 | local_irq_restore(flags); |
881 | preempt_enable(); | ||
882 | return ret; | 857 | return ret; |
883 | } | 858 | } |
884 | 859 | ||
@@ -1047,7 +1022,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2) | |||
1047 | } | 1022 | } |
1048 | EXPORT_SYMBOL(aio_complete); | 1023 | EXPORT_SYMBOL(aio_complete); |
1049 | 1024 | ||
1050 | /* aio_read_events | 1025 | /* aio_read_events_ring |
1051 | * Pull an event off of the ioctx's event ring. Returns the number of | 1026 | * Pull an event off of the ioctx's event ring. Returns the number of |
1052 | * events fetched | 1027 | * events fetched |
1053 | */ | 1028 | */ |
@@ -1270,12 +1245,12 @@ static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb, | |||
1270 | if (compat) | 1245 | if (compat) |
1271 | ret = compat_rw_copy_check_uvector(rw, | 1246 | ret = compat_rw_copy_check_uvector(rw, |
1272 | (struct compat_iovec __user *)buf, | 1247 | (struct compat_iovec __user *)buf, |
1273 | *nr_segs, 1, *iovec, iovec); | 1248 | *nr_segs, UIO_FASTIOV, *iovec, iovec); |
1274 | else | 1249 | else |
1275 | #endif | 1250 | #endif |
1276 | ret = rw_copy_check_uvector(rw, | 1251 | ret = rw_copy_check_uvector(rw, |
1277 | (struct iovec __user *)buf, | 1252 | (struct iovec __user *)buf, |
1278 | *nr_segs, 1, *iovec, iovec); | 1253 | *nr_segs, UIO_FASTIOV, *iovec, iovec); |
1279 | if (ret < 0) | 1254 | if (ret < 0) |
1280 | return ret; | 1255 | return ret; |
1281 | 1256 | ||
@@ -1299,9 +1274,8 @@ static ssize_t aio_setup_single_vector(struct kiocb *kiocb, | |||
1299 | } | 1274 | } |
1300 | 1275 | ||
1301 | /* | 1276 | /* |
1302 | * aio_setup_iocb: | 1277 | * aio_run_iocb: |
1303 | * Performs the initial checks and aio retry method | 1278 | * Performs the initial checks and io submission. |
1304 | * setup for the kiocb at the time of io submission. | ||
1305 | */ | 1279 | */ |
1306 | static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, | 1280 | static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, |
1307 | char __user *buf, bool compat) | 1281 | char __user *buf, bool compat) |
@@ -1313,7 +1287,7 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, | |||
1313 | fmode_t mode; | 1287 | fmode_t mode; |
1314 | aio_rw_op *rw_op; | 1288 | aio_rw_op *rw_op; |
1315 | rw_iter_op *iter_op; | 1289 | rw_iter_op *iter_op; |
1316 | struct iovec inline_vec, *iovec = &inline_vec; | 1290 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
1317 | struct iov_iter iter; | 1291 | struct iov_iter iter; |
1318 | 1292 | ||
1319 | switch (opcode) { | 1293 | switch (opcode) { |
@@ -1348,7 +1322,7 @@ rw_common: | |||
1348 | if (!ret) | 1322 | if (!ret) |
1349 | ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); | 1323 | ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); |
1350 | if (ret < 0) { | 1324 | if (ret < 0) { |
1351 | if (iovec != &inline_vec) | 1325 | if (iovec != inline_vecs) |
1352 | kfree(iovec); | 1326 | kfree(iovec); |
1353 | return ret; | 1327 | return ret; |
1354 | } | 1328 | } |
@@ -1395,7 +1369,7 @@ rw_common: | |||
1395 | return -EINVAL; | 1369 | return -EINVAL; |
1396 | } | 1370 | } |
1397 | 1371 | ||
1398 | if (iovec != &inline_vec) | 1372 | if (iovec != inline_vecs) |
1399 | kfree(iovec); | 1373 | kfree(iovec); |
1400 | 1374 | ||
1401 | if (ret != -EIOCBQUEUED) { | 1375 | if (ret != -EIOCBQUEUED) { |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index e25564bfcb46..54a201dac7f9 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -276,9 +276,8 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
276 | } | 276 | } |
277 | if (ret > 0) | 277 | if (ret > 0) |
278 | goto next; | 278 | goto next; |
279 | ret = ulist_add_merge(parents, eb->start, | 279 | ret = ulist_add_merge_ptr(parents, eb->start, |
280 | (uintptr_t)eie, | 280 | eie, (void **)&old, GFP_NOFS); |
281 | (u64 *)&old, GFP_NOFS); | ||
282 | if (ret < 0) | 281 | if (ret < 0) |
283 | break; | 282 | break; |
284 | if (!ret && extent_item_pos) { | 283 | if (!ret && extent_item_pos) { |
@@ -1001,16 +1000,19 @@ again: | |||
1001 | ret = -EIO; | 1000 | ret = -EIO; |
1002 | goto out; | 1001 | goto out; |
1003 | } | 1002 | } |
1003 | btrfs_tree_read_lock(eb); | ||
1004 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | ||
1004 | ret = find_extent_in_eb(eb, bytenr, | 1005 | ret = find_extent_in_eb(eb, bytenr, |
1005 | *extent_item_pos, &eie); | 1006 | *extent_item_pos, &eie); |
1007 | btrfs_tree_read_unlock_blocking(eb); | ||
1006 | free_extent_buffer(eb); | 1008 | free_extent_buffer(eb); |
1007 | if (ret < 0) | 1009 | if (ret < 0) |
1008 | goto out; | 1010 | goto out; |
1009 | ref->inode_list = eie; | 1011 | ref->inode_list = eie; |
1010 | } | 1012 | } |
1011 | ret = ulist_add_merge(refs, ref->parent, | 1013 | ret = ulist_add_merge_ptr(refs, ref->parent, |
1012 | (uintptr_t)ref->inode_list, | 1014 | ref->inode_list, |
1013 | (u64 *)&eie, GFP_NOFS); | 1015 | (void **)&eie, GFP_NOFS); |
1014 | if (ret < 0) | 1016 | if (ret < 0) |
1015 | goto out; | 1017 | goto out; |
1016 | if (!ret && extent_item_pos) { | 1018 | if (!ret && extent_item_pos) { |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 4794923c410c..43527fd78825 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -84,12 +84,6 @@ struct btrfs_inode { | |||
84 | */ | 84 | */ |
85 | struct list_head delalloc_inodes; | 85 | struct list_head delalloc_inodes; |
86 | 86 | ||
87 | /* | ||
88 | * list for tracking inodes that must be sent to disk before a | ||
89 | * rename or truncate commit | ||
90 | */ | ||
91 | struct list_head ordered_operations; | ||
92 | |||
93 | /* node for the red-black tree that links inodes in subvolume root */ | 87 | /* node for the red-black tree that links inodes in subvolume root */ |
94 | struct rb_node rb_node; | 88 | struct rb_node rb_node; |
95 | 89 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index aeab453b8e24..44ee5d2e52a4 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -280,9 +280,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
280 | 280 | ||
281 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 281 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
282 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) | 282 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) |
283 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 283 | ret = btrfs_inc_ref(trans, root, cow, 1); |
284 | else | 284 | else |
285 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); | 285 | ret = btrfs_inc_ref(trans, root, cow, 0); |
286 | 286 | ||
287 | if (ret) | 287 | if (ret) |
288 | return ret; | 288 | return ret; |
@@ -1035,14 +1035,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
1035 | if ((owner == root->root_key.objectid || | 1035 | if ((owner == root->root_key.objectid || |
1036 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && | 1036 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && |
1037 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { | 1037 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { |
1038 | ret = btrfs_inc_ref(trans, root, buf, 1, 1); | 1038 | ret = btrfs_inc_ref(trans, root, buf, 1); |
1039 | BUG_ON(ret); /* -ENOMEM */ | 1039 | BUG_ON(ret); /* -ENOMEM */ |
1040 | 1040 | ||
1041 | if (root->root_key.objectid == | 1041 | if (root->root_key.objectid == |
1042 | BTRFS_TREE_RELOC_OBJECTID) { | 1042 | BTRFS_TREE_RELOC_OBJECTID) { |
1043 | ret = btrfs_dec_ref(trans, root, buf, 0, 1); | 1043 | ret = btrfs_dec_ref(trans, root, buf, 0); |
1044 | BUG_ON(ret); /* -ENOMEM */ | 1044 | BUG_ON(ret); /* -ENOMEM */ |
1045 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 1045 | ret = btrfs_inc_ref(trans, root, cow, 1); |
1046 | BUG_ON(ret); /* -ENOMEM */ | 1046 | BUG_ON(ret); /* -ENOMEM */ |
1047 | } | 1047 | } |
1048 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; | 1048 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; |
@@ -1050,9 +1050,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
1050 | 1050 | ||
1051 | if (root->root_key.objectid == | 1051 | if (root->root_key.objectid == |
1052 | BTRFS_TREE_RELOC_OBJECTID) | 1052 | BTRFS_TREE_RELOC_OBJECTID) |
1053 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 1053 | ret = btrfs_inc_ref(trans, root, cow, 1); |
1054 | else | 1054 | else |
1055 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); | 1055 | ret = btrfs_inc_ref(trans, root, cow, 0); |
1056 | BUG_ON(ret); /* -ENOMEM */ | 1056 | BUG_ON(ret); /* -ENOMEM */ |
1057 | } | 1057 | } |
1058 | if (new_flags != 0) { | 1058 | if (new_flags != 0) { |
@@ -1069,11 +1069,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
1069 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { | 1069 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { |
1070 | if (root->root_key.objectid == | 1070 | if (root->root_key.objectid == |
1071 | BTRFS_TREE_RELOC_OBJECTID) | 1071 | BTRFS_TREE_RELOC_OBJECTID) |
1072 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 1072 | ret = btrfs_inc_ref(trans, root, cow, 1); |
1073 | else | 1073 | else |
1074 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); | 1074 | ret = btrfs_inc_ref(trans, root, cow, 0); |
1075 | BUG_ON(ret); /* -ENOMEM */ | 1075 | BUG_ON(ret); /* -ENOMEM */ |
1076 | ret = btrfs_dec_ref(trans, root, buf, 1, 1); | 1076 | ret = btrfs_dec_ref(trans, root, buf, 1); |
1077 | BUG_ON(ret); /* -ENOMEM */ | 1077 | BUG_ON(ret); /* -ENOMEM */ |
1078 | } | 1078 | } |
1079 | clean_tree_block(trans, root, buf); | 1079 | clean_tree_block(trans, root, buf); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index be91397f4e92..8e29b614fe93 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -3326,9 +3326,9 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, | |||
3326 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, | 3326 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, |
3327 | struct btrfs_key *ins, int is_data, int delalloc); | 3327 | struct btrfs_key *ins, int is_data, int delalloc); |
3328 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3328 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3329 | struct extent_buffer *buf, int full_backref, int no_quota); | 3329 | struct extent_buffer *buf, int full_backref); |
3330 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3330 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3331 | struct extent_buffer *buf, int full_backref, int no_quota); | 3331 | struct extent_buffer *buf, int full_backref); |
3332 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, | 3332 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, |
3333 | struct btrfs_root *root, | 3333 | struct btrfs_root *root, |
3334 | u64 bytenr, u64 num_bytes, u64 flags, | 3334 | u64 bytenr, u64 num_bytes, u64 flags, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 08e65e9cf2aa..d0ed9e664f7d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -60,8 +60,6 @@ static void end_workqueue_fn(struct btrfs_work *work); | |||
60 | static void free_fs_root(struct btrfs_root *root); | 60 | static void free_fs_root(struct btrfs_root *root); |
61 | static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | 61 | static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, |
62 | int read_only); | 62 | int read_only); |
63 | static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t, | ||
64 | struct btrfs_root *root); | ||
65 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root); | 63 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root); |
66 | static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | 64 | static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, |
67 | struct btrfs_root *root); | 65 | struct btrfs_root *root); |
@@ -3829,34 +3827,6 @@ static void btrfs_error_commit_super(struct btrfs_root *root) | |||
3829 | btrfs_cleanup_transaction(root); | 3827 | btrfs_cleanup_transaction(root); |
3830 | } | 3828 | } |
3831 | 3829 | ||
3832 | static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t, | ||
3833 | struct btrfs_root *root) | ||
3834 | { | ||
3835 | struct btrfs_inode *btrfs_inode; | ||
3836 | struct list_head splice; | ||
3837 | |||
3838 | INIT_LIST_HEAD(&splice); | ||
3839 | |||
3840 | mutex_lock(&root->fs_info->ordered_operations_mutex); | ||
3841 | spin_lock(&root->fs_info->ordered_root_lock); | ||
3842 | |||
3843 | list_splice_init(&t->ordered_operations, &splice); | ||
3844 | while (!list_empty(&splice)) { | ||
3845 | btrfs_inode = list_entry(splice.next, struct btrfs_inode, | ||
3846 | ordered_operations); | ||
3847 | |||
3848 | list_del_init(&btrfs_inode->ordered_operations); | ||
3849 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
3850 | |||
3851 | btrfs_invalidate_inodes(btrfs_inode->root); | ||
3852 | |||
3853 | spin_lock(&root->fs_info->ordered_root_lock); | ||
3854 | } | ||
3855 | |||
3856 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
3857 | mutex_unlock(&root->fs_info->ordered_operations_mutex); | ||
3858 | } | ||
3859 | |||
3860 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) | 3830 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) |
3861 | { | 3831 | { |
3862 | struct btrfs_ordered_extent *ordered; | 3832 | struct btrfs_ordered_extent *ordered; |
@@ -4093,8 +4063,6 @@ again: | |||
4093 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | 4063 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, |
4094 | struct btrfs_root *root) | 4064 | struct btrfs_root *root) |
4095 | { | 4065 | { |
4096 | btrfs_destroy_ordered_operations(cur_trans, root); | ||
4097 | |||
4098 | btrfs_destroy_delayed_refs(cur_trans, root); | 4066 | btrfs_destroy_delayed_refs(cur_trans, root); |
4099 | 4067 | ||
4100 | cur_trans->state = TRANS_STATE_COMMIT_START; | 4068 | cur_trans->state = TRANS_STATE_COMMIT_START; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 813537f362f9..102ed3143976 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3057,7 +3057,7 @@ out: | |||
3057 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | 3057 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, |
3058 | struct btrfs_root *root, | 3058 | struct btrfs_root *root, |
3059 | struct extent_buffer *buf, | 3059 | struct extent_buffer *buf, |
3060 | int full_backref, int inc, int no_quota) | 3060 | int full_backref, int inc) |
3061 | { | 3061 | { |
3062 | u64 bytenr; | 3062 | u64 bytenr; |
3063 | u64 num_bytes; | 3063 | u64 num_bytes; |
@@ -3111,7 +3111,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
3111 | key.offset -= btrfs_file_extent_offset(buf, fi); | 3111 | key.offset -= btrfs_file_extent_offset(buf, fi); |
3112 | ret = process_func(trans, root, bytenr, num_bytes, | 3112 | ret = process_func(trans, root, bytenr, num_bytes, |
3113 | parent, ref_root, key.objectid, | 3113 | parent, ref_root, key.objectid, |
3114 | key.offset, no_quota); | 3114 | key.offset, 1); |
3115 | if (ret) | 3115 | if (ret) |
3116 | goto fail; | 3116 | goto fail; |
3117 | } else { | 3117 | } else { |
@@ -3119,7 +3119,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
3119 | num_bytes = btrfs_level_size(root, level - 1); | 3119 | num_bytes = btrfs_level_size(root, level - 1); |
3120 | ret = process_func(trans, root, bytenr, num_bytes, | 3120 | ret = process_func(trans, root, bytenr, num_bytes, |
3121 | parent, ref_root, level - 1, 0, | 3121 | parent, ref_root, level - 1, 0, |
3122 | no_quota); | 3122 | 1); |
3123 | if (ret) | 3123 | if (ret) |
3124 | goto fail; | 3124 | goto fail; |
3125 | } | 3125 | } |
@@ -3130,15 +3130,15 @@ fail: | |||
3130 | } | 3130 | } |
3131 | 3131 | ||
3132 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3132 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3133 | struct extent_buffer *buf, int full_backref, int no_quota) | 3133 | struct extent_buffer *buf, int full_backref) |
3134 | { | 3134 | { |
3135 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1, no_quota); | 3135 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1); |
3136 | } | 3136 | } |
3137 | 3137 | ||
3138 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3138 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3139 | struct extent_buffer *buf, int full_backref, int no_quota) | 3139 | struct extent_buffer *buf, int full_backref) |
3140 | { | 3140 | { |
3141 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0, no_quota); | 3141 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0); |
3142 | } | 3142 | } |
3143 | 3143 | ||
3144 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 3144 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
@@ -7478,6 +7478,220 @@ reada: | |||
7478 | wc->reada_slot = slot; | 7478 | wc->reada_slot = slot; |
7479 | } | 7479 | } |
7480 | 7480 | ||
7481 | static int account_leaf_items(struct btrfs_trans_handle *trans, | ||
7482 | struct btrfs_root *root, | ||
7483 | struct extent_buffer *eb) | ||
7484 | { | ||
7485 | int nr = btrfs_header_nritems(eb); | ||
7486 | int i, extent_type, ret; | ||
7487 | struct btrfs_key key; | ||
7488 | struct btrfs_file_extent_item *fi; | ||
7489 | u64 bytenr, num_bytes; | ||
7490 | |||
7491 | for (i = 0; i < nr; i++) { | ||
7492 | btrfs_item_key_to_cpu(eb, &key, i); | ||
7493 | |||
7494 | if (key.type != BTRFS_EXTENT_DATA_KEY) | ||
7495 | continue; | ||
7496 | |||
7497 | fi = btrfs_item_ptr(eb, i, struct btrfs_file_extent_item); | ||
7498 | /* filter out non qgroup-accountable extents */ | ||
7499 | extent_type = btrfs_file_extent_type(eb, fi); | ||
7500 | |||
7501 | if (extent_type == BTRFS_FILE_EXTENT_INLINE) | ||
7502 | continue; | ||
7503 | |||
7504 | bytenr = btrfs_file_extent_disk_bytenr(eb, fi); | ||
7505 | if (!bytenr) | ||
7506 | continue; | ||
7507 | |||
7508 | num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); | ||
7509 | |||
7510 | ret = btrfs_qgroup_record_ref(trans, root->fs_info, | ||
7511 | root->objectid, | ||
7512 | bytenr, num_bytes, | ||
7513 | BTRFS_QGROUP_OPER_SUB_SUBTREE, 0); | ||
7514 | if (ret) | ||
7515 | return ret; | ||
7516 | } | ||
7517 | return 0; | ||
7518 | } | ||
7519 | |||
7520 | /* | ||
7521 | * Walk up the tree from the bottom, freeing leaves and any interior | ||
7522 | * nodes which have had all slots visited. If a node (leaf or | ||
7523 | * interior) is freed, the node above it will have it's slot | ||
7524 | * incremented. The root node will never be freed. | ||
7525 | * | ||
7526 | * At the end of this function, we should have a path which has all | ||
7527 | * slots incremented to the next position for a search. If we need to | ||
7528 | * read a new node it will be NULL and the node above it will have the | ||
7529 | * correct slot selected for a later read. | ||
7530 | * | ||
7531 | * If we increment the root nodes slot counter past the number of | ||
7532 | * elements, 1 is returned to signal completion of the search. | ||
7533 | */ | ||
7534 | static int adjust_slots_upwards(struct btrfs_root *root, | ||
7535 | struct btrfs_path *path, int root_level) | ||
7536 | { | ||
7537 | int level = 0; | ||
7538 | int nr, slot; | ||
7539 | struct extent_buffer *eb; | ||
7540 | |||
7541 | if (root_level == 0) | ||
7542 | return 1; | ||
7543 | |||
7544 | while (level <= root_level) { | ||
7545 | eb = path->nodes[level]; | ||
7546 | nr = btrfs_header_nritems(eb); | ||
7547 | path->slots[level]++; | ||
7548 | slot = path->slots[level]; | ||
7549 | if (slot >= nr || level == 0) { | ||
7550 | /* | ||
7551 | * Don't free the root - we will detect this | ||
7552 | * condition after our loop and return a | ||
7553 | * positive value for caller to stop walking the tree. | ||
7554 | */ | ||
7555 | if (level != root_level) { | ||
7556 | btrfs_tree_unlock_rw(eb, path->locks[level]); | ||
7557 | path->locks[level] = 0; | ||
7558 | |||
7559 | free_extent_buffer(eb); | ||
7560 | path->nodes[level] = NULL; | ||
7561 | path->slots[level] = 0; | ||
7562 | } | ||
7563 | } else { | ||
7564 | /* | ||
7565 | * We have a valid slot to walk back down | ||
7566 | * from. Stop here so caller can process these | ||
7567 | * new nodes. | ||
7568 | */ | ||
7569 | break; | ||
7570 | } | ||
7571 | |||
7572 | level++; | ||
7573 | } | ||
7574 | |||
7575 | eb = path->nodes[root_level]; | ||
7576 | if (path->slots[root_level] >= btrfs_header_nritems(eb)) | ||
7577 | return 1; | ||
7578 | |||
7579 | return 0; | ||
7580 | } | ||
7581 | |||
7582 | /* | ||
7583 | * root_eb is the subtree root and is locked before this function is called. | ||
7584 | */ | ||
7585 | static int account_shared_subtree(struct btrfs_trans_handle *trans, | ||
7586 | struct btrfs_root *root, | ||
7587 | struct extent_buffer *root_eb, | ||
7588 | u64 root_gen, | ||
7589 | int root_level) | ||
7590 | { | ||
7591 | int ret = 0; | ||
7592 | int level; | ||
7593 | struct extent_buffer *eb = root_eb; | ||
7594 | struct btrfs_path *path = NULL; | ||
7595 | |||
7596 | BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL); | ||
7597 | BUG_ON(root_eb == NULL); | ||
7598 | |||
7599 | if (!root->fs_info->quota_enabled) | ||
7600 | return 0; | ||
7601 | |||
7602 | if (!extent_buffer_uptodate(root_eb)) { | ||
7603 | ret = btrfs_read_buffer(root_eb, root_gen); | ||
7604 | if (ret) | ||
7605 | goto out; | ||
7606 | } | ||
7607 | |||
7608 | if (root_level == 0) { | ||
7609 | ret = account_leaf_items(trans, root, root_eb); | ||
7610 | goto out; | ||
7611 | } | ||
7612 | |||
7613 | path = btrfs_alloc_path(); | ||
7614 | if (!path) | ||
7615 | return -ENOMEM; | ||
7616 | |||
7617 | /* | ||
7618 | * Walk down the tree. Missing extent blocks are filled in as | ||
7619 | * we go. Metadata is accounted every time we read a new | ||
7620 | * extent block. | ||
7621 | * | ||
7622 | * When we reach a leaf, we account for file extent items in it, | ||
7623 | * walk back up the tree (adjusting slot pointers as we go) | ||
7624 | * and restart the search process. | ||
7625 | */ | ||
7626 | extent_buffer_get(root_eb); /* For path */ | ||
7627 | path->nodes[root_level] = root_eb; | ||
7628 | path->slots[root_level] = 0; | ||
7629 | path->locks[root_level] = 0; /* so release_path doesn't try to unlock */ | ||
7630 | walk_down: | ||
7631 | level = root_level; | ||
7632 | while (level >= 0) { | ||
7633 | if (path->nodes[level] == NULL) { | ||
7634 | int child_bsize = root->nodesize; | ||
7635 | int parent_slot; | ||
7636 | u64 child_gen; | ||
7637 | u64 child_bytenr; | ||
7638 | |||
7639 | /* We need to get child blockptr/gen from | ||
7640 | * parent before we can read it. */ | ||
7641 | eb = path->nodes[level + 1]; | ||
7642 | parent_slot = path->slots[level + 1]; | ||
7643 | child_bytenr = btrfs_node_blockptr(eb, parent_slot); | ||
7644 | child_gen = btrfs_node_ptr_generation(eb, parent_slot); | ||
7645 | |||
7646 | eb = read_tree_block(root, child_bytenr, child_bsize, | ||
7647 | child_gen); | ||
7648 | if (!eb || !extent_buffer_uptodate(eb)) { | ||
7649 | ret = -EIO; | ||
7650 | goto out; | ||
7651 | } | ||
7652 | |||
7653 | path->nodes[level] = eb; | ||
7654 | path->slots[level] = 0; | ||
7655 | |||
7656 | btrfs_tree_read_lock(eb); | ||
7657 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | ||
7658 | path->locks[level] = BTRFS_READ_LOCK_BLOCKING; | ||
7659 | |||
7660 | ret = btrfs_qgroup_record_ref(trans, root->fs_info, | ||
7661 | root->objectid, | ||
7662 | child_bytenr, | ||
7663 | child_bsize, | ||
7664 | BTRFS_QGROUP_OPER_SUB_SUBTREE, | ||
7665 | 0); | ||
7666 | if (ret) | ||
7667 | goto out; | ||
7668 | |||
7669 | } | ||
7670 | |||
7671 | if (level == 0) { | ||
7672 | ret = account_leaf_items(trans, root, path->nodes[level]); | ||
7673 | if (ret) | ||
7674 | goto out; | ||
7675 | |||
7676 | /* Nonzero return here means we completed our search */ | ||
7677 | ret = adjust_slots_upwards(root, path, root_level); | ||
7678 | if (ret) | ||
7679 | break; | ||
7680 | |||
7681 | /* Restart search with new slots */ | ||
7682 | goto walk_down; | ||
7683 | } | ||
7684 | |||
7685 | level--; | ||
7686 | } | ||
7687 | |||
7688 | ret = 0; | ||
7689 | out: | ||
7690 | btrfs_free_path(path); | ||
7691 | |||
7692 | return ret; | ||
7693 | } | ||
7694 | |||
7481 | /* | 7695 | /* |
7482 | * helper to process tree block while walking down the tree. | 7696 | * helper to process tree block while walking down the tree. |
7483 | * | 7697 | * |
@@ -7532,9 +7746,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, | |||
7532 | /* wc->stage == UPDATE_BACKREF */ | 7746 | /* wc->stage == UPDATE_BACKREF */ |
7533 | if (!(wc->flags[level] & flag)) { | 7747 | if (!(wc->flags[level] & flag)) { |
7534 | BUG_ON(!path->locks[level]); | 7748 | BUG_ON(!path->locks[level]); |
7535 | ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc); | 7749 | ret = btrfs_inc_ref(trans, root, eb, 1); |
7536 | BUG_ON(ret); /* -ENOMEM */ | 7750 | BUG_ON(ret); /* -ENOMEM */ |
7537 | ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); | 7751 | ret = btrfs_dec_ref(trans, root, eb, 0); |
7538 | BUG_ON(ret); /* -ENOMEM */ | 7752 | BUG_ON(ret); /* -ENOMEM */ |
7539 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, | 7753 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, |
7540 | eb->len, flag, | 7754 | eb->len, flag, |
@@ -7581,6 +7795,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
7581 | int level = wc->level; | 7795 | int level = wc->level; |
7582 | int reada = 0; | 7796 | int reada = 0; |
7583 | int ret = 0; | 7797 | int ret = 0; |
7798 | bool need_account = false; | ||
7584 | 7799 | ||
7585 | generation = btrfs_node_ptr_generation(path->nodes[level], | 7800 | generation = btrfs_node_ptr_generation(path->nodes[level], |
7586 | path->slots[level]); | 7801 | path->slots[level]); |
@@ -7626,6 +7841,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
7626 | 7841 | ||
7627 | if (wc->stage == DROP_REFERENCE) { | 7842 | if (wc->stage == DROP_REFERENCE) { |
7628 | if (wc->refs[level - 1] > 1) { | 7843 | if (wc->refs[level - 1] > 1) { |
7844 | need_account = true; | ||
7629 | if (level == 1 && | 7845 | if (level == 1 && |
7630 | (wc->flags[0] & BTRFS_BLOCK_FLAG_FULL_BACKREF)) | 7846 | (wc->flags[0] & BTRFS_BLOCK_FLAG_FULL_BACKREF)) |
7631 | goto skip; | 7847 | goto skip; |
@@ -7689,6 +7905,16 @@ skip: | |||
7689 | parent = 0; | 7905 | parent = 0; |
7690 | } | 7906 | } |
7691 | 7907 | ||
7908 | if (need_account) { | ||
7909 | ret = account_shared_subtree(trans, root, next, | ||
7910 | generation, level - 1); | ||
7911 | if (ret) { | ||
7912 | printk_ratelimited(KERN_ERR "BTRFS: %s Error " | ||
7913 | "%d accounting shared subtree. Quota " | ||
7914 | "is out of sync, rescan required.\n", | ||
7915 | root->fs_info->sb->s_id, ret); | ||
7916 | } | ||
7917 | } | ||
7692 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, | 7918 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, |
7693 | root->root_key.objectid, level - 1, 0, 0); | 7919 | root->root_key.objectid, level - 1, 0, 0); |
7694 | BUG_ON(ret); /* -ENOMEM */ | 7920 | BUG_ON(ret); /* -ENOMEM */ |
@@ -7769,12 +7995,17 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
7769 | if (wc->refs[level] == 1) { | 7995 | if (wc->refs[level] == 1) { |
7770 | if (level == 0) { | 7996 | if (level == 0) { |
7771 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) | 7997 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) |
7772 | ret = btrfs_dec_ref(trans, root, eb, 1, | 7998 | ret = btrfs_dec_ref(trans, root, eb, 1); |
7773 | wc->for_reloc); | ||
7774 | else | 7999 | else |
7775 | ret = btrfs_dec_ref(trans, root, eb, 0, | 8000 | ret = btrfs_dec_ref(trans, root, eb, 0); |
7776 | wc->for_reloc); | ||
7777 | BUG_ON(ret); /* -ENOMEM */ | 8001 | BUG_ON(ret); /* -ENOMEM */ |
8002 | ret = account_leaf_items(trans, root, eb); | ||
8003 | if (ret) { | ||
8004 | printk_ratelimited(KERN_ERR "BTRFS: %s Error " | ||
8005 | "%d accounting leaf items. Quota " | ||
8006 | "is out of sync, rescan required.\n", | ||
8007 | root->fs_info->sb->s_id, ret); | ||
8008 | } | ||
7778 | } | 8009 | } |
7779 | /* make block locked assertion in clean_tree_block happy */ | 8010 | /* make block locked assertion in clean_tree_block happy */ |
7780 | if (!path->locks[level] && | 8011 | if (!path->locks[level] && |
@@ -7900,6 +8131,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
7900 | int level; | 8131 | int level; |
7901 | bool root_dropped = false; | 8132 | bool root_dropped = false; |
7902 | 8133 | ||
8134 | btrfs_debug(root->fs_info, "Drop subvolume %llu", root->objectid); | ||
8135 | |||
7903 | path = btrfs_alloc_path(); | 8136 | path = btrfs_alloc_path(); |
7904 | if (!path) { | 8137 | if (!path) { |
7905 | err = -ENOMEM; | 8138 | err = -ENOMEM; |
@@ -8025,6 +8258,24 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
8025 | goto out_end_trans; | 8258 | goto out_end_trans; |
8026 | } | 8259 | } |
8027 | 8260 | ||
8261 | /* | ||
8262 | * Qgroup update accounting is run from | ||
8263 | * delayed ref handling. This usually works | ||
8264 | * out because delayed refs are normally the | ||
8265 | * only way qgroup updates are added. However, | ||
8266 | * we may have added updates during our tree | ||
8267 | * walk so run qgroups here to make sure we | ||
8268 | * don't lose any updates. | ||
8269 | */ | ||
8270 | ret = btrfs_delayed_qgroup_accounting(trans, | ||
8271 | root->fs_info); | ||
8272 | if (ret) | ||
8273 | printk_ratelimited(KERN_ERR "BTRFS: Failure %d " | ||
8274 | "running qgroup updates " | ||
8275 | "during snapshot delete. " | ||
8276 | "Quota is out of sync, " | ||
8277 | "rescan required.\n", ret); | ||
8278 | |||
8028 | btrfs_end_transaction_throttle(trans, tree_root); | 8279 | btrfs_end_transaction_throttle(trans, tree_root); |
8029 | if (!for_reloc && btrfs_need_cleaner_sleep(root)) { | 8280 | if (!for_reloc && btrfs_need_cleaner_sleep(root)) { |
8030 | pr_debug("BTRFS: drop snapshot early exit\n"); | 8281 | pr_debug("BTRFS: drop snapshot early exit\n"); |
@@ -8078,6 +8329,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
8078 | } | 8329 | } |
8079 | root_dropped = true; | 8330 | root_dropped = true; |
8080 | out_end_trans: | 8331 | out_end_trans: |
8332 | ret = btrfs_delayed_qgroup_accounting(trans, tree_root->fs_info); | ||
8333 | if (ret) | ||
8334 | printk_ratelimited(KERN_ERR "BTRFS: Failure %d " | ||
8335 | "running qgroup updates " | ||
8336 | "during snapshot delete. " | ||
8337 | "Quota is out of sync, " | ||
8338 | "rescan required.\n", ret); | ||
8339 | |||
8081 | btrfs_end_transaction_throttle(trans, tree_root); | 8340 | btrfs_end_transaction_throttle(trans, tree_root); |
8082 | out_free: | 8341 | out_free: |
8083 | kfree(wc); | 8342 | kfree(wc); |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index f46cfe45d686..54c84daec9b5 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -756,7 +756,7 @@ again: | |||
756 | found_next = 1; | 756 | found_next = 1; |
757 | if (ret != 0) | 757 | if (ret != 0) |
758 | goto insert; | 758 | goto insert; |
759 | slot = 0; | 759 | slot = path->slots[0]; |
760 | } | 760 | } |
761 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); | 761 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); |
762 | if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || | 762 | if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 1f2b99cb55ea..d3afac292d67 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1838,33 +1838,9 @@ out: | |||
1838 | 1838 | ||
1839 | int btrfs_release_file(struct inode *inode, struct file *filp) | 1839 | int btrfs_release_file(struct inode *inode, struct file *filp) |
1840 | { | 1840 | { |
1841 | /* | ||
1842 | * ordered_data_close is set by settattr when we are about to truncate | ||
1843 | * a file from a non-zero size to a zero size. This tries to | ||
1844 | * flush down new bytes that may have been written if the | ||
1845 | * application were using truncate to replace a file in place. | ||
1846 | */ | ||
1847 | if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, | ||
1848 | &BTRFS_I(inode)->runtime_flags)) { | ||
1849 | struct btrfs_trans_handle *trans; | ||
1850 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
1851 | |||
1852 | /* | ||
1853 | * We need to block on a committing transaction to keep us from | ||
1854 | * throwing a ordered operation on to the list and causing | ||
1855 | * something like sync to deadlock trying to flush out this | ||
1856 | * inode. | ||
1857 | */ | ||
1858 | trans = btrfs_start_transaction(root, 0); | ||
1859 | if (IS_ERR(trans)) | ||
1860 | return PTR_ERR(trans); | ||
1861 | btrfs_add_ordered_operation(trans, BTRFS_I(inode)->root, inode); | ||
1862 | btrfs_end_transaction(trans, root); | ||
1863 | if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) | ||
1864 | filemap_flush(inode->i_mapping); | ||
1865 | } | ||
1866 | if (filp->private_data) | 1841 | if (filp->private_data) |
1867 | btrfs_ioctl_trans_end(filp); | 1842 | btrfs_ioctl_trans_end(filp); |
1843 | filemap_flush(inode->i_mapping); | ||
1868 | return 0; | 1844 | return 0; |
1869 | } | 1845 | } |
1870 | 1846 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3183742d6f0d..03708ef3deef 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -709,6 +709,18 @@ retry: | |||
709 | unlock_extent(io_tree, async_extent->start, | 709 | unlock_extent(io_tree, async_extent->start, |
710 | async_extent->start + | 710 | async_extent->start + |
711 | async_extent->ram_size - 1); | 711 | async_extent->ram_size - 1); |
712 | |||
713 | /* | ||
714 | * we need to redirty the pages if we decide to | ||
715 | * fallback to uncompressed IO, otherwise we | ||
716 | * will not submit these pages down to lower | ||
717 | * layers. | ||
718 | */ | ||
719 | extent_range_redirty_for_io(inode, | ||
720 | async_extent->start, | ||
721 | async_extent->start + | ||
722 | async_extent->ram_size - 1); | ||
723 | |||
712 | goto retry; | 724 | goto retry; |
713 | } | 725 | } |
714 | goto out_free; | 726 | goto out_free; |
@@ -7939,27 +7951,6 @@ static int btrfs_truncate(struct inode *inode) | |||
7939 | BUG_ON(ret); | 7951 | BUG_ON(ret); |
7940 | 7952 | ||
7941 | /* | 7953 | /* |
7942 | * setattr is responsible for setting the ordered_data_close flag, | ||
7943 | * but that is only tested during the last file release. That | ||
7944 | * could happen well after the next commit, leaving a great big | ||
7945 | * window where new writes may get lost if someone chooses to write | ||
7946 | * to this file after truncating to zero | ||
7947 | * | ||
7948 | * The inode doesn't have any dirty data here, and so if we commit | ||
7949 | * this is a noop. If someone immediately starts writing to the inode | ||
7950 | * it is very likely we'll catch some of their writes in this | ||
7951 | * transaction, and the commit will find this file on the ordered | ||
7952 | * data list with good things to send down. | ||
7953 | * | ||
7954 | * This is a best effort solution, there is still a window where | ||
7955 | * using truncate to replace the contents of the file will | ||
7956 | * end up with a zero length file after a crash. | ||
7957 | */ | ||
7958 | if (inode->i_size == 0 && test_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, | ||
7959 | &BTRFS_I(inode)->runtime_flags)) | ||
7960 | btrfs_add_ordered_operation(trans, root, inode); | ||
7961 | |||
7962 | /* | ||
7963 | * So if we truncate and then write and fsync we normally would just | 7954 | * So if we truncate and then write and fsync we normally would just |
7964 | * write the extents that changed, which is a problem if we need to | 7955 | * write the extents that changed, which is a problem if we need to |
7965 | * first truncate that entire inode. So set this flag so we write out | 7956 | * first truncate that entire inode. So set this flag so we write out |
@@ -8106,7 +8097,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
8106 | mutex_init(&ei->delalloc_mutex); | 8097 | mutex_init(&ei->delalloc_mutex); |
8107 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); | 8098 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); |
8108 | INIT_LIST_HEAD(&ei->delalloc_inodes); | 8099 | INIT_LIST_HEAD(&ei->delalloc_inodes); |
8109 | INIT_LIST_HEAD(&ei->ordered_operations); | ||
8110 | RB_CLEAR_NODE(&ei->rb_node); | 8100 | RB_CLEAR_NODE(&ei->rb_node); |
8111 | 8101 | ||
8112 | return inode; | 8102 | return inode; |
@@ -8146,17 +8136,6 @@ void btrfs_destroy_inode(struct inode *inode) | |||
8146 | if (!root) | 8136 | if (!root) |
8147 | goto free; | 8137 | goto free; |
8148 | 8138 | ||
8149 | /* | ||
8150 | * Make sure we're properly removed from the ordered operation | ||
8151 | * lists. | ||
8152 | */ | ||
8153 | smp_mb(); | ||
8154 | if (!list_empty(&BTRFS_I(inode)->ordered_operations)) { | ||
8155 | spin_lock(&root->fs_info->ordered_root_lock); | ||
8156 | list_del_init(&BTRFS_I(inode)->ordered_operations); | ||
8157 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
8158 | } | ||
8159 | |||
8160 | if (test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, | 8139 | if (test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, |
8161 | &BTRFS_I(inode)->runtime_flags)) { | 8140 | &BTRFS_I(inode)->runtime_flags)) { |
8162 | btrfs_info(root->fs_info, "inode %llu still on the orphan list", | 8141 | btrfs_info(root->fs_info, "inode %llu still on the orphan list", |
@@ -8338,12 +8317,10 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
8338 | ret = 0; | 8317 | ret = 0; |
8339 | 8318 | ||
8340 | /* | 8319 | /* |
8341 | * we're using rename to replace one file with another. | 8320 | * we're using rename to replace one file with another. Start IO on it |
8342 | * and the replacement file is large. Start IO on it now so | 8321 | * now so we don't add too much work to the end of the transaction |
8343 | * we don't add too much work to the end of the transaction | ||
8344 | */ | 8322 | */ |
8345 | if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size && | 8323 | if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size) |
8346 | old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) | ||
8347 | filemap_flush(old_inode->i_mapping); | 8324 | filemap_flush(old_inode->i_mapping); |
8348 | 8325 | ||
8349 | /* close the racy window with snapshot create/destroy ioctl */ | 8326 | /* close the racy window with snapshot create/destroy ioctl */ |
@@ -8391,12 +8368,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
8391 | */ | 8368 | */ |
8392 | btrfs_pin_log_trans(root); | 8369 | btrfs_pin_log_trans(root); |
8393 | } | 8370 | } |
8394 | /* | ||
8395 | * make sure the inode gets flushed if it is replacing | ||
8396 | * something. | ||
8397 | */ | ||
8398 | if (new_inode && new_inode->i_size && S_ISREG(old_inode->i_mode)) | ||
8399 | btrfs_add_ordered_operation(trans, root, old_inode); | ||
8400 | 8371 | ||
8401 | inode_inc_iversion(old_dir); | 8372 | inode_inc_iversion(old_dir); |
8402 | inode_inc_iversion(new_dir); | 8373 | inode_inc_iversion(new_dir); |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 7187b14faa6c..963895c1f801 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -571,18 +571,6 @@ void btrfs_remove_ordered_extent(struct inode *inode, | |||
571 | 571 | ||
572 | trace_btrfs_ordered_extent_remove(inode, entry); | 572 | trace_btrfs_ordered_extent_remove(inode, entry); |
573 | 573 | ||
574 | /* | ||
575 | * we have no more ordered extents for this inode and | ||
576 | * no dirty pages. We can safely remove it from the | ||
577 | * list of ordered extents | ||
578 | */ | ||
579 | if (RB_EMPTY_ROOT(&tree->tree) && | ||
580 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { | ||
581 | spin_lock(&root->fs_info->ordered_root_lock); | ||
582 | list_del_init(&BTRFS_I(inode)->ordered_operations); | ||
583 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
584 | } | ||
585 | |||
586 | if (!root->nr_ordered_extents) { | 574 | if (!root->nr_ordered_extents) { |
587 | spin_lock(&root->fs_info->ordered_root_lock); | 575 | spin_lock(&root->fs_info->ordered_root_lock); |
588 | BUG_ON(list_empty(&root->ordered_root)); | 576 | BUG_ON(list_empty(&root->ordered_root)); |
@@ -687,81 +675,6 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr) | |||
687 | } | 675 | } |
688 | 676 | ||
689 | /* | 677 | /* |
690 | * this is used during transaction commit to write all the inodes | ||
691 | * added to the ordered operation list. These files must be fully on | ||
692 | * disk before the transaction commits. | ||
693 | * | ||
694 | * we have two modes here, one is to just start the IO via filemap_flush | ||
695 | * and the other is to wait for all the io. When we wait, we have an | ||
696 | * extra check to make sure the ordered operation list really is empty | ||
697 | * before we return | ||
698 | */ | ||
699 | int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans, | ||
700 | struct btrfs_root *root, int wait) | ||
701 | { | ||
702 | struct btrfs_inode *btrfs_inode; | ||
703 | struct inode *inode; | ||
704 | struct btrfs_transaction *cur_trans = trans->transaction; | ||
705 | struct list_head splice; | ||
706 | struct list_head works; | ||
707 | struct btrfs_delalloc_work *work, *next; | ||
708 | int ret = 0; | ||
709 | |||
710 | INIT_LIST_HEAD(&splice); | ||
711 | INIT_LIST_HEAD(&works); | ||
712 | |||
713 | mutex_lock(&root->fs_info->ordered_extent_flush_mutex); | ||
714 | spin_lock(&root->fs_info->ordered_root_lock); | ||
715 | list_splice_init(&cur_trans->ordered_operations, &splice); | ||
716 | while (!list_empty(&splice)) { | ||
717 | btrfs_inode = list_entry(splice.next, struct btrfs_inode, | ||
718 | ordered_operations); | ||
719 | inode = &btrfs_inode->vfs_inode; | ||
720 | |||
721 | list_del_init(&btrfs_inode->ordered_operations); | ||
722 | |||
723 | /* | ||
724 | * the inode may be getting freed (in sys_unlink path). | ||
725 | */ | ||
726 | inode = igrab(inode); | ||
727 | if (!inode) | ||
728 | continue; | ||
729 | |||
730 | if (!wait) | ||
731 | list_add_tail(&BTRFS_I(inode)->ordered_operations, | ||
732 | &cur_trans->ordered_operations); | ||
733 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
734 | |||
735 | work = btrfs_alloc_delalloc_work(inode, wait, 1); | ||
736 | if (!work) { | ||
737 | spin_lock(&root->fs_info->ordered_root_lock); | ||
738 | if (list_empty(&BTRFS_I(inode)->ordered_operations)) | ||
739 | list_add_tail(&btrfs_inode->ordered_operations, | ||
740 | &splice); | ||
741 | list_splice_tail(&splice, | ||
742 | &cur_trans->ordered_operations); | ||
743 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
744 | ret = -ENOMEM; | ||
745 | goto out; | ||
746 | } | ||
747 | list_add_tail(&work->list, &works); | ||
748 | btrfs_queue_work(root->fs_info->flush_workers, | ||
749 | &work->work); | ||
750 | |||
751 | cond_resched(); | ||
752 | spin_lock(&root->fs_info->ordered_root_lock); | ||
753 | } | ||
754 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
755 | out: | ||
756 | list_for_each_entry_safe(work, next, &works, list) { | ||
757 | list_del_init(&work->list); | ||
758 | btrfs_wait_and_free_delalloc_work(work); | ||
759 | } | ||
760 | mutex_unlock(&root->fs_info->ordered_extent_flush_mutex); | ||
761 | return ret; | ||
762 | } | ||
763 | |||
764 | /* | ||
765 | * Used to start IO or wait for a given ordered extent to finish. | 678 | * Used to start IO or wait for a given ordered extent to finish. |
766 | * | 679 | * |
767 | * If wait is one, this effectively waits on page writeback for all the pages | 680 | * If wait is one, this effectively waits on page writeback for all the pages |
@@ -1120,42 +1033,6 @@ out: | |||
1120 | return index; | 1033 | return index; |
1121 | } | 1034 | } |
1122 | 1035 | ||
1123 | |||
1124 | /* | ||
1125 | * add a given inode to the list of inodes that must be fully on | ||
1126 | * disk before a transaction commit finishes. | ||
1127 | * | ||
1128 | * This basically gives us the ext3 style data=ordered mode, and it is mostly | ||
1129 | * used to make sure renamed files are fully on disk. | ||
1130 | * | ||
1131 | * It is a noop if the inode is already fully on disk. | ||
1132 | * | ||
1133 | * If trans is not null, we'll do a friendly check for a transaction that | ||
1134 | * is already flushing things and force the IO down ourselves. | ||
1135 | */ | ||
1136 | void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, | ||
1137 | struct btrfs_root *root, struct inode *inode) | ||
1138 | { | ||
1139 | struct btrfs_transaction *cur_trans = trans->transaction; | ||
1140 | u64 last_mod; | ||
1141 | |||
1142 | last_mod = max(BTRFS_I(inode)->generation, BTRFS_I(inode)->last_trans); | ||
1143 | |||
1144 | /* | ||
1145 | * if this file hasn't been changed since the last transaction | ||
1146 | * commit, we can safely return without doing anything | ||
1147 | */ | ||
1148 | if (last_mod <= root->fs_info->last_trans_committed) | ||
1149 | return; | ||
1150 | |||
1151 | spin_lock(&root->fs_info->ordered_root_lock); | ||
1152 | if (list_empty(&BTRFS_I(inode)->ordered_operations)) { | ||
1153 | list_add_tail(&BTRFS_I(inode)->ordered_operations, | ||
1154 | &cur_trans->ordered_operations); | ||
1155 | } | ||
1156 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
1157 | } | ||
1158 | |||
1159 | int __init ordered_data_init(void) | 1036 | int __init ordered_data_init(void) |
1160 | { | 1037 | { |
1161 | btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent", | 1038 | btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent", |
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 246897058efb..d81a274d621e 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h | |||
@@ -190,11 +190,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
190 | struct btrfs_ordered_extent *ordered); | 190 | struct btrfs_ordered_extent *ordered); |
191 | int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | 191 | int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, |
192 | u32 *sum, int len); | 192 | u32 *sum, int len); |
193 | int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans, | ||
194 | struct btrfs_root *root, int wait); | ||
195 | void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, | ||
196 | struct btrfs_root *root, | ||
197 | struct inode *inode); | ||
198 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr); | 193 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr); |
199 | void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr); | 194 | void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr); |
200 | void btrfs_get_logged_extents(struct inode *inode, | 195 | void btrfs_get_logged_extents(struct inode *inode, |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 98cb6b2630f9..b497498484be 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -1201,6 +1201,50 @@ out: | |||
1201 | mutex_unlock(&fs_info->qgroup_ioctl_lock); | 1201 | mutex_unlock(&fs_info->qgroup_ioctl_lock); |
1202 | return ret; | 1202 | return ret; |
1203 | } | 1203 | } |
1204 | |||
1205 | static int comp_oper_exist(struct btrfs_qgroup_operation *oper1, | ||
1206 | struct btrfs_qgroup_operation *oper2) | ||
1207 | { | ||
1208 | /* | ||
1209 | * Ignore seq and type here, we're looking for any operation | ||
1210 | * at all related to this extent on that root. | ||
1211 | */ | ||
1212 | if (oper1->bytenr < oper2->bytenr) | ||
1213 | return -1; | ||
1214 | if (oper1->bytenr > oper2->bytenr) | ||
1215 | return 1; | ||
1216 | if (oper1->ref_root < oper2->ref_root) | ||
1217 | return -1; | ||
1218 | if (oper1->ref_root > oper2->ref_root) | ||
1219 | return 1; | ||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | static int qgroup_oper_exists(struct btrfs_fs_info *fs_info, | ||
1224 | struct btrfs_qgroup_operation *oper) | ||
1225 | { | ||
1226 | struct rb_node *n; | ||
1227 | struct btrfs_qgroup_operation *cur; | ||
1228 | int cmp; | ||
1229 | |||
1230 | spin_lock(&fs_info->qgroup_op_lock); | ||
1231 | n = fs_info->qgroup_op_tree.rb_node; | ||
1232 | while (n) { | ||
1233 | cur = rb_entry(n, struct btrfs_qgroup_operation, n); | ||
1234 | cmp = comp_oper_exist(cur, oper); | ||
1235 | if (cmp < 0) { | ||
1236 | n = n->rb_right; | ||
1237 | } else if (cmp) { | ||
1238 | n = n->rb_left; | ||
1239 | } else { | ||
1240 | spin_unlock(&fs_info->qgroup_op_lock); | ||
1241 | return -EEXIST; | ||
1242 | } | ||
1243 | } | ||
1244 | spin_unlock(&fs_info->qgroup_op_lock); | ||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1204 | static int comp_oper(struct btrfs_qgroup_operation *oper1, | 1248 | static int comp_oper(struct btrfs_qgroup_operation *oper1, |
1205 | struct btrfs_qgroup_operation *oper2) | 1249 | struct btrfs_qgroup_operation *oper2) |
1206 | { | 1250 | { |
@@ -1290,6 +1334,23 @@ int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans, | |||
1290 | oper->seq = atomic_inc_return(&fs_info->qgroup_op_seq); | 1334 | oper->seq = atomic_inc_return(&fs_info->qgroup_op_seq); |
1291 | INIT_LIST_HEAD(&oper->elem.list); | 1335 | INIT_LIST_HEAD(&oper->elem.list); |
1292 | oper->elem.seq = 0; | 1336 | oper->elem.seq = 0; |
1337 | |||
1338 | if (type == BTRFS_QGROUP_OPER_SUB_SUBTREE) { | ||
1339 | /* | ||
1340 | * If any operation for this bytenr/ref_root combo | ||
1341 | * exists, then we know it's not exclusively owned and | ||
1342 | * shouldn't be queued up. | ||
1343 | * | ||
1344 | * This also catches the case where we have a cloned | ||
1345 | * extent that gets queued up multiple times during | ||
1346 | * drop snapshot. | ||
1347 | */ | ||
1348 | if (qgroup_oper_exists(fs_info, oper)) { | ||
1349 | kfree(oper); | ||
1350 | return 0; | ||
1351 | } | ||
1352 | } | ||
1353 | |||
1293 | ret = insert_qgroup_oper(fs_info, oper); | 1354 | ret = insert_qgroup_oper(fs_info, oper); |
1294 | if (ret) { | 1355 | if (ret) { |
1295 | /* Shouldn't happen so have an assert for developers */ | 1356 | /* Shouldn't happen so have an assert for developers */ |
@@ -1884,6 +1945,111 @@ out: | |||
1884 | } | 1945 | } |
1885 | 1946 | ||
1886 | /* | 1947 | /* |
1948 | * Process a reference to a shared subtree. This type of operation is | ||
1949 | * queued during snapshot removal when we encounter extents which are | ||
1950 | * shared between more than one root. | ||
1951 | */ | ||
1952 | static int qgroup_subtree_accounting(struct btrfs_trans_handle *trans, | ||
1953 | struct btrfs_fs_info *fs_info, | ||
1954 | struct btrfs_qgroup_operation *oper) | ||
1955 | { | ||
1956 | struct ulist *roots = NULL; | ||
1957 | struct ulist_node *unode; | ||
1958 | struct ulist_iterator uiter; | ||
1959 | struct btrfs_qgroup_list *glist; | ||
1960 | struct ulist *parents; | ||
1961 | int ret = 0; | ||
1962 | int err; | ||
1963 | struct btrfs_qgroup *qg; | ||
1964 | u64 root_obj = 0; | ||
1965 | struct seq_list elem = {}; | ||
1966 | |||
1967 | parents = ulist_alloc(GFP_NOFS); | ||
1968 | if (!parents) | ||
1969 | return -ENOMEM; | ||
1970 | |||
1971 | btrfs_get_tree_mod_seq(fs_info, &elem); | ||
1972 | ret = btrfs_find_all_roots(trans, fs_info, oper->bytenr, | ||
1973 | elem.seq, &roots); | ||
1974 | btrfs_put_tree_mod_seq(fs_info, &elem); | ||
1975 | if (ret < 0) | ||
1976 | return ret; | ||
1977 | |||
1978 | if (roots->nnodes != 1) | ||
1979 | goto out; | ||
1980 | |||
1981 | ULIST_ITER_INIT(&uiter); | ||
1982 | unode = ulist_next(roots, &uiter); /* Only want 1 so no need to loop */ | ||
1983 | /* | ||
1984 | * If we find our ref root then that means all refs | ||
1985 | * this extent has to the root have not yet been | ||
1986 | * deleted. In that case, we do nothing and let the | ||
1987 | * last ref for this bytenr drive our update. | ||
1988 | * | ||
1989 | * This can happen for example if an extent is | ||
1990 | * referenced multiple times in a snapshot (clone, | ||
1991 | * etc). If we are in the middle of snapshot removal, | ||
1992 | * queued updates for such an extent will find the | ||
1993 | * root if we have not yet finished removing the | ||
1994 | * snapshot. | ||
1995 | */ | ||
1996 | if (unode->val == oper->ref_root) | ||
1997 | goto out; | ||
1998 | |||
1999 | root_obj = unode->val; | ||
2000 | BUG_ON(!root_obj); | ||
2001 | |||
2002 | spin_lock(&fs_info->qgroup_lock); | ||
2003 | qg = find_qgroup_rb(fs_info, root_obj); | ||
2004 | if (!qg) | ||
2005 | goto out_unlock; | ||
2006 | |||
2007 | qg->excl += oper->num_bytes; | ||
2008 | qg->excl_cmpr += oper->num_bytes; | ||
2009 | qgroup_dirty(fs_info, qg); | ||
2010 | |||
2011 | /* | ||
2012 | * Adjust counts for parent groups. First we find all | ||
2013 | * parents, then in the 2nd loop we do the adjustment | ||
2014 | * while adding parents of the parents to our ulist. | ||
2015 | */ | ||
2016 | list_for_each_entry(glist, &qg->groups, next_group) { | ||
2017 | err = ulist_add(parents, glist->group->qgroupid, | ||
2018 | ptr_to_u64(glist->group), GFP_ATOMIC); | ||
2019 | if (err < 0) { | ||
2020 | ret = err; | ||
2021 | goto out_unlock; | ||
2022 | } | ||
2023 | } | ||
2024 | |||
2025 | ULIST_ITER_INIT(&uiter); | ||
2026 | while ((unode = ulist_next(parents, &uiter))) { | ||
2027 | qg = u64_to_ptr(unode->aux); | ||
2028 | qg->excl += oper->num_bytes; | ||
2029 | qg->excl_cmpr += oper->num_bytes; | ||
2030 | qgroup_dirty(fs_info, qg); | ||
2031 | |||
2032 | /* Add any parents of the parents */ | ||
2033 | list_for_each_entry(glist, &qg->groups, next_group) { | ||
2034 | err = ulist_add(parents, glist->group->qgroupid, | ||
2035 | ptr_to_u64(glist->group), GFP_ATOMIC); | ||
2036 | if (err < 0) { | ||
2037 | ret = err; | ||
2038 | goto out_unlock; | ||
2039 | } | ||
2040 | } | ||
2041 | } | ||
2042 | |||
2043 | out_unlock: | ||
2044 | spin_unlock(&fs_info->qgroup_lock); | ||
2045 | |||
2046 | out: | ||
2047 | ulist_free(roots); | ||
2048 | ulist_free(parents); | ||
2049 | return ret; | ||
2050 | } | ||
2051 | |||
2052 | /* | ||
1887 | * btrfs_qgroup_account_ref is called for every ref that is added to or deleted | 2053 | * btrfs_qgroup_account_ref is called for every ref that is added to or deleted |
1888 | * from the fs. First, all roots referencing the extent are searched, and | 2054 | * from the fs. First, all roots referencing the extent are searched, and |
1889 | * then the space is accounted accordingly to the different roots. The | 2055 | * then the space is accounted accordingly to the different roots. The |
@@ -1920,6 +2086,9 @@ static int btrfs_qgroup_account(struct btrfs_trans_handle *trans, | |||
1920 | case BTRFS_QGROUP_OPER_SUB_SHARED: | 2086 | case BTRFS_QGROUP_OPER_SUB_SHARED: |
1921 | ret = qgroup_shared_accounting(trans, fs_info, oper); | 2087 | ret = qgroup_shared_accounting(trans, fs_info, oper); |
1922 | break; | 2088 | break; |
2089 | case BTRFS_QGROUP_OPER_SUB_SUBTREE: | ||
2090 | ret = qgroup_subtree_accounting(trans, fs_info, oper); | ||
2091 | break; | ||
1923 | default: | 2092 | default: |
1924 | ASSERT(0); | 2093 | ASSERT(0); |
1925 | } | 2094 | } |
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 5952ff1fbd7a..18cc68ca3090 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h | |||
@@ -44,6 +44,7 @@ enum btrfs_qgroup_operation_type { | |||
44 | BTRFS_QGROUP_OPER_ADD_SHARED, | 44 | BTRFS_QGROUP_OPER_ADD_SHARED, |
45 | BTRFS_QGROUP_OPER_SUB_EXCL, | 45 | BTRFS_QGROUP_OPER_SUB_EXCL, |
46 | BTRFS_QGROUP_OPER_SUB_SHARED, | 46 | BTRFS_QGROUP_OPER_SUB_SHARED, |
47 | BTRFS_QGROUP_OPER_SUB_SUBTREE, | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | struct btrfs_qgroup_operation { | 50 | struct btrfs_qgroup_operation { |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 67b48b9a03e0..c4124de4435b 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1665,6 +1665,21 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1665 | return 0; | 1665 | return 0; |
1666 | } | 1666 | } |
1667 | 1667 | ||
1668 | /* | ||
1669 | * Calculate numbers for 'df', pessimistic in case of mixed raid profiles. | ||
1670 | * | ||
1671 | * If there's a redundant raid level at DATA block groups, use the respective | ||
1672 | * multiplier to scale the sizes. | ||
1673 | * | ||
1674 | * Unused device space usage is based on simulating the chunk allocator | ||
1675 | * algorithm that respects the device sizes, order of allocations and the | ||
1676 | * 'alloc_start' value, this is a close approximation of the actual use but | ||
1677 | * there are other factors that may change the result (like a new metadata | ||
1678 | * chunk). | ||
1679 | * | ||
1680 | * FIXME: not accurate for mixed block groups, total and free/used are ok, | ||
1681 | * available appears slightly larger. | ||
1682 | */ | ||
1668 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1683 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
1669 | { | 1684 | { |
1670 | struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); | 1685 | struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); |
@@ -1675,6 +1690,8 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1675 | u64 total_free_data = 0; | 1690 | u64 total_free_data = 0; |
1676 | int bits = dentry->d_sb->s_blocksize_bits; | 1691 | int bits = dentry->d_sb->s_blocksize_bits; |
1677 | __be32 *fsid = (__be32 *)fs_info->fsid; | 1692 | __be32 *fsid = (__be32 *)fs_info->fsid; |
1693 | unsigned factor = 1; | ||
1694 | struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; | ||
1678 | int ret; | 1695 | int ret; |
1679 | 1696 | ||
1680 | /* holding chunk_muext to avoid allocating new chunks */ | 1697 | /* holding chunk_muext to avoid allocating new chunks */ |
@@ -1682,30 +1699,52 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1682 | rcu_read_lock(); | 1699 | rcu_read_lock(); |
1683 | list_for_each_entry_rcu(found, head, list) { | 1700 | list_for_each_entry_rcu(found, head, list) { |
1684 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { | 1701 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { |
1702 | int i; | ||
1703 | |||
1685 | total_free_data += found->disk_total - found->disk_used; | 1704 | total_free_data += found->disk_total - found->disk_used; |
1686 | total_free_data -= | 1705 | total_free_data -= |
1687 | btrfs_account_ro_block_groups_free_space(found); | 1706 | btrfs_account_ro_block_groups_free_space(found); |
1707 | |||
1708 | for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) { | ||
1709 | if (!list_empty(&found->block_groups[i])) { | ||
1710 | switch (i) { | ||
1711 | case BTRFS_RAID_DUP: | ||
1712 | case BTRFS_RAID_RAID1: | ||
1713 | case BTRFS_RAID_RAID10: | ||
1714 | factor = 2; | ||
1715 | } | ||
1716 | } | ||
1717 | } | ||
1688 | } | 1718 | } |
1689 | 1719 | ||
1690 | total_used += found->disk_used; | 1720 | total_used += found->disk_used; |
1691 | } | 1721 | } |
1722 | |||
1692 | rcu_read_unlock(); | 1723 | rcu_read_unlock(); |
1693 | 1724 | ||
1694 | buf->f_namelen = BTRFS_NAME_LEN; | 1725 | buf->f_blocks = div_u64(btrfs_super_total_bytes(disk_super), factor); |
1695 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; | 1726 | buf->f_blocks >>= bits; |
1696 | buf->f_bfree = buf->f_blocks - (total_used >> bits); | 1727 | buf->f_bfree = buf->f_blocks - (div_u64(total_used, factor) >> bits); |
1697 | buf->f_bsize = dentry->d_sb->s_blocksize; | 1728 | |
1698 | buf->f_type = BTRFS_SUPER_MAGIC; | 1729 | /* Account global block reserve as used, it's in logical size already */ |
1730 | spin_lock(&block_rsv->lock); | ||
1731 | buf->f_bfree -= block_rsv->size >> bits; | ||
1732 | spin_unlock(&block_rsv->lock); | ||
1733 | |||
1699 | buf->f_bavail = total_free_data; | 1734 | buf->f_bavail = total_free_data; |
1700 | ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); | 1735 | ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); |
1701 | if (ret) { | 1736 | if (ret) { |
1702 | mutex_unlock(&fs_info->chunk_mutex); | 1737 | mutex_unlock(&fs_info->chunk_mutex); |
1703 | return ret; | 1738 | return ret; |
1704 | } | 1739 | } |
1705 | buf->f_bavail += total_free_data; | 1740 | buf->f_bavail += div_u64(total_free_data, factor); |
1706 | buf->f_bavail = buf->f_bavail >> bits; | 1741 | buf->f_bavail = buf->f_bavail >> bits; |
1707 | mutex_unlock(&fs_info->chunk_mutex); | 1742 | mutex_unlock(&fs_info->chunk_mutex); |
1708 | 1743 | ||
1744 | buf->f_type = BTRFS_SUPER_MAGIC; | ||
1745 | buf->f_bsize = dentry->d_sb->s_blocksize; | ||
1746 | buf->f_namelen = BTRFS_NAME_LEN; | ||
1747 | |||
1709 | /* We treat it as constant endianness (it doesn't matter _which_) | 1748 | /* We treat it as constant endianness (it doesn't matter _which_) |
1710 | because we want the fsid to come out the same whether mounted | 1749 | because we want the fsid to come out the same whether mounted |
1711 | on a big-endian or little-endian host */ | 1750 | on a big-endian or little-endian host */ |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 5f379affdf23..d89c6d3542ca 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -218,7 +218,6 @@ loop: | |||
218 | spin_lock_init(&cur_trans->delayed_refs.lock); | 218 | spin_lock_init(&cur_trans->delayed_refs.lock); |
219 | 219 | ||
220 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 220 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
221 | INIT_LIST_HEAD(&cur_trans->ordered_operations); | ||
222 | INIT_LIST_HEAD(&cur_trans->pending_chunks); | 221 | INIT_LIST_HEAD(&cur_trans->pending_chunks); |
223 | INIT_LIST_HEAD(&cur_trans->switch_commits); | 222 | INIT_LIST_HEAD(&cur_trans->switch_commits); |
224 | list_add_tail(&cur_trans->list, &fs_info->trans_list); | 223 | list_add_tail(&cur_trans->list, &fs_info->trans_list); |
@@ -1612,27 +1611,6 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1612 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 1611 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
1613 | } | 1612 | } |
1614 | 1613 | ||
1615 | static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | ||
1616 | struct btrfs_root *root) | ||
1617 | { | ||
1618 | int ret; | ||
1619 | |||
1620 | ret = btrfs_run_delayed_items(trans, root); | ||
1621 | if (ret) | ||
1622 | return ret; | ||
1623 | |||
1624 | /* | ||
1625 | * rename don't use btrfs_join_transaction, so, once we | ||
1626 | * set the transaction to blocked above, we aren't going | ||
1627 | * to get any new ordered operations. We can safely run | ||
1628 | * it here and no for sure that nothing new will be added | ||
1629 | * to the list | ||
1630 | */ | ||
1631 | ret = btrfs_run_ordered_operations(trans, root, 1); | ||
1632 | |||
1633 | return ret; | ||
1634 | } | ||
1635 | |||
1636 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) | 1614 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) |
1637 | { | 1615 | { |
1638 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) | 1616 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) |
@@ -1653,13 +1631,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1653 | struct btrfs_transaction *prev_trans = NULL; | 1631 | struct btrfs_transaction *prev_trans = NULL; |
1654 | int ret; | 1632 | int ret; |
1655 | 1633 | ||
1656 | ret = btrfs_run_ordered_operations(trans, root, 0); | ||
1657 | if (ret) { | ||
1658 | btrfs_abort_transaction(trans, root, ret); | ||
1659 | btrfs_end_transaction(trans, root); | ||
1660 | return ret; | ||
1661 | } | ||
1662 | |||
1663 | /* Stop the commit early if ->aborted is set */ | 1634 | /* Stop the commit early if ->aborted is set */ |
1664 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { | 1635 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { |
1665 | ret = cur_trans->aborted; | 1636 | ret = cur_trans->aborted; |
@@ -1740,7 +1711,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1740 | if (ret) | 1711 | if (ret) |
1741 | goto cleanup_transaction; | 1712 | goto cleanup_transaction; |
1742 | 1713 | ||
1743 | ret = btrfs_flush_all_pending_stuffs(trans, root); | 1714 | ret = btrfs_run_delayed_items(trans, root); |
1744 | if (ret) | 1715 | if (ret) |
1745 | goto cleanup_transaction; | 1716 | goto cleanup_transaction; |
1746 | 1717 | ||
@@ -1748,7 +1719,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1748 | extwriter_counter_read(cur_trans) == 0); | 1719 | extwriter_counter_read(cur_trans) == 0); |
1749 | 1720 | ||
1750 | /* some pending stuffs might be added after the previous flush. */ | 1721 | /* some pending stuffs might be added after the previous flush. */ |
1751 | ret = btrfs_flush_all_pending_stuffs(trans, root); | 1722 | ret = btrfs_run_delayed_items(trans, root); |
1752 | if (ret) | 1723 | if (ret) |
1753 | goto cleanup_transaction; | 1724 | goto cleanup_transaction; |
1754 | 1725 | ||
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 7dd558ed0716..579be51b27e5 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -55,7 +55,6 @@ struct btrfs_transaction { | |||
55 | wait_queue_head_t writer_wait; | 55 | wait_queue_head_t writer_wait; |
56 | wait_queue_head_t commit_wait; | 56 | wait_queue_head_t commit_wait; |
57 | struct list_head pending_snapshots; | 57 | struct list_head pending_snapshots; |
58 | struct list_head ordered_operations; | ||
59 | struct list_head pending_chunks; | 58 | struct list_head pending_chunks; |
60 | struct list_head switch_commits; | 59 | struct list_head switch_commits; |
61 | struct btrfs_delayed_ref_root delayed_refs; | 60 | struct btrfs_delayed_ref_root delayed_refs; |
diff --git a/fs/btrfs/ulist.h b/fs/btrfs/ulist.h index 7f78cbf5cf41..4c29db604bbe 100644 --- a/fs/btrfs/ulist.h +++ b/fs/btrfs/ulist.h | |||
@@ -57,6 +57,21 @@ void ulist_free(struct ulist *ulist); | |||
57 | int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask); | 57 | int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask); |
58 | int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux, | 58 | int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux, |
59 | u64 *old_aux, gfp_t gfp_mask); | 59 | u64 *old_aux, gfp_t gfp_mask); |
60 | |||
61 | /* just like ulist_add_merge() but take a pointer for the aux data */ | ||
62 | static inline int ulist_add_merge_ptr(struct ulist *ulist, u64 val, void *aux, | ||
63 | void **old_aux, gfp_t gfp_mask) | ||
64 | { | ||
65 | #if BITS_PER_LONG == 32 | ||
66 | u64 old64 = (uintptr_t)*old_aux; | ||
67 | int ret = ulist_add_merge(ulist, val, (uintptr_t)aux, &old64, gfp_mask); | ||
68 | *old_aux = (void *)((uintptr_t)old64); | ||
69 | return ret; | ||
70 | #else | ||
71 | return ulist_add_merge(ulist, val, (u64)aux, (u64 *)old_aux, gfp_mask); | ||
72 | #endif | ||
73 | } | ||
74 | |||
60 | struct ulist_node *ulist_next(struct ulist *ulist, | 75 | struct ulist_node *ulist_next(struct ulist *ulist, |
61 | struct ulist_iterator *uiter); | 76 | struct ulist_iterator *uiter); |
62 | 77 | ||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ac4f260155c8..889b98455750 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -207,6 +207,19 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) | ||
211 | { | ||
212 | struct super_block *sb = file->f_path.dentry->d_sb; | ||
213 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | ||
214 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | ||
215 | struct TCP_Server_Info *server = tcon->ses->server; | ||
216 | |||
217 | if (server->ops->fallocate) | ||
218 | return server->ops->fallocate(file, tcon, mode, off, len); | ||
219 | |||
220 | return -EOPNOTSUPP; | ||
221 | } | ||
222 | |||
210 | static int cifs_permission(struct inode *inode, int mask) | 223 | static int cifs_permission(struct inode *inode, int mask) |
211 | { | 224 | { |
212 | struct cifs_sb_info *cifs_sb; | 225 | struct cifs_sb_info *cifs_sb; |
@@ -812,8 +825,9 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | |||
812 | if (!(S_ISREG(inode->i_mode))) | 825 | if (!(S_ISREG(inode->i_mode))) |
813 | return -EINVAL; | 826 | return -EINVAL; |
814 | 827 | ||
815 | /* check if file is oplocked */ | 828 | /* Check if file is oplocked if this is request for new lease */ |
816 | if (((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || | 829 | if (arg == F_UNLCK || |
830 | ((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || | ||
817 | ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode)))) | 831 | ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode)))) |
818 | return generic_setlease(file, arg, lease); | 832 | return generic_setlease(file, arg, lease); |
819 | else if (tlink_tcon(cfile->tlink)->local_lease && | 833 | else if (tlink_tcon(cfile->tlink)->local_lease && |
@@ -908,6 +922,7 @@ const struct file_operations cifs_file_ops = { | |||
908 | .unlocked_ioctl = cifs_ioctl, | 922 | .unlocked_ioctl = cifs_ioctl, |
909 | #endif /* CONFIG_CIFS_POSIX */ | 923 | #endif /* CONFIG_CIFS_POSIX */ |
910 | .setlease = cifs_setlease, | 924 | .setlease = cifs_setlease, |
925 | .fallocate = cifs_fallocate, | ||
911 | }; | 926 | }; |
912 | 927 | ||
913 | const struct file_operations cifs_file_strict_ops = { | 928 | const struct file_operations cifs_file_strict_ops = { |
@@ -927,6 +942,7 @@ const struct file_operations cifs_file_strict_ops = { | |||
927 | .unlocked_ioctl = cifs_ioctl, | 942 | .unlocked_ioctl = cifs_ioctl, |
928 | #endif /* CONFIG_CIFS_POSIX */ | 943 | #endif /* CONFIG_CIFS_POSIX */ |
929 | .setlease = cifs_setlease, | 944 | .setlease = cifs_setlease, |
945 | .fallocate = cifs_fallocate, | ||
930 | }; | 946 | }; |
931 | 947 | ||
932 | const struct file_operations cifs_file_direct_ops = { | 948 | const struct file_operations cifs_file_direct_ops = { |
@@ -947,6 +963,7 @@ const struct file_operations cifs_file_direct_ops = { | |||
947 | #endif /* CONFIG_CIFS_POSIX */ | 963 | #endif /* CONFIG_CIFS_POSIX */ |
948 | .llseek = cifs_llseek, | 964 | .llseek = cifs_llseek, |
949 | .setlease = cifs_setlease, | 965 | .setlease = cifs_setlease, |
966 | .fallocate = cifs_fallocate, | ||
950 | }; | 967 | }; |
951 | 968 | ||
952 | const struct file_operations cifs_file_nobrl_ops = { | 969 | const struct file_operations cifs_file_nobrl_ops = { |
@@ -965,6 +982,7 @@ const struct file_operations cifs_file_nobrl_ops = { | |||
965 | .unlocked_ioctl = cifs_ioctl, | 982 | .unlocked_ioctl = cifs_ioctl, |
966 | #endif /* CONFIG_CIFS_POSIX */ | 983 | #endif /* CONFIG_CIFS_POSIX */ |
967 | .setlease = cifs_setlease, | 984 | .setlease = cifs_setlease, |
985 | .fallocate = cifs_fallocate, | ||
968 | }; | 986 | }; |
969 | 987 | ||
970 | const struct file_operations cifs_file_strict_nobrl_ops = { | 988 | const struct file_operations cifs_file_strict_nobrl_ops = { |
@@ -983,6 +1001,7 @@ const struct file_operations cifs_file_strict_nobrl_ops = { | |||
983 | .unlocked_ioctl = cifs_ioctl, | 1001 | .unlocked_ioctl = cifs_ioctl, |
984 | #endif /* CONFIG_CIFS_POSIX */ | 1002 | #endif /* CONFIG_CIFS_POSIX */ |
985 | .setlease = cifs_setlease, | 1003 | .setlease = cifs_setlease, |
1004 | .fallocate = cifs_fallocate, | ||
986 | }; | 1005 | }; |
987 | 1006 | ||
988 | const struct file_operations cifs_file_direct_nobrl_ops = { | 1007 | const struct file_operations cifs_file_direct_nobrl_ops = { |
@@ -1002,6 +1021,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { | |||
1002 | #endif /* CONFIG_CIFS_POSIX */ | 1021 | #endif /* CONFIG_CIFS_POSIX */ |
1003 | .llseek = cifs_llseek, | 1022 | .llseek = cifs_llseek, |
1004 | .setlease = cifs_setlease, | 1023 | .setlease = cifs_setlease, |
1024 | .fallocate = cifs_fallocate, | ||
1005 | }; | 1025 | }; |
1006 | 1026 | ||
1007 | const struct file_operations cifs_dir_ops = { | 1027 | const struct file_operations cifs_dir_ops = { |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 0012e1e291d4..dfc731b02aa9 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -409,6 +409,10 @@ struct smb_version_operations { | |||
409 | /* get mtu credits */ | 409 | /* get mtu credits */ |
410 | int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, | 410 | int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, |
411 | unsigned int *, unsigned int *); | 411 | unsigned int *, unsigned int *); |
412 | /* check if we need to issue closedir */ | ||
413 | bool (*dir_needs_close)(struct cifsFileInfo *); | ||
414 | long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, | ||
415 | loff_t); | ||
412 | }; | 416 | }; |
413 | 417 | ||
414 | struct smb_version_values { | 418 | struct smb_version_values { |
@@ -883,6 +887,7 @@ struct cifs_tcon { | |||
883 | for this mount even if server would support */ | 887 | for this mount even if server would support */ |
884 | bool local_lease:1; /* check leases (only) on local system not remote */ | 888 | bool local_lease:1; /* check leases (only) on local system not remote */ |
885 | bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */ | 889 | bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */ |
890 | bool broken_sparse_sup; /* if server or share does not support sparse */ | ||
886 | bool need_reconnect:1; /* connection reset, tid now invalid */ | 891 | bool need_reconnect:1; /* connection reset, tid now invalid */ |
887 | #ifdef CONFIG_CIFS_SMB2 | 892 | #ifdef CONFIG_CIFS_SMB2 |
888 | bool print:1; /* set if connection to printer share */ | 893 | bool print:1; /* set if connection to printer share */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 33df36ef9d52..5f9822ac0245 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -2253,6 +2253,29 @@ typedef struct { | |||
2253 | /* minimum includes first three fields, and empty FS Name */ | 2253 | /* minimum includes first three fields, and empty FS Name */ |
2254 | #define MIN_FS_ATTR_INFO_SIZE 12 | 2254 | #define MIN_FS_ATTR_INFO_SIZE 12 |
2255 | 2255 | ||
2256 | |||
2257 | /* List of FileSystemAttributes - see 2.5.1 of MS-FSCC */ | ||
2258 | #define FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000 | ||
2259 | #define FILE_SUPPORTS_USN_JOURNAL 0x02000000 | ||
2260 | #define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000 | ||
2261 | #define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000 | ||
2262 | #define FILE_SUPPORTS_HARD_LINKS 0x00400000 | ||
2263 | #define FILE_SUPPORTS_TRANSACTIONS 0x00200000 | ||
2264 | #define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000 | ||
2265 | #define FILE_READ_ONLY_VOLUME 0x00080000 | ||
2266 | #define FILE_NAMED_STREAMS 0x00040000 | ||
2267 | #define FILE_SUPPORTS_ENCRYPTION 0x00020000 | ||
2268 | #define FILE_SUPPORTS_OBJECT_IDS 0x00010000 | ||
2269 | #define FILE_VOLUME_IS_COMPRESSED 0x00008000 | ||
2270 | #define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100 | ||
2271 | #define FILE_SUPPORTS_REPARSE_POINTS 0x00000080 | ||
2272 | #define FILE_SUPPORTS_SPARSE_FILES 0x00000040 | ||
2273 | #define FILE_VOLUME_QUOTAS 0x00000020 | ||
2274 | #define FILE_FILE_COMPRESSION 0x00000010 | ||
2275 | #define FILE_PERSISTENT_ACLS 0x00000008 | ||
2276 | #define FILE_UNICODE_ON_DISK 0x00000004 | ||
2277 | #define FILE_CASE_PRESERVED_NAMES 0x00000002 | ||
2278 | #define FILE_CASE_SENSITIVE_SEARCH 0x00000001 | ||
2256 | typedef struct { | 2279 | typedef struct { |
2257 | __le32 Attributes; | 2280 | __le32 Attributes; |
2258 | __le32 MaxPathNameComponentLength; | 2281 | __le32 MaxPathNameComponentLength; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4ab2f79ffa7a..d5fec92e0360 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -762,7 +762,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
762 | 762 | ||
763 | cifs_dbg(FYI, "Freeing private data in close dir\n"); | 763 | cifs_dbg(FYI, "Freeing private data in close dir\n"); |
764 | spin_lock(&cifs_file_list_lock); | 764 | spin_lock(&cifs_file_list_lock); |
765 | if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) { | 765 | if (server->ops->dir_needs_close(cfile)) { |
766 | cfile->invalidHandle = true; | 766 | cfile->invalidHandle = true; |
767 | spin_unlock(&cifs_file_list_lock); | 767 | spin_unlock(&cifs_file_list_lock); |
768 | if (server->ops->close_dir) | 768 | if (server->ops->close_dir) |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 426d6c6ad8bf..949ec909ec9a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1727,6 +1727,12 @@ unlink_target: | |||
1727 | target_dentry, to_name); | 1727 | target_dentry, to_name); |
1728 | } | 1728 | } |
1729 | 1729 | ||
1730 | /* force revalidate to go get info when needed */ | ||
1731 | CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0; | ||
1732 | |||
1733 | source_dir->i_ctime = source_dir->i_mtime = target_dir->i_ctime = | ||
1734 | target_dir->i_mtime = current_fs_time(source_dir->i_sb); | ||
1735 | |||
1730 | cifs_rename_exit: | 1736 | cifs_rename_exit: |
1731 | kfree(info_buf_source); | 1737 | kfree(info_buf_source); |
1732 | kfree(from_name); | 1738 | kfree(from_name); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 81340c6253eb..b7415d596dbd 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -574,13 +574,6 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | |||
574 | cinode->oplock = 0; | 574 | cinode->oplock = 0; |
575 | } | 575 | } |
576 | 576 | ||
577 | static int | ||
578 | cifs_oplock_break_wait(void *unused) | ||
579 | { | ||
580 | schedule(); | ||
581 | return signal_pending(current) ? -ERESTARTSYS : 0; | ||
582 | } | ||
583 | |||
584 | /* | 577 | /* |
585 | * We wait for oplock breaks to be processed before we attempt to perform | 578 | * We wait for oplock breaks to be processed before we attempt to perform |
586 | * writes. | 579 | * writes. |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b15862e0f68c..798c80a41c88 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -593,7 +593,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, | |||
593 | /* close and restart search */ | 593 | /* close and restart search */ |
594 | cifs_dbg(FYI, "search backing up - close and restart search\n"); | 594 | cifs_dbg(FYI, "search backing up - close and restart search\n"); |
595 | spin_lock(&cifs_file_list_lock); | 595 | spin_lock(&cifs_file_list_lock); |
596 | if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) { | 596 | if (server->ops->dir_needs_close(cfile)) { |
597 | cfile->invalidHandle = true; | 597 | cfile->invalidHandle = true; |
598 | spin_unlock(&cifs_file_list_lock); | 598 | spin_unlock(&cifs_file_list_lock); |
599 | if (server->ops->close) | 599 | if (server->ops->close) |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 5e8c22d6c7b9..1a6df4b03f67 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -1015,6 +1015,12 @@ cifs_wp_retry_size(struct inode *inode) | |||
1015 | return CIFS_SB(inode->i_sb)->wsize; | 1015 | return CIFS_SB(inode->i_sb)->wsize; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | static bool | ||
1019 | cifs_dir_needs_close(struct cifsFileInfo *cfile) | ||
1020 | { | ||
1021 | return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle; | ||
1022 | } | ||
1023 | |||
1018 | struct smb_version_operations smb1_operations = { | 1024 | struct smb_version_operations smb1_operations = { |
1019 | .send_cancel = send_nt_cancel, | 1025 | .send_cancel = send_nt_cancel, |
1020 | .compare_fids = cifs_compare_fids, | 1026 | .compare_fids = cifs_compare_fids, |
@@ -1086,6 +1092,7 @@ struct smb_version_operations smb1_operations = { | |||
1086 | .create_mf_symlink = cifs_create_mf_symlink, | 1092 | .create_mf_symlink = cifs_create_mf_symlink, |
1087 | .is_read_op = cifs_is_read_op, | 1093 | .is_read_op = cifs_is_read_op, |
1088 | .wp_retry_size = cifs_wp_retry_size, | 1094 | .wp_retry_size = cifs_wp_retry_size, |
1095 | .dir_needs_close = cifs_dir_needs_close, | ||
1089 | #ifdef CONFIG_CIFS_XATTR | 1096 | #ifdef CONFIG_CIFS_XATTR |
1090 | .query_all_EAs = CIFSSMBQAllEAs, | 1097 | .query_all_EAs = CIFSSMBQAllEAs, |
1091 | .set_EA = CIFSSMBSetEA, | 1098 | .set_EA = CIFSSMBSetEA, |
diff --git a/fs/cifs/smb2maperror.c b/fs/cifs/smb2maperror.c index e31a9dfdcd39..af59d03db492 100644 --- a/fs/cifs/smb2maperror.c +++ b/fs/cifs/smb2maperror.c | |||
@@ -214,7 +214,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = { | |||
214 | {STATUS_BREAKPOINT, -EIO, "STATUS_BREAKPOINT"}, | 214 | {STATUS_BREAKPOINT, -EIO, "STATUS_BREAKPOINT"}, |
215 | {STATUS_SINGLE_STEP, -EIO, "STATUS_SINGLE_STEP"}, | 215 | {STATUS_SINGLE_STEP, -EIO, "STATUS_SINGLE_STEP"}, |
216 | {STATUS_BUFFER_OVERFLOW, -EIO, "STATUS_BUFFER_OVERFLOW"}, | 216 | {STATUS_BUFFER_OVERFLOW, -EIO, "STATUS_BUFFER_OVERFLOW"}, |
217 | {STATUS_NO_MORE_FILES, -EIO, "STATUS_NO_MORE_FILES"}, | 217 | {STATUS_NO_MORE_FILES, -ENODATA, "STATUS_NO_MORE_FILES"}, |
218 | {STATUS_WAKE_SYSTEM_DEBUGGER, -EIO, "STATUS_WAKE_SYSTEM_DEBUGGER"}, | 218 | {STATUS_WAKE_SYSTEM_DEBUGGER, -EIO, "STATUS_WAKE_SYSTEM_DEBUGGER"}, |
219 | {STATUS_HANDLES_CLOSED, -EIO, "STATUS_HANDLES_CLOSED"}, | 219 | {STATUS_HANDLES_CLOSED, -EIO, "STATUS_HANDLES_CLOSED"}, |
220 | {STATUS_NO_INHERITANCE, -EIO, "STATUS_NO_INHERITANCE"}, | 220 | {STATUS_NO_INHERITANCE, -EIO, "STATUS_NO_INHERITANCE"}, |
@@ -298,7 +298,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = { | |||
298 | {STATUS_INVALID_PARAMETER, -EINVAL, "STATUS_INVALID_PARAMETER"}, | 298 | {STATUS_INVALID_PARAMETER, -EINVAL, "STATUS_INVALID_PARAMETER"}, |
299 | {STATUS_NO_SUCH_DEVICE, -ENODEV, "STATUS_NO_SUCH_DEVICE"}, | 299 | {STATUS_NO_SUCH_DEVICE, -ENODEV, "STATUS_NO_SUCH_DEVICE"}, |
300 | {STATUS_NO_SUCH_FILE, -ENOENT, "STATUS_NO_SUCH_FILE"}, | 300 | {STATUS_NO_SUCH_FILE, -ENOENT, "STATUS_NO_SUCH_FILE"}, |
301 | {STATUS_INVALID_DEVICE_REQUEST, -EIO, "STATUS_INVALID_DEVICE_REQUEST"}, | 301 | {STATUS_INVALID_DEVICE_REQUEST, -EOPNOTSUPP, "STATUS_INVALID_DEVICE_REQUEST"}, |
302 | {STATUS_END_OF_FILE, -ENODATA, "STATUS_END_OF_FILE"}, | 302 | {STATUS_END_OF_FILE, -ENODATA, "STATUS_END_OF_FILE"}, |
303 | {STATUS_WRONG_VOLUME, -EIO, "STATUS_WRONG_VOLUME"}, | 303 | {STATUS_WRONG_VOLUME, -EIO, "STATUS_WRONG_VOLUME"}, |
304 | {STATUS_NO_MEDIA_IN_DEVICE, -EIO, "STATUS_NO_MEDIA_IN_DEVICE"}, | 304 | {STATUS_NO_MEDIA_IN_DEVICE, -EIO, "STATUS_NO_MEDIA_IN_DEVICE"}, |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index f2e6ac29a8d6..4aa7a0f07d6e 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -178,9 +178,24 @@ smb2_check_message(char *buf, unsigned int length) | |||
178 | /* Windows 7 server returns 24 bytes more */ | 178 | /* Windows 7 server returns 24 bytes more */ |
179 | if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE) | 179 | if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE) |
180 | return 0; | 180 | return 0; |
181 | /* server can return one byte more */ | 181 | /* server can return one byte more due to implied bcc[0] */ |
182 | if (clc_len == 4 + len + 1) | 182 | if (clc_len == 4 + len + 1) |
183 | return 0; | 183 | return 0; |
184 | |||
185 | /* | ||
186 | * MacOS server pads after SMB2.1 write response with 3 bytes | ||
187 | * of junk. Other servers match RFC1001 len to actual | ||
188 | * SMB2/SMB3 frame length (header + smb2 response specific data) | ||
189 | * Log the server error (once), but allow it and continue | ||
190 | * since the frame is parseable. | ||
191 | */ | ||
192 | if (clc_len < 4 /* RFC1001 header size */ + len) { | ||
193 | printk_once(KERN_WARNING | ||
194 | "SMB2 server sent bad RFC1001 len %d not %d\n", | ||
195 | len, clc_len - 4); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
184 | return 1; | 199 | return 1; |
185 | } | 200 | } |
186 | return 0; | 201 | return 0; |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 77f8aeb9c2fc..5a48aa290dfe 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -731,11 +731,72 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile, | |||
731 | return SMB2_write(xid, parms, written, iov, nr_segs); | 731 | return SMB2_write(xid, parms, written, iov, nr_segs); |
732 | } | 732 | } |
733 | 733 | ||
734 | /* Set or clear the SPARSE_FILE attribute based on value passed in setsparse */ | ||
735 | static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon, | ||
736 | struct cifsFileInfo *cfile, struct inode *inode, __u8 setsparse) | ||
737 | { | ||
738 | struct cifsInodeInfo *cifsi; | ||
739 | int rc; | ||
740 | |||
741 | cifsi = CIFS_I(inode); | ||
742 | |||
743 | /* if file already sparse don't bother setting sparse again */ | ||
744 | if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && setsparse) | ||
745 | return true; /* already sparse */ | ||
746 | |||
747 | if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && !setsparse) | ||
748 | return true; /* already not sparse */ | ||
749 | |||
750 | /* | ||
751 | * Can't check for sparse support on share the usual way via the | ||
752 | * FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share | ||
753 | * since Samba server doesn't set the flag on the share, yet | ||
754 | * supports the set sparse FSCTL and returns sparse correctly | ||
755 | * in the file attributes. If we fail setting sparse though we | ||
756 | * mark that server does not support sparse files for this share | ||
757 | * to avoid repeatedly sending the unsupported fsctl to server | ||
758 | * if the file is repeatedly extended. | ||
759 | */ | ||
760 | if (tcon->broken_sparse_sup) | ||
761 | return false; | ||
762 | |||
763 | rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, | ||
764 | cfile->fid.volatile_fid, FSCTL_SET_SPARSE, | ||
765 | true /* is_fctl */, &setsparse, 1, NULL, NULL); | ||
766 | if (rc) { | ||
767 | tcon->broken_sparse_sup = true; | ||
768 | cifs_dbg(FYI, "set sparse rc = %d\n", rc); | ||
769 | return false; | ||
770 | } | ||
771 | |||
772 | if (setsparse) | ||
773 | cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE; | ||
774 | else | ||
775 | cifsi->cifsAttrs &= (~FILE_ATTRIBUTE_SPARSE_FILE); | ||
776 | |||
777 | return true; | ||
778 | } | ||
779 | |||
734 | static int | 780 | static int |
735 | smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, | 781 | smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, |
736 | struct cifsFileInfo *cfile, __u64 size, bool set_alloc) | 782 | struct cifsFileInfo *cfile, __u64 size, bool set_alloc) |
737 | { | 783 | { |
738 | __le64 eof = cpu_to_le64(size); | 784 | __le64 eof = cpu_to_le64(size); |
785 | struct inode *inode; | ||
786 | |||
787 | /* | ||
788 | * If extending file more than one page make sparse. Many Linux fs | ||
789 | * make files sparse by default when extending via ftruncate | ||
790 | */ | ||
791 | inode = cfile->dentry->d_inode; | ||
792 | |||
793 | if (!set_alloc && (size > inode->i_size + 8192)) { | ||
794 | __u8 set_sparse = 1; | ||
795 | |||
796 | /* whether set sparse succeeds or not, extend the file */ | ||
797 | smb2_set_sparse(xid, tcon, cfile, inode, set_sparse); | ||
798 | } | ||
799 | |||
739 | return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, | 800 | return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, |
740 | cfile->fid.volatile_fid, cfile->pid, &eof, false); | 801 | cfile->fid.volatile_fid, cfile->pid, &eof, false); |
741 | } | 802 | } |
@@ -954,6 +1015,105 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
954 | return rc; | 1015 | return rc; |
955 | } | 1016 | } |
956 | 1017 | ||
1018 | static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, | ||
1019 | loff_t offset, loff_t len, bool keep_size) | ||
1020 | { | ||
1021 | struct inode *inode; | ||
1022 | struct cifsInodeInfo *cifsi; | ||
1023 | struct cifsFileInfo *cfile = file->private_data; | ||
1024 | struct file_zero_data_information fsctl_buf; | ||
1025 | long rc; | ||
1026 | unsigned int xid; | ||
1027 | |||
1028 | xid = get_xid(); | ||
1029 | |||
1030 | inode = cfile->dentry->d_inode; | ||
1031 | cifsi = CIFS_I(inode); | ||
1032 | |||
1033 | /* if file not oplocked can't be sure whether asking to extend size */ | ||
1034 | if (!CIFS_CACHE_READ(cifsi)) | ||
1035 | if (keep_size == false) | ||
1036 | return -EOPNOTSUPP; | ||
1037 | |||
1038 | /* | ||
1039 | * Must check if file sparse since fallocate -z (zero range) assumes | ||
1040 | * non-sparse allocation | ||
1041 | */ | ||
1042 | if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) | ||
1043 | return -EOPNOTSUPP; | ||
1044 | |||
1045 | /* | ||
1046 | * need to make sure we are not asked to extend the file since the SMB3 | ||
1047 | * fsctl does not change the file size. In the future we could change | ||
1048 | * this to zero the first part of the range then set the file size | ||
1049 | * which for a non sparse file would zero the newly extended range | ||
1050 | */ | ||
1051 | if (keep_size == false) | ||
1052 | if (i_size_read(inode) < offset + len) | ||
1053 | return -EOPNOTSUPP; | ||
1054 | |||
1055 | cifs_dbg(FYI, "offset %lld len %lld", offset, len); | ||
1056 | |||
1057 | fsctl_buf.FileOffset = cpu_to_le64(offset); | ||
1058 | fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len); | ||
1059 | |||
1060 | rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, | ||
1061 | cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, | ||
1062 | true /* is_fctl */, (char *)&fsctl_buf, | ||
1063 | sizeof(struct file_zero_data_information), NULL, NULL); | ||
1064 | free_xid(xid); | ||
1065 | return rc; | ||
1066 | } | ||
1067 | |||
1068 | static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, | ||
1069 | loff_t offset, loff_t len) | ||
1070 | { | ||
1071 | struct inode *inode; | ||
1072 | struct cifsInodeInfo *cifsi; | ||
1073 | struct cifsFileInfo *cfile = file->private_data; | ||
1074 | struct file_zero_data_information fsctl_buf; | ||
1075 | long rc; | ||
1076 | unsigned int xid; | ||
1077 | __u8 set_sparse = 1; | ||
1078 | |||
1079 | xid = get_xid(); | ||
1080 | |||
1081 | inode = cfile->dentry->d_inode; | ||
1082 | cifsi = CIFS_I(inode); | ||
1083 | |||
1084 | /* Need to make file sparse, if not already, before freeing range. */ | ||
1085 | /* Consider adding equivalent for compressed since it could also work */ | ||
1086 | if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) | ||
1087 | return -EOPNOTSUPP; | ||
1088 | |||
1089 | cifs_dbg(FYI, "offset %lld len %lld", offset, len); | ||
1090 | |||
1091 | fsctl_buf.FileOffset = cpu_to_le64(offset); | ||
1092 | fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len); | ||
1093 | |||
1094 | rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, | ||
1095 | cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, | ||
1096 | true /* is_fctl */, (char *)&fsctl_buf, | ||
1097 | sizeof(struct file_zero_data_information), NULL, NULL); | ||
1098 | free_xid(xid); | ||
1099 | return rc; | ||
1100 | } | ||
1101 | |||
1102 | static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, | ||
1103 | loff_t off, loff_t len) | ||
1104 | { | ||
1105 | /* KEEP_SIZE already checked for by do_fallocate */ | ||
1106 | if (mode & FALLOC_FL_PUNCH_HOLE) | ||
1107 | return smb3_punch_hole(file, tcon, off, len); | ||
1108 | else if (mode & FALLOC_FL_ZERO_RANGE) { | ||
1109 | if (mode & FALLOC_FL_KEEP_SIZE) | ||
1110 | return smb3_zero_range(file, tcon, off, len, true); | ||
1111 | return smb3_zero_range(file, tcon, off, len, false); | ||
1112 | } | ||
1113 | |||
1114 | return -EOPNOTSUPP; | ||
1115 | } | ||
1116 | |||
957 | static void | 1117 | static void |
958 | smb2_downgrade_oplock(struct TCP_Server_Info *server, | 1118 | smb2_downgrade_oplock(struct TCP_Server_Info *server, |
959 | struct cifsInodeInfo *cinode, bool set_level2) | 1119 | struct cifsInodeInfo *cinode, bool set_level2) |
@@ -1161,6 +1321,12 @@ smb2_wp_retry_size(struct inode *inode) | |||
1161 | SMB2_MAX_BUFFER_SIZE); | 1321 | SMB2_MAX_BUFFER_SIZE); |
1162 | } | 1322 | } |
1163 | 1323 | ||
1324 | static bool | ||
1325 | smb2_dir_needs_close(struct cifsFileInfo *cfile) | ||
1326 | { | ||
1327 | return !cfile->invalidHandle; | ||
1328 | } | ||
1329 | |||
1164 | struct smb_version_operations smb20_operations = { | 1330 | struct smb_version_operations smb20_operations = { |
1165 | .compare_fids = smb2_compare_fids, | 1331 | .compare_fids = smb2_compare_fids, |
1166 | .setup_request = smb2_setup_request, | 1332 | .setup_request = smb2_setup_request, |
@@ -1236,6 +1402,7 @@ struct smb_version_operations smb20_operations = { | |||
1236 | .parse_lease_buf = smb2_parse_lease_buf, | 1402 | .parse_lease_buf = smb2_parse_lease_buf, |
1237 | .clone_range = smb2_clone_range, | 1403 | .clone_range = smb2_clone_range, |
1238 | .wp_retry_size = smb2_wp_retry_size, | 1404 | .wp_retry_size = smb2_wp_retry_size, |
1405 | .dir_needs_close = smb2_dir_needs_close, | ||
1239 | }; | 1406 | }; |
1240 | 1407 | ||
1241 | struct smb_version_operations smb21_operations = { | 1408 | struct smb_version_operations smb21_operations = { |
@@ -1313,6 +1480,7 @@ struct smb_version_operations smb21_operations = { | |||
1313 | .parse_lease_buf = smb2_parse_lease_buf, | 1480 | .parse_lease_buf = smb2_parse_lease_buf, |
1314 | .clone_range = smb2_clone_range, | 1481 | .clone_range = smb2_clone_range, |
1315 | .wp_retry_size = smb2_wp_retry_size, | 1482 | .wp_retry_size = smb2_wp_retry_size, |
1483 | .dir_needs_close = smb2_dir_needs_close, | ||
1316 | }; | 1484 | }; |
1317 | 1485 | ||
1318 | struct smb_version_operations smb30_operations = { | 1486 | struct smb_version_operations smb30_operations = { |
@@ -1393,6 +1561,8 @@ struct smb_version_operations smb30_operations = { | |||
1393 | .clone_range = smb2_clone_range, | 1561 | .clone_range = smb2_clone_range, |
1394 | .validate_negotiate = smb3_validate_negotiate, | 1562 | .validate_negotiate = smb3_validate_negotiate, |
1395 | .wp_retry_size = smb2_wp_retry_size, | 1563 | .wp_retry_size = smb2_wp_retry_size, |
1564 | .dir_needs_close = smb2_dir_needs_close, | ||
1565 | .fallocate = smb3_fallocate, | ||
1396 | }; | 1566 | }; |
1397 | 1567 | ||
1398 | struct smb_version_values smb20_values = { | 1568 | struct smb_version_values smb20_values = { |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 42ebc1a8be6c..fa0dd044213b 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -907,7 +907,8 @@ tcon_exit: | |||
907 | tcon_error_exit: | 907 | tcon_error_exit: |
908 | if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) { | 908 | if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) { |
909 | cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); | 909 | cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); |
910 | tcon->bad_network_name = true; | 910 | if (tcon) |
911 | tcon->bad_network_name = true; | ||
911 | } | 912 | } |
912 | goto tcon_exit; | 913 | goto tcon_exit; |
913 | } | 914 | } |
@@ -1224,7 +1225,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | |||
1224 | 1225 | ||
1225 | cifs_dbg(FYI, "SMB2 IOCTL\n"); | 1226 | cifs_dbg(FYI, "SMB2 IOCTL\n"); |
1226 | 1227 | ||
1227 | *out_data = NULL; | 1228 | if (out_data != NULL) |
1229 | *out_data = NULL; | ||
1230 | |||
1228 | /* zero out returned data len, in case of error */ | 1231 | /* zero out returned data len, in case of error */ |
1229 | if (plen) | 1232 | if (plen) |
1230 | *plen = 0; | 1233 | *plen = 0; |
@@ -2177,6 +2180,10 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, | |||
2177 | rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base; | 2180 | rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base; |
2178 | 2181 | ||
2179 | if (rc) { | 2182 | if (rc) { |
2183 | if (rc == -ENODATA && rsp->hdr.Status == STATUS_NO_MORE_FILES) { | ||
2184 | srch_inf->endOfSearch = true; | ||
2185 | rc = 0; | ||
2186 | } | ||
2180 | cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); | 2187 | cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); |
2181 | goto qdir_exit; | 2188 | goto qdir_exit; |
2182 | } | 2189 | } |
@@ -2214,11 +2221,6 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, | |||
2214 | else | 2221 | else |
2215 | cifs_dbg(VFS, "illegal search buffer type\n"); | 2222 | cifs_dbg(VFS, "illegal search buffer type\n"); |
2216 | 2223 | ||
2217 | if (rsp->hdr.Status == STATUS_NO_MORE_FILES) | ||
2218 | srch_inf->endOfSearch = 1; | ||
2219 | else | ||
2220 | srch_inf->endOfSearch = 0; | ||
2221 | |||
2222 | return rc; | 2224 | return rc; |
2223 | 2225 | ||
2224 | qdir_exit: | 2226 | qdir_exit: |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 69f3595d3952..fbe486c285a9 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -573,6 +573,12 @@ struct copychunk_ioctl { | |||
573 | __u32 Reserved2; | 573 | __u32 Reserved2; |
574 | } __packed; | 574 | } __packed; |
575 | 575 | ||
576 | /* this goes in the ioctl buffer when doing FSCTL_SET_ZERO_DATA */ | ||
577 | struct file_zero_data_information { | ||
578 | __le64 FileOffset; | ||
579 | __le64 BeyondFinalZero; | ||
580 | } __packed; | ||
581 | |||
576 | struct copychunk_ioctl_rsp { | 582 | struct copychunk_ioctl_rsp { |
577 | __le32 ChunksWritten; | 583 | __le32 ChunksWritten; |
578 | __le32 ChunkBytesWritten; | 584 | __le32 ChunkBytesWritten; |
diff --git a/fs/cifs/smbfsctl.h b/fs/cifs/smbfsctl.h index 0e538b5c9622..83efa59535be 100644 --- a/fs/cifs/smbfsctl.h +++ b/fs/cifs/smbfsctl.h | |||
@@ -63,7 +63,7 @@ | |||
63 | #define FSCTL_SET_OBJECT_ID_EXTENDED 0x000900BC /* BB add struct */ | 63 | #define FSCTL_SET_OBJECT_ID_EXTENDED 0x000900BC /* BB add struct */ |
64 | #define FSCTL_CREATE_OR_GET_OBJECT_ID 0x000900C0 /* BB add struct */ | 64 | #define FSCTL_CREATE_OR_GET_OBJECT_ID 0x000900C0 /* BB add struct */ |
65 | #define FSCTL_SET_SPARSE 0x000900C4 /* BB add struct */ | 65 | #define FSCTL_SET_SPARSE 0x000900C4 /* BB add struct */ |
66 | #define FSCTL_SET_ZERO_DATA 0x000900C8 /* BB add struct */ | 66 | #define FSCTL_SET_ZERO_DATA 0x000980C8 |
67 | #define FSCTL_SET_ENCRYPTION 0x000900D7 /* BB add struct */ | 67 | #define FSCTL_SET_ENCRYPTION 0x000900D7 /* BB add struct */ |
68 | #define FSCTL_ENCRYPTION_FSCTL_IO 0x000900DB /* BB add struct */ | 68 | #define FSCTL_ENCRYPTION_FSCTL_IO 0x000900DB /* BB add struct */ |
69 | #define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF /* BB add struct */ | 69 | #define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF /* BB add struct */ |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 08cdfe5461e3..622e88249024 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2828,8 +2828,9 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2828 | */ | 2828 | */ |
2829 | overhead += ngroups * (2 + sbi->s_itb_per_group); | 2829 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
2830 | 2830 | ||
2831 | /* Add the journal blocks as well */ | 2831 | /* Add the internal journal blocks as well */ |
2832 | overhead += sbi->s_journal->j_maxlen; | 2832 | if (sbi->s_journal && !sbi->journal_bdev) |
2833 | overhead += sbi->s_journal->j_maxlen; | ||
2833 | 2834 | ||
2834 | sbi->s_overhead_last = overhead; | 2835 | sbi->s_overhead_last = overhead; |
2835 | smp_wmb(); | 2836 | smp_wmb(); |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 4556ce1af5b0..5ddaf8625d3b 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -61,7 +61,7 @@ static void isofs_put_super(struct super_block *sb) | |||
61 | return; | 61 | return; |
62 | } | 62 | } |
63 | 63 | ||
64 | static int isofs_read_inode(struct inode *); | 64 | static int isofs_read_inode(struct inode *, int relocated); |
65 | static int isofs_statfs (struct dentry *, struct kstatfs *); | 65 | static int isofs_statfs (struct dentry *, struct kstatfs *); |
66 | 66 | ||
67 | static struct kmem_cache *isofs_inode_cachep; | 67 | static struct kmem_cache *isofs_inode_cachep; |
@@ -1259,7 +1259,7 @@ out_toomany: | |||
1259 | goto out; | 1259 | goto out; |
1260 | } | 1260 | } |
1261 | 1261 | ||
1262 | static int isofs_read_inode(struct inode *inode) | 1262 | static int isofs_read_inode(struct inode *inode, int relocated) |
1263 | { | 1263 | { |
1264 | struct super_block *sb = inode->i_sb; | 1264 | struct super_block *sb = inode->i_sb; |
1265 | struct isofs_sb_info *sbi = ISOFS_SB(sb); | 1265 | struct isofs_sb_info *sbi = ISOFS_SB(sb); |
@@ -1404,7 +1404,7 @@ static int isofs_read_inode(struct inode *inode) | |||
1404 | */ | 1404 | */ |
1405 | 1405 | ||
1406 | if (!high_sierra) { | 1406 | if (!high_sierra) { |
1407 | parse_rock_ridge_inode(de, inode); | 1407 | parse_rock_ridge_inode(de, inode, relocated); |
1408 | /* if we want uid/gid set, override the rock ridge setting */ | 1408 | /* if we want uid/gid set, override the rock ridge setting */ |
1409 | if (sbi->s_uid_set) | 1409 | if (sbi->s_uid_set) |
1410 | inode->i_uid = sbi->s_uid; | 1410 | inode->i_uid = sbi->s_uid; |
@@ -1483,9 +1483,10 @@ static int isofs_iget5_set(struct inode *ino, void *data) | |||
1483 | * offset that point to the underlying meta-data for the inode. The | 1483 | * offset that point to the underlying meta-data for the inode. The |
1484 | * code below is otherwise similar to the iget() code in | 1484 | * code below is otherwise similar to the iget() code in |
1485 | * include/linux/fs.h */ | 1485 | * include/linux/fs.h */ |
1486 | struct inode *isofs_iget(struct super_block *sb, | 1486 | struct inode *__isofs_iget(struct super_block *sb, |
1487 | unsigned long block, | 1487 | unsigned long block, |
1488 | unsigned long offset) | 1488 | unsigned long offset, |
1489 | int relocated) | ||
1489 | { | 1490 | { |
1490 | unsigned long hashval; | 1491 | unsigned long hashval; |
1491 | struct inode *inode; | 1492 | struct inode *inode; |
@@ -1507,7 +1508,7 @@ struct inode *isofs_iget(struct super_block *sb, | |||
1507 | return ERR_PTR(-ENOMEM); | 1508 | return ERR_PTR(-ENOMEM); |
1508 | 1509 | ||
1509 | if (inode->i_state & I_NEW) { | 1510 | if (inode->i_state & I_NEW) { |
1510 | ret = isofs_read_inode(inode); | 1511 | ret = isofs_read_inode(inode, relocated); |
1511 | if (ret < 0) { | 1512 | if (ret < 0) { |
1512 | iget_failed(inode); | 1513 | iget_failed(inode); |
1513 | inode = ERR_PTR(ret); | 1514 | inode = ERR_PTR(ret); |
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 99167238518d..0ac4c1f73fbd 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
@@ -107,7 +107,7 @@ extern int iso_date(char *, int); | |||
107 | 107 | ||
108 | struct inode; /* To make gcc happy */ | 108 | struct inode; /* To make gcc happy */ |
109 | 109 | ||
110 | extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *); | 110 | extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *, int relocated); |
111 | extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *); | 111 | extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *); |
112 | extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *); | 112 | extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *); |
113 | 113 | ||
@@ -118,9 +118,24 @@ extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int | |||
118 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); | 118 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); |
119 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); | 119 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); |
120 | 120 | ||
121 | extern struct inode *isofs_iget(struct super_block *sb, | 121 | struct inode *__isofs_iget(struct super_block *sb, |
122 | unsigned long block, | 122 | unsigned long block, |
123 | unsigned long offset); | 123 | unsigned long offset, |
124 | int relocated); | ||
125 | |||
126 | static inline struct inode *isofs_iget(struct super_block *sb, | ||
127 | unsigned long block, | ||
128 | unsigned long offset) | ||
129 | { | ||
130 | return __isofs_iget(sb, block, offset, 0); | ||
131 | } | ||
132 | |||
133 | static inline struct inode *isofs_iget_reloc(struct super_block *sb, | ||
134 | unsigned long block, | ||
135 | unsigned long offset) | ||
136 | { | ||
137 | return __isofs_iget(sb, block, offset, 1); | ||
138 | } | ||
124 | 139 | ||
125 | /* Because the inode number is no longer relevant to finding the | 140 | /* Because the inode number is no longer relevant to finding the |
126 | * underlying meta-data for an inode, we are free to choose a more | 141 | * underlying meta-data for an inode, we are free to choose a more |
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index c0bf42472e40..f488bbae541a 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c | |||
@@ -288,12 +288,16 @@ eio: | |||
288 | goto out; | 288 | goto out; |
289 | } | 289 | } |
290 | 290 | ||
291 | #define RR_REGARD_XA 1 | ||
292 | #define RR_RELOC_DE 2 | ||
293 | |||
291 | static int | 294 | static int |
292 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, | 295 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, |
293 | struct inode *inode, int regard_xa) | 296 | struct inode *inode, int flags) |
294 | { | 297 | { |
295 | int symlink_len = 0; | 298 | int symlink_len = 0; |
296 | int cnt, sig; | 299 | int cnt, sig; |
300 | unsigned int reloc_block; | ||
297 | struct inode *reloc; | 301 | struct inode *reloc; |
298 | struct rock_ridge *rr; | 302 | struct rock_ridge *rr; |
299 | int rootflag; | 303 | int rootflag; |
@@ -305,7 +309,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, | |||
305 | 309 | ||
306 | init_rock_state(&rs, inode); | 310 | init_rock_state(&rs, inode); |
307 | setup_rock_ridge(de, inode, &rs); | 311 | setup_rock_ridge(de, inode, &rs); |
308 | if (regard_xa) { | 312 | if (flags & RR_REGARD_XA) { |
309 | rs.chr += 14; | 313 | rs.chr += 14; |
310 | rs.len -= 14; | 314 | rs.len -= 14; |
311 | if (rs.len < 0) | 315 | if (rs.len < 0) |
@@ -485,12 +489,22 @@ repeat: | |||
485 | "relocated directory\n"); | 489 | "relocated directory\n"); |
486 | goto out; | 490 | goto out; |
487 | case SIG('C', 'L'): | 491 | case SIG('C', 'L'): |
488 | ISOFS_I(inode)->i_first_extent = | 492 | if (flags & RR_RELOC_DE) { |
489 | isonum_733(rr->u.CL.location); | 493 | printk(KERN_ERR |
490 | reloc = | 494 | "ISOFS: Recursive directory relocation " |
491 | isofs_iget(inode->i_sb, | 495 | "is not supported\n"); |
492 | ISOFS_I(inode)->i_first_extent, | 496 | goto eio; |
493 | 0); | 497 | } |
498 | reloc_block = isonum_733(rr->u.CL.location); | ||
499 | if (reloc_block == ISOFS_I(inode)->i_iget5_block && | ||
500 | ISOFS_I(inode)->i_iget5_offset == 0) { | ||
501 | printk(KERN_ERR | ||
502 | "ISOFS: Directory relocation points to " | ||
503 | "itself\n"); | ||
504 | goto eio; | ||
505 | } | ||
506 | ISOFS_I(inode)->i_first_extent = reloc_block; | ||
507 | reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0); | ||
494 | if (IS_ERR(reloc)) { | 508 | if (IS_ERR(reloc)) { |
495 | ret = PTR_ERR(reloc); | 509 | ret = PTR_ERR(reloc); |
496 | goto out; | 510 | goto out; |
@@ -637,9 +651,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) | |||
637 | return rpnt; | 651 | return rpnt; |
638 | } | 652 | } |
639 | 653 | ||
640 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | 654 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, |
655 | int relocated) | ||
641 | { | 656 | { |
642 | int result = parse_rock_ridge_inode_internal(de, inode, 0); | 657 | int flags = relocated ? RR_RELOC_DE : 0; |
658 | int result = parse_rock_ridge_inode_internal(de, inode, flags); | ||
643 | 659 | ||
644 | /* | 660 | /* |
645 | * if rockridge flag was reset and we didn't look for attributes | 661 | * if rockridge flag was reset and we didn't look for attributes |
@@ -647,7 +663,8 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | |||
647 | */ | 663 | */ |
648 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) | 664 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) |
649 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { | 665 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { |
650 | result = parse_rock_ridge_inode_internal(de, inode, 14); | 666 | result = parse_rock_ridge_inode_internal(de, inode, |
667 | flags | RR_REGARD_XA); | ||
651 | } | 668 | } |
652 | return result; | 669 | return result; |
653 | } | 670 | } |
diff --git a/fs/locks.c b/fs/locks.c index a6f54802d277..cb66fb05ad4a 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -247,6 +247,18 @@ void locks_free_lock(struct file_lock *fl) | |||
247 | } | 247 | } |
248 | EXPORT_SYMBOL(locks_free_lock); | 248 | EXPORT_SYMBOL(locks_free_lock); |
249 | 249 | ||
250 | static void | ||
251 | locks_dispose_list(struct list_head *dispose) | ||
252 | { | ||
253 | struct file_lock *fl; | ||
254 | |||
255 | while (!list_empty(dispose)) { | ||
256 | fl = list_first_entry(dispose, struct file_lock, fl_block); | ||
257 | list_del_init(&fl->fl_block); | ||
258 | locks_free_lock(fl); | ||
259 | } | ||
260 | } | ||
261 | |||
250 | void locks_init_lock(struct file_lock *fl) | 262 | void locks_init_lock(struct file_lock *fl) |
251 | { | 263 | { |
252 | memset(fl, 0, sizeof(struct file_lock)); | 264 | memset(fl, 0, sizeof(struct file_lock)); |
@@ -285,7 +297,8 @@ EXPORT_SYMBOL(__locks_copy_lock); | |||
285 | 297 | ||
286 | void locks_copy_lock(struct file_lock *new, struct file_lock *fl) | 298 | void locks_copy_lock(struct file_lock *new, struct file_lock *fl) |
287 | { | 299 | { |
288 | locks_release_private(new); | 300 | /* "new" must be a freshly-initialized lock */ |
301 | WARN_ON_ONCE(new->fl_ops); | ||
289 | 302 | ||
290 | __locks_copy_lock(new, fl); | 303 | __locks_copy_lock(new, fl); |
291 | new->fl_file = fl->fl_file; | 304 | new->fl_file = fl->fl_file; |
@@ -650,12 +663,16 @@ static void locks_unlink_lock(struct file_lock **thisfl_p) | |||
650 | * | 663 | * |
651 | * Must be called with i_lock held! | 664 | * Must be called with i_lock held! |
652 | */ | 665 | */ |
653 | static void locks_delete_lock(struct file_lock **thisfl_p) | 666 | static void locks_delete_lock(struct file_lock **thisfl_p, |
667 | struct list_head *dispose) | ||
654 | { | 668 | { |
655 | struct file_lock *fl = *thisfl_p; | 669 | struct file_lock *fl = *thisfl_p; |
656 | 670 | ||
657 | locks_unlink_lock(thisfl_p); | 671 | locks_unlink_lock(thisfl_p); |
658 | locks_free_lock(fl); | 672 | if (dispose) |
673 | list_add(&fl->fl_block, dispose); | ||
674 | else | ||
675 | locks_free_lock(fl); | ||
659 | } | 676 | } |
660 | 677 | ||
661 | /* Determine if lock sys_fl blocks lock caller_fl. Common functionality | 678 | /* Determine if lock sys_fl blocks lock caller_fl. Common functionality |
@@ -811,6 +828,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
811 | struct inode * inode = file_inode(filp); | 828 | struct inode * inode = file_inode(filp); |
812 | int error = 0; | 829 | int error = 0; |
813 | int found = 0; | 830 | int found = 0; |
831 | LIST_HEAD(dispose); | ||
814 | 832 | ||
815 | if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { | 833 | if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { |
816 | new_fl = locks_alloc_lock(); | 834 | new_fl = locks_alloc_lock(); |
@@ -833,7 +851,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
833 | if (request->fl_type == fl->fl_type) | 851 | if (request->fl_type == fl->fl_type) |
834 | goto out; | 852 | goto out; |
835 | found = 1; | 853 | found = 1; |
836 | locks_delete_lock(before); | 854 | locks_delete_lock(before, &dispose); |
837 | break; | 855 | break; |
838 | } | 856 | } |
839 | 857 | ||
@@ -880,6 +898,7 @@ out: | |||
880 | spin_unlock(&inode->i_lock); | 898 | spin_unlock(&inode->i_lock); |
881 | if (new_fl) | 899 | if (new_fl) |
882 | locks_free_lock(new_fl); | 900 | locks_free_lock(new_fl); |
901 | locks_dispose_list(&dispose); | ||
883 | return error; | 902 | return error; |
884 | } | 903 | } |
885 | 904 | ||
@@ -893,6 +912,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
893 | struct file_lock **before; | 912 | struct file_lock **before; |
894 | int error; | 913 | int error; |
895 | bool added = false; | 914 | bool added = false; |
915 | LIST_HEAD(dispose); | ||
896 | 916 | ||
897 | /* | 917 | /* |
898 | * We may need two file_lock structures for this operation, | 918 | * We may need two file_lock structures for this operation, |
@@ -988,7 +1008,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
988 | else | 1008 | else |
989 | request->fl_end = fl->fl_end; | 1009 | request->fl_end = fl->fl_end; |
990 | if (added) { | 1010 | if (added) { |
991 | locks_delete_lock(before); | 1011 | locks_delete_lock(before, &dispose); |
992 | continue; | 1012 | continue; |
993 | } | 1013 | } |
994 | request = fl; | 1014 | request = fl; |
@@ -1018,21 +1038,24 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1018 | * one (This may happen several times). | 1038 | * one (This may happen several times). |
1019 | */ | 1039 | */ |
1020 | if (added) { | 1040 | if (added) { |
1021 | locks_delete_lock(before); | 1041 | locks_delete_lock(before, &dispose); |
1022 | continue; | 1042 | continue; |
1023 | } | 1043 | } |
1024 | /* Replace the old lock with the new one. | 1044 | /* |
1025 | * Wake up anybody waiting for the old one, | 1045 | * Replace the old lock with new_fl, and |
1026 | * as the change in lock type might satisfy | 1046 | * remove the old one. It's safe to do the |
1027 | * their needs. | 1047 | * insert here since we know that we won't be |
1048 | * using new_fl later, and that the lock is | ||
1049 | * just replacing an existing lock. | ||
1028 | */ | 1050 | */ |
1029 | locks_wake_up_blocks(fl); | 1051 | error = -ENOLCK; |
1030 | fl->fl_start = request->fl_start; | 1052 | if (!new_fl) |
1031 | fl->fl_end = request->fl_end; | 1053 | goto out; |
1032 | fl->fl_type = request->fl_type; | 1054 | locks_copy_lock(new_fl, request); |
1033 | locks_release_private(fl); | 1055 | request = new_fl; |
1034 | locks_copy_private(fl, request); | 1056 | new_fl = NULL; |
1035 | request = fl; | 1057 | locks_delete_lock(before, &dispose); |
1058 | locks_insert_lock(before, request); | ||
1036 | added = true; | 1059 | added = true; |
1037 | } | 1060 | } |
1038 | } | 1061 | } |
@@ -1093,6 +1116,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1093 | locks_free_lock(new_fl); | 1116 | locks_free_lock(new_fl); |
1094 | if (new_fl2) | 1117 | if (new_fl2) |
1095 | locks_free_lock(new_fl2); | 1118 | locks_free_lock(new_fl2); |
1119 | locks_dispose_list(&dispose); | ||
1096 | return error; | 1120 | return error; |
1097 | } | 1121 | } |
1098 | 1122 | ||
@@ -1268,7 +1292,7 @@ int lease_modify(struct file_lock **before, int arg) | |||
1268 | printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); | 1292 | printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); |
1269 | fl->fl_fasync = NULL; | 1293 | fl->fl_fasync = NULL; |
1270 | } | 1294 | } |
1271 | locks_delete_lock(before); | 1295 | locks_delete_lock(before, NULL); |
1272 | } | 1296 | } |
1273 | return 0; | 1297 | return 0; |
1274 | } | 1298 | } |
@@ -1737,13 +1761,10 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1737 | ret = fl; | 1761 | ret = fl; |
1738 | spin_lock(&inode->i_lock); | 1762 | spin_lock(&inode->i_lock); |
1739 | error = __vfs_setlease(filp, arg, &ret); | 1763 | error = __vfs_setlease(filp, arg, &ret); |
1740 | if (error) { | 1764 | if (error) |
1741 | spin_unlock(&inode->i_lock); | 1765 | goto out_unlock; |
1742 | locks_free_lock(fl); | 1766 | if (ret == fl) |
1743 | goto out_free_fasync; | 1767 | fl = NULL; |
1744 | } | ||
1745 | if (ret != fl) | ||
1746 | locks_free_lock(fl); | ||
1747 | 1768 | ||
1748 | /* | 1769 | /* |
1749 | * fasync_insert_entry() returns the old entry if any. | 1770 | * fasync_insert_entry() returns the old entry if any. |
@@ -1755,9 +1776,10 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1755 | new = NULL; | 1776 | new = NULL; |
1756 | 1777 | ||
1757 | error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); | 1778 | error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); |
1779 | out_unlock: | ||
1758 | spin_unlock(&inode->i_lock); | 1780 | spin_unlock(&inode->i_lock); |
1759 | 1781 | if (fl) | |
1760 | out_free_fasync: | 1782 | locks_free_lock(fl); |
1761 | if (new) | 1783 | if (new) |
1762 | fasync_free(new); | 1784 | fasync_free(new); |
1763 | return error; | 1785 | return error; |
@@ -2320,6 +2342,7 @@ void locks_remove_file(struct file *filp) | |||
2320 | struct inode * inode = file_inode(filp); | 2342 | struct inode * inode = file_inode(filp); |
2321 | struct file_lock *fl; | 2343 | struct file_lock *fl; |
2322 | struct file_lock **before; | 2344 | struct file_lock **before; |
2345 | LIST_HEAD(dispose); | ||
2323 | 2346 | ||
2324 | if (!inode->i_flock) | 2347 | if (!inode->i_flock) |
2325 | return; | 2348 | return; |
@@ -2365,12 +2388,13 @@ void locks_remove_file(struct file *filp) | |||
2365 | fl->fl_type, fl->fl_flags, | 2388 | fl->fl_type, fl->fl_flags, |
2366 | fl->fl_start, fl->fl_end); | 2389 | fl->fl_start, fl->fl_end); |
2367 | 2390 | ||
2368 | locks_delete_lock(before); | 2391 | locks_delete_lock(before, &dispose); |
2369 | continue; | 2392 | continue; |
2370 | } | 2393 | } |
2371 | before = &fl->fl_next; | 2394 | before = &fl->fl_next; |
2372 | } | 2395 | } |
2373 | spin_unlock(&inode->i_lock); | 2396 | spin_unlock(&inode->i_lock); |
2397 | locks_dispose_list(&dispose); | ||
2374 | } | 2398 | } |
2375 | 2399 | ||
2376 | /** | 2400 | /** |
@@ -2452,7 +2476,11 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, | |||
2452 | seq_puts(f, "FLOCK ADVISORY "); | 2476 | seq_puts(f, "FLOCK ADVISORY "); |
2453 | } | 2477 | } |
2454 | } else if (IS_LEASE(fl)) { | 2478 | } else if (IS_LEASE(fl)) { |
2455 | seq_puts(f, "LEASE "); | 2479 | if (fl->fl_flags & FL_DELEG) |
2480 | seq_puts(f, "DELEG "); | ||
2481 | else | ||
2482 | seq_puts(f, "LEASE "); | ||
2483 | |||
2456 | if (lease_breaking(fl)) | 2484 | if (lease_breaking(fl)) |
2457 | seq_puts(f, "BREAKING "); | 2485 | seq_puts(f, "BREAKING "); |
2458 | else if (fl->fl_file) | 2486 | else if (fl->fl_file) |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 9737cba1357d..83a06001742b 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -1014,7 +1014,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1014 | 1014 | ||
1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1016 | if (!fi) | 1016 | if (!fi) |
1017 | goto out_no_entry; | 1017 | goto out_fail; |
1018 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); | 1018 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); |
1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
1020 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { | 1020 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
@@ -1036,6 +1036,7 @@ out: | |||
1036 | 1036 | ||
1037 | out_no_entry: | 1037 | out_no_entry: |
1038 | up_write(&iinfo->i_data_sem); | 1038 | up_write(&iinfo->i_data_sem); |
1039 | out_fail: | ||
1039 | inode_dec_link_count(inode); | 1040 | inode_dec_link_count(inode); |
1040 | iput(inode); | 1041 | iput(inode); |
1041 | goto out; | 1042 | goto out; |
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 6f76277baf39..61219b9b3445 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h | |||
@@ -16,7 +16,6 @@ | |||
16 | #define PHY_ID_BCM7366 0x600d8490 | 16 | #define PHY_ID_BCM7366 0x600d8490 |
17 | #define PHY_ID_BCM7439 0x600d8480 | 17 | #define PHY_ID_BCM7439 0x600d8480 |
18 | #define PHY_ID_BCM7445 0x600d8510 | 18 | #define PHY_ID_BCM7445 0x600d8510 |
19 | #define PHY_ID_BCM7XXX_28 0x600d8400 | ||
20 | 19 | ||
21 | #define PHY_BCM_OUI_MASK 0xfffffc00 | 20 | #define PHY_BCM_OUI_MASK 0xfffffc00 |
22 | #define PHY_BCM_OUI_1 0x00206000 | 21 | #define PHY_BCM_OUI_1 0x00206000 |
diff --git a/include/linux/edac.h b/include/linux/edac.h index 8e6c20af11a2..e1e68da6f35c 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h | |||
@@ -194,6 +194,9 @@ static inline char *mc_event_error_type(const unsigned int err_type) | |||
194 | * @MEM_DDR3: DDR3 RAM | 194 | * @MEM_DDR3: DDR3 RAM |
195 | * @MEM_RDDR3: Registered DDR3 RAM | 195 | * @MEM_RDDR3: Registered DDR3 RAM |
196 | * This is a variant of the DDR3 memories. | 196 | * This is a variant of the DDR3 memories. |
197 | * @MEM_DDR4: DDR4 RAM | ||
198 | * @MEM_RDDR4: Registered DDR4 RAM | ||
199 | * This is a variant of the DDR4 memories. | ||
197 | */ | 200 | */ |
198 | enum mem_type { | 201 | enum mem_type { |
199 | MEM_EMPTY = 0, | 202 | MEM_EMPTY = 0, |
@@ -213,6 +216,8 @@ enum mem_type { | |||
213 | MEM_XDR, | 216 | MEM_XDR, |
214 | MEM_DDR3, | 217 | MEM_DDR3, |
215 | MEM_RDDR3, | 218 | MEM_RDDR3, |
219 | MEM_DDR4, | ||
220 | MEM_RDDR4, | ||
216 | }; | 221 | }; |
217 | 222 | ||
218 | #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) | 223 | #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index ea507665896c..a95efeb53a8b 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -577,16 +577,20 @@ static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node | |||
577 | } | 577 | } |
578 | #endif /* CONFIG_OF */ | 578 | #endif /* CONFIG_OF */ |
579 | 579 | ||
580 | #ifdef CONFIG_I2C_ACPI | 580 | #ifdef CONFIG_ACPI |
581 | int acpi_i2c_install_space_handler(struct i2c_adapter *adapter); | ||
582 | void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter); | ||
583 | void acpi_i2c_register_devices(struct i2c_adapter *adap); | 581 | void acpi_i2c_register_devices(struct i2c_adapter *adap); |
584 | #else | 582 | #else |
585 | static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) { } | 583 | static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) { } |
584 | #endif /* CONFIG_ACPI */ | ||
585 | |||
586 | #ifdef CONFIG_ACPI_I2C_OPREGION | ||
587 | int acpi_i2c_install_space_handler(struct i2c_adapter *adapter); | ||
588 | void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter); | ||
589 | #else | ||
586 | static inline void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter) | 590 | static inline void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter) |
587 | { } | 591 | { } |
588 | static inline int acpi_i2c_install_space_handler(struct i2c_adapter *adapter) | 592 | static inline int acpi_i2c_install_space_handler(struct i2c_adapter *adapter) |
589 | { return 0; } | 593 | { return 0; } |
590 | #endif | 594 | #endif /* CONFIG_ACPI_I2C_OPREGION */ |
591 | 595 | ||
592 | #endif /* _LINUX_I2C_H */ | 596 | #endif /* _LINUX_I2C_H */ |
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 1b1dfa80d9ff..f583ff639776 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h | |||
@@ -105,6 +105,7 @@ void input_mt_report_slot_state(struct input_dev *dev, | |||
105 | 105 | ||
106 | void input_mt_report_finger_count(struct input_dev *dev, int count); | 106 | void input_mt_report_finger_count(struct input_dev *dev, int count); |
107 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); | 107 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); |
108 | void input_mt_drop_unused(struct input_dev *dev); | ||
108 | 109 | ||
109 | void input_mt_sync_frame(struct input_dev *dev); | 110 | void input_mt_sync_frame(struct input_dev *dev); |
110 | 111 | ||
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index fd0421c6d40a..95ed9424a11a 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h | |||
@@ -527,6 +527,7 @@ enum iscsi_err { | |||
527 | ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, | 527 | ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, |
528 | ISCSI_ERR_TCP_CONN_CLOSE = ISCSI_ERR_BASE + 20, | 528 | ISCSI_ERR_TCP_CONN_CLOSE = ISCSI_ERR_BASE + 20, |
529 | ISCSI_ERR_SCSI_EH_SESSION_RST = ISCSI_ERR_BASE + 21, | 529 | ISCSI_ERR_SCSI_EH_SESSION_RST = ISCSI_ERR_BASE + 21, |
530 | ISCSI_ERR_NOP_TIMEDOUT = ISCSI_ERR_BASE + 22, | ||
530 | }; | 531 | }; |
531 | 532 | ||
532 | /* | 533 | /* |
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index f1afd607f043..11d11bc5c78f 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h | |||
@@ -703,9 +703,11 @@ __SYSCALL(__NR_renameat2, sys_renameat2) | |||
703 | __SYSCALL(__NR_seccomp, sys_seccomp) | 703 | __SYSCALL(__NR_seccomp, sys_seccomp) |
704 | #define __NR_getrandom 278 | 704 | #define __NR_getrandom 278 |
705 | __SYSCALL(__NR_getrandom, sys_getrandom) | 705 | __SYSCALL(__NR_getrandom, sys_getrandom) |
706 | #define __NR_memfd_create 279 | ||
707 | __SYSCALL(__NR_memfd_create, sys_memfd_create) | ||
706 | 708 | ||
707 | #undef __NR_syscalls | 709 | #undef __NR_syscalls |
708 | #define __NR_syscalls 279 | 710 | #define __NR_syscalls 280 |
709 | 711 | ||
710 | /* | 712 | /* |
711 | * All syscalls below here should go away really, | 713 | * All syscalls below here should go away really, |
diff --git a/kernel/module.c b/kernel/module.c index 6f69463f0066..03214bd288e9 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -3304,6 +3304,11 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3304 | mutex_lock(&module_mutex); | 3304 | mutex_lock(&module_mutex); |
3305 | module_bug_cleanup(mod); | 3305 | module_bug_cleanup(mod); |
3306 | mutex_unlock(&module_mutex); | 3306 | mutex_unlock(&module_mutex); |
3307 | |||
3308 | /* we can't deallocate the module until we clear memory protection */ | ||
3309 | unset_module_init_ro_nx(mod); | ||
3310 | unset_module_core_ro_nx(mod); | ||
3311 | |||
3307 | ddebug_cleanup: | 3312 | ddebug_cleanup: |
3308 | dynamic_debug_remove(info->debug); | 3313 | dynamic_debug_remove(info->debug); |
3309 | synchronize_sched(); | 3314 | synchronize_sched(); |
diff --git a/net/atm/lec.c b/net/atm/lec.c index e4853b50cf40..4b98f897044a 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
@@ -410,9 +410,11 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) | |||
410 | priv->lane2_ops = NULL; | 410 | priv->lane2_ops = NULL; |
411 | if (priv->lane_version > 1) | 411 | if (priv->lane_version > 1) |
412 | priv->lane2_ops = &lane2_ops; | 412 | priv->lane2_ops = &lane2_ops; |
413 | rtnl_lock(); | ||
413 | if (dev_set_mtu(dev, mesg->content.config.mtu)) | 414 | if (dev_set_mtu(dev, mesg->content.config.mtu)) |
414 | pr_info("%s: change_mtu to %d failed\n", | 415 | pr_info("%s: change_mtu to %d failed\n", |
415 | dev->name, mesg->content.config.mtu); | 416 | dev->name, mesg->content.config.mtu); |
417 | rtnl_unlock(); | ||
416 | priv->is_proxy = mesg->content.config.is_proxy; | 418 | priv->is_proxy = mesg->content.config.is_proxy; |
417 | break; | 419 | break; |
418 | case l_flush_tran_id: | 420 | case l_flush_tran_id: |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 52c43f904220..fc1835c6bb40 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -188,7 +188,7 @@ static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node, | |||
188 | 188 | ||
189 | /* Reached the end of the list, so insert after 'frag_entry_last'. */ | 189 | /* Reached the end of the list, so insert after 'frag_entry_last'. */ |
190 | if (likely(frag_entry_last)) { | 190 | if (likely(frag_entry_last)) { |
191 | hlist_add_behind(&frag_entry_last->list, &frag_entry_new->list); | 191 | hlist_add_behind(&frag_entry_new->list, &frag_entry_last->list); |
192 | chain->size += skb->len - hdr_size; | 192 | chain->size += skb->len - hdr_size; |
193 | chain->timestamp = jiffies; | 193 | chain->timestamp = jiffies; |
194 | ret = true; | 194 | ret = true; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index cb4459bd1d29..76b7f5ee8f4c 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -643,7 +643,7 @@ static int fib6_commit_metrics(struct dst_entry *dst, | |||
643 | if (dst->flags & DST_HOST) { | 643 | if (dst->flags & DST_HOST) { |
644 | mp = dst_metrics_write_ptr(dst); | 644 | mp = dst_metrics_write_ptr(dst); |
645 | } else { | 645 | } else { |
646 | mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); | 646 | mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC); |
647 | if (!mp) | 647 | if (!mp) |
648 | return -ENOMEM; | 648 | return -ENOMEM; |
649 | dst_init_metrics(dst, mp, 0); | 649 | dst_init_metrics(dst, mp, 0); |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 6d537f03c0ba..0375009ddc0d 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -1444,7 +1444,7 @@ ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) | |||
1444 | 1444 | ||
1445 | list_del(&sdata->reserved_chanctx_list); | 1445 | list_del(&sdata->reserved_chanctx_list); |
1446 | list_move(&sdata->assigned_chanctx_list, | 1446 | list_move(&sdata->assigned_chanctx_list, |
1447 | &new_ctx->assigned_vifs); | 1447 | &ctx->assigned_vifs); |
1448 | sdata->reserved_chanctx = NULL; | 1448 | sdata->reserved_chanctx = NULL; |
1449 | 1449 | ||
1450 | ieee80211_vif_chanctx_reservation_complete(sdata); | 1450 | ieee80211_vif_chanctx_reservation_complete(sdata); |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index fe5cda0deb39..5231652a95d9 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -42,6 +42,9 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
42 | 42 | ||
43 | static int make_writable(struct sk_buff *skb, int write_len) | 43 | static int make_writable(struct sk_buff *skb, int write_len) |
44 | { | 44 | { |
45 | if (!pskb_may_pull(skb, write_len)) | ||
46 | return -ENOMEM; | ||
47 | |||
45 | if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) | 48 | if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) |
46 | return 0; | 49 | return 0; |
47 | 50 | ||
@@ -70,6 +73,8 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) | |||
70 | 73 | ||
71 | vlan_set_encap_proto(skb, vhdr); | 74 | vlan_set_encap_proto(skb, vhdr); |
72 | skb->mac_header += VLAN_HLEN; | 75 | skb->mac_header += VLAN_HLEN; |
76 | if (skb_network_offset(skb) < ETH_HLEN) | ||
77 | skb_set_network_header(skb, ETH_HLEN); | ||
73 | skb_reset_mac_len(skb); | 78 | skb_reset_mac_len(skb); |
74 | 79 | ||
75 | return 0; | 80 | return 0; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8d9f8042705a..93896d2092f6 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -632,6 +632,7 @@ static void init_prb_bdqc(struct packet_sock *po, | |||
632 | p1->tov_in_jiffies = msecs_to_jiffies(p1->retire_blk_tov); | 632 | p1->tov_in_jiffies = msecs_to_jiffies(p1->retire_blk_tov); |
633 | p1->blk_sizeof_priv = req_u->req3.tp_sizeof_priv; | 633 | p1->blk_sizeof_priv = req_u->req3.tp_sizeof_priv; |
634 | 634 | ||
635 | p1->max_frame_len = p1->kblk_size - BLK_PLUS_PRIV(p1->blk_sizeof_priv); | ||
635 | prb_init_ft_ops(p1, req_u); | 636 | prb_init_ft_ops(p1, req_u); |
636 | prb_setup_retire_blk_timer(po, tx_ring); | 637 | prb_setup_retire_blk_timer(po, tx_ring); |
637 | prb_open_block(p1, pbd); | 638 | prb_open_block(p1, pbd); |
@@ -1942,6 +1943,18 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
1942 | if ((int)snaplen < 0) | 1943 | if ((int)snaplen < 0) |
1943 | snaplen = 0; | 1944 | snaplen = 0; |
1944 | } | 1945 | } |
1946 | } else if (unlikely(macoff + snaplen > | ||
1947 | GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len)) { | ||
1948 | u32 nval; | ||
1949 | |||
1950 | nval = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len - macoff; | ||
1951 | pr_err_once("tpacket_rcv: packet too big, clamped from %u to %u. macoff=%u\n", | ||
1952 | snaplen, nval, macoff); | ||
1953 | snaplen = nval; | ||
1954 | if (unlikely((int)snaplen < 0)) { | ||
1955 | snaplen = 0; | ||
1956 | macoff = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len; | ||
1957 | } | ||
1945 | } | 1958 | } |
1946 | spin_lock(&sk->sk_receive_queue.lock); | 1959 | spin_lock(&sk->sk_receive_queue.lock); |
1947 | h.raw = packet_current_rx_frame(po, skb, | 1960 | h.raw = packet_current_rx_frame(po, skb, |
@@ -3783,6 +3796,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
3783 | goto out; | 3796 | goto out; |
3784 | if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) | 3797 | if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) |
3785 | goto out; | 3798 | goto out; |
3799 | if (po->tp_version >= TPACKET_V3 && | ||
3800 | (int)(req->tp_block_size - | ||
3801 | BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) | ||
3802 | goto out; | ||
3786 | if (unlikely(req->tp_frame_size < po->tp_hdrlen + | 3803 | if (unlikely(req->tp_frame_size < po->tp_hdrlen + |
3787 | po->tp_reserve)) | 3804 | po->tp_reserve)) |
3788 | goto out; | 3805 | goto out; |
diff --git a/net/packet/internal.h b/net/packet/internal.h index eb9580a6b25f..cdddf6a30399 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h | |||
@@ -29,6 +29,7 @@ struct tpacket_kbdq_core { | |||
29 | char *pkblk_start; | 29 | char *pkblk_start; |
30 | char *pkblk_end; | 30 | char *pkblk_end; |
31 | int kblk_size; | 31 | int kblk_size; |
32 | unsigned int max_frame_len; | ||
32 | unsigned int knum_blocks; | 33 | unsigned int knum_blocks; |
33 | uint64_t knxt_seq_num; | 34 | uint64_t knxt_seq_num; |
34 | char *prev; | 35 | char *prev; |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index ead526467cca..762a04bb8f6d 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -159,7 +159,6 @@ struct cbq_sched_data { | |||
159 | struct cbq_class *tx_borrowed; | 159 | struct cbq_class *tx_borrowed; |
160 | int tx_len; | 160 | int tx_len; |
161 | psched_time_t now; /* Cached timestamp */ | 161 | psched_time_t now; /* Cached timestamp */ |
162 | psched_time_t now_rt; /* Cached real time */ | ||
163 | unsigned int pmask; | 162 | unsigned int pmask; |
164 | 163 | ||
165 | struct hrtimer delay_timer; | 164 | struct hrtimer delay_timer; |
@@ -353,12 +352,7 @@ cbq_mark_toplevel(struct cbq_sched_data *q, struct cbq_class *cl) | |||
353 | int toplevel = q->toplevel; | 352 | int toplevel = q->toplevel; |
354 | 353 | ||
355 | if (toplevel > cl->level && !(qdisc_is_throttled(cl->q))) { | 354 | if (toplevel > cl->level && !(qdisc_is_throttled(cl->q))) { |
356 | psched_time_t now; | 355 | psched_time_t now = psched_get_time(); |
357 | psched_tdiff_t incr; | ||
358 | |||
359 | now = psched_get_time(); | ||
360 | incr = now - q->now_rt; | ||
361 | now = q->now + incr; | ||
362 | 356 | ||
363 | do { | 357 | do { |
364 | if (cl->undertime < now) { | 358 | if (cl->undertime < now) { |
@@ -700,8 +694,13 @@ cbq_update(struct cbq_sched_data *q) | |||
700 | struct cbq_class *this = q->tx_class; | 694 | struct cbq_class *this = q->tx_class; |
701 | struct cbq_class *cl = this; | 695 | struct cbq_class *cl = this; |
702 | int len = q->tx_len; | 696 | int len = q->tx_len; |
697 | psched_time_t now; | ||
703 | 698 | ||
704 | q->tx_class = NULL; | 699 | q->tx_class = NULL; |
700 | /* Time integrator. We calculate EOS time | ||
701 | * by adding expected packet transmission time. | ||
702 | */ | ||
703 | now = q->now + L2T(&q->link, len); | ||
705 | 704 | ||
706 | for ( ; cl; cl = cl->share) { | 705 | for ( ; cl; cl = cl->share) { |
707 | long avgidle = cl->avgidle; | 706 | long avgidle = cl->avgidle; |
@@ -717,7 +716,7 @@ cbq_update(struct cbq_sched_data *q) | |||
717 | * idle = (now - last) - last_pktlen/rate | 716 | * idle = (now - last) - last_pktlen/rate |
718 | */ | 717 | */ |
719 | 718 | ||
720 | idle = q->now - cl->last; | 719 | idle = now - cl->last; |
721 | if ((unsigned long)idle > 128*1024*1024) { | 720 | if ((unsigned long)idle > 128*1024*1024) { |
722 | avgidle = cl->maxidle; | 721 | avgidle = cl->maxidle; |
723 | } else { | 722 | } else { |
@@ -761,7 +760,7 @@ cbq_update(struct cbq_sched_data *q) | |||
761 | idle -= L2T(&q->link, len); | 760 | idle -= L2T(&q->link, len); |
762 | idle += L2T(cl, len); | 761 | idle += L2T(cl, len); |
763 | 762 | ||
764 | cl->undertime = q->now + idle; | 763 | cl->undertime = now + idle; |
765 | } else { | 764 | } else { |
766 | /* Underlimit */ | 765 | /* Underlimit */ |
767 | 766 | ||
@@ -771,7 +770,8 @@ cbq_update(struct cbq_sched_data *q) | |||
771 | else | 770 | else |
772 | cl->avgidle = avgidle; | 771 | cl->avgidle = avgidle; |
773 | } | 772 | } |
774 | cl->last = q->now; | 773 | if ((s64)(now - cl->last) > 0) |
774 | cl->last = now; | ||
775 | } | 775 | } |
776 | 776 | ||
777 | cbq_update_toplevel(q, this, q->tx_borrowed); | 777 | cbq_update_toplevel(q, this, q->tx_borrowed); |
@@ -943,31 +943,13 @@ cbq_dequeue(struct Qdisc *sch) | |||
943 | struct sk_buff *skb; | 943 | struct sk_buff *skb; |
944 | struct cbq_sched_data *q = qdisc_priv(sch); | 944 | struct cbq_sched_data *q = qdisc_priv(sch); |
945 | psched_time_t now; | 945 | psched_time_t now; |
946 | psched_tdiff_t incr; | ||
947 | 946 | ||
948 | now = psched_get_time(); | 947 | now = psched_get_time(); |
949 | incr = now - q->now_rt; | 948 | |
950 | 949 | if (q->tx_class) | |
951 | if (q->tx_class) { | ||
952 | psched_tdiff_t incr2; | ||
953 | /* Time integrator. We calculate EOS time | ||
954 | * by adding expected packet transmission time. | ||
955 | * If real time is greater, we warp artificial clock, | ||
956 | * so that: | ||
957 | * | ||
958 | * cbq_time = max(real_time, work); | ||
959 | */ | ||
960 | incr2 = L2T(&q->link, q->tx_len); | ||
961 | q->now += incr2; | ||
962 | cbq_update(q); | 950 | cbq_update(q); |
963 | if ((incr -= incr2) < 0) | 951 | |
964 | incr = 0; | 952 | q->now = now; |
965 | q->now += incr; | ||
966 | } else { | ||
967 | if (now > q->now) | ||
968 | q->now = now; | ||
969 | } | ||
970 | q->now_rt = now; | ||
971 | 953 | ||
972 | for (;;) { | 954 | for (;;) { |
973 | q->wd_expires = 0; | 955 | q->wd_expires = 0; |
@@ -1223,7 +1205,6 @@ cbq_reset(struct Qdisc *sch) | |||
1223 | hrtimer_cancel(&q->delay_timer); | 1205 | hrtimer_cancel(&q->delay_timer); |
1224 | q->toplevel = TC_CBQ_MAXLEVEL; | 1206 | q->toplevel = TC_CBQ_MAXLEVEL; |
1225 | q->now = psched_get_time(); | 1207 | q->now = psched_get_time(); |
1226 | q->now_rt = q->now; | ||
1227 | 1208 | ||
1228 | for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++) | 1209 | for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++) |
1229 | q->active[prio] = NULL; | 1210 | q->active[prio] = NULL; |
@@ -1407,7 +1388,6 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) | |||
1407 | q->delay_timer.function = cbq_undelay; | 1388 | q->delay_timer.function = cbq_undelay; |
1408 | q->toplevel = TC_CBQ_MAXLEVEL; | 1389 | q->toplevel = TC_CBQ_MAXLEVEL; |
1409 | q->now = psched_get_time(); | 1390 | q->now = psched_get_time(); |
1410 | q->now_rt = q->now; | ||
1411 | 1391 | ||
1412 | cbq_link_class(&q->link); | 1392 | cbq_link_class(&q->link); |
1413 | 1393 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 06a9ee6b2d3a..a88b8524846e 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -813,6 +813,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, | |||
813 | else { | 813 | else { |
814 | dst_release(transport->dst); | 814 | dst_release(transport->dst); |
815 | transport->dst = NULL; | 815 | transport->dst = NULL; |
816 | ulp_notify = false; | ||
816 | } | 817 | } |
817 | 818 | ||
818 | spc_state = SCTP_ADDR_UNREACHABLE; | 819 | spc_state = SCTP_ADDR_UNREACHABLE; |
@@ -1244,7 +1245,7 @@ static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr, | |||
1244 | { | 1245 | { |
1245 | u8 score_curr, score_best; | 1246 | u8 score_curr, score_best; |
1246 | 1247 | ||
1247 | if (best == NULL) | 1248 | if (best == NULL || curr == best) |
1248 | return curr; | 1249 | return curr; |
1249 | 1250 | ||
1250 | score_curr = sctp_trans_score(curr); | 1251 | score_curr = sctp_trans_score(curr); |
@@ -1355,14 +1356,11 @@ static void sctp_select_active_and_retran_path(struct sctp_association *asoc) | |||
1355 | trans_sec = trans_pri; | 1356 | trans_sec = trans_pri; |
1356 | 1357 | ||
1357 | /* If we failed to find a usable transport, just camp on the | 1358 | /* If we failed to find a usable transport, just camp on the |
1358 | * primary or retran, even if they are inactive, if possible | 1359 | * active or pick a PF iff it's the better choice. |
1359 | * pick a PF iff it's the better choice. | ||
1360 | */ | 1360 | */ |
1361 | if (trans_pri == NULL) { | 1361 | if (trans_pri == NULL) { |
1362 | trans_pri = sctp_trans_elect_best(asoc->peer.primary_path, | 1362 | trans_pri = sctp_trans_elect_best(asoc->peer.active_path, trans_pf); |
1363 | asoc->peer.retran_path); | 1363 | trans_sec = trans_pri; |
1364 | trans_pri = sctp_trans_elect_best(trans_pri, trans_pf); | ||
1365 | trans_sec = asoc->peer.primary_path; | ||
1366 | } | 1364 | } |
1367 | 1365 | ||
1368 | /* Set the active and retran transports. */ | 1366 | /* Set the active and retran transports. */ |
diff --git a/net/tipc/port.h b/net/tipc/port.h index 3f93454592b6..3087da39ee47 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
@@ -179,9 +179,12 @@ static inline int tipc_port_importance(struct tipc_port *port) | |||
179 | return msg_importance(&port->phdr); | 179 | return msg_importance(&port->phdr); |
180 | } | 180 | } |
181 | 181 | ||
182 | static inline void tipc_port_set_importance(struct tipc_port *port, int imp) | 182 | static inline int tipc_port_set_importance(struct tipc_port *port, int imp) |
183 | { | 183 | { |
184 | if (imp > TIPC_CRITICAL_IMPORTANCE) | ||
185 | return -EINVAL; | ||
184 | msg_set_importance(&port->phdr, (u32)imp); | 186 | msg_set_importance(&port->phdr, (u32)imp); |
187 | return 0; | ||
185 | } | 188 | } |
186 | 189 | ||
187 | #endif | 190 | #endif |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 7d423ee10897..ff8c8118d56e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1973,7 +1973,7 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt, | |||
1973 | 1973 | ||
1974 | switch (opt) { | 1974 | switch (opt) { |
1975 | case TIPC_IMPORTANCE: | 1975 | case TIPC_IMPORTANCE: |
1976 | tipc_port_set_importance(port, value); | 1976 | res = tipc_port_set_importance(port, value); |
1977 | break; | 1977 | break; |
1978 | case TIPC_SRC_DROPPABLE: | 1978 | case TIPC_SRC_DROPPABLE: |
1979 | if (sock->type != SOCK_STREAM) | 1979 | if (sock->type != SOCK_STREAM) |
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c index 62b8869f5a4c..279bc565ac7e 100644 --- a/sound/oss/uart401.c +++ b/sound/oss/uart401.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #include "mpu401.h" | 31 | #include "mpu401.h" |
32 | 32 | ||
33 | typedef struct uart401_devc | 33 | struct uart401_devc |
34 | { | 34 | { |
35 | int base; | 35 | int base; |
36 | int irq; | 36 | int irq; |
@@ -41,14 +41,13 @@ typedef struct uart401_devc | |||
41 | int my_dev; | 41 | int my_dev; |
42 | int share_irq; | 42 | int share_irq; |
43 | spinlock_t lock; | 43 | spinlock_t lock; |
44 | } | 44 | }; |
45 | uart401_devc; | ||
46 | 45 | ||
47 | #define DATAPORT (devc->base) | 46 | #define DATAPORT (devc->base) |
48 | #define COMDPORT (devc->base+1) | 47 | #define COMDPORT (devc->base+1) |
49 | #define STATPORT (devc->base+1) | 48 | #define STATPORT (devc->base+1) |
50 | 49 | ||
51 | static int uart401_status(uart401_devc * devc) | 50 | static int uart401_status(struct uart401_devc *devc) |
52 | { | 51 | { |
53 | return inb(STATPORT); | 52 | return inb(STATPORT); |
54 | } | 53 | } |
@@ -56,17 +55,17 @@ static int uart401_status(uart401_devc * devc) | |||
56 | #define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL)) | 55 | #define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL)) |
57 | #define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY)) | 56 | #define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY)) |
58 | 57 | ||
59 | static void uart401_cmd(uart401_devc * devc, unsigned char cmd) | 58 | static void uart401_cmd(struct uart401_devc *devc, unsigned char cmd) |
60 | { | 59 | { |
61 | outb((cmd), COMDPORT); | 60 | outb((cmd), COMDPORT); |
62 | } | 61 | } |
63 | 62 | ||
64 | static int uart401_read(uart401_devc * devc) | 63 | static int uart401_read(struct uart401_devc *devc) |
65 | { | 64 | { |
66 | return inb(DATAPORT); | 65 | return inb(DATAPORT); |
67 | } | 66 | } |
68 | 67 | ||
69 | static void uart401_write(uart401_devc * devc, unsigned char byte) | 68 | static void uart401_write(struct uart401_devc *devc, unsigned char byte) |
70 | { | 69 | { |
71 | outb((byte), DATAPORT); | 70 | outb((byte), DATAPORT); |
72 | } | 71 | } |
@@ -77,10 +76,10 @@ static void uart401_write(uart401_devc * devc, unsigned char byte) | |||
77 | #define MPU_RESET 0xFF | 76 | #define MPU_RESET 0xFF |
78 | #define UART_MODE_ON 0x3F | 77 | #define UART_MODE_ON 0x3F |
79 | 78 | ||
80 | static int reset_uart401(uart401_devc * devc); | 79 | static int reset_uart401(struct uart401_devc *devc); |
81 | static void enter_uart_mode(uart401_devc * devc); | 80 | static void enter_uart_mode(struct uart401_devc *devc); |
82 | 81 | ||
83 | static void uart401_input_loop(uart401_devc * devc) | 82 | static void uart401_input_loop(struct uart401_devc *devc) |
84 | { | 83 | { |
85 | int work_limit=30000; | 84 | int work_limit=30000; |
86 | 85 | ||
@@ -99,7 +98,7 @@ static void uart401_input_loop(uart401_devc * devc) | |||
99 | 98 | ||
100 | irqreturn_t uart401intr(int irq, void *dev_id) | 99 | irqreturn_t uart401intr(int irq, void *dev_id) |
101 | { | 100 | { |
102 | uart401_devc *devc = dev_id; | 101 | struct uart401_devc *devc = dev_id; |
103 | 102 | ||
104 | if (devc == NULL) | 103 | if (devc == NULL) |
105 | { | 104 | { |
@@ -118,7 +117,8 @@ uart401_open(int dev, int mode, | |||
118 | void (*output) (int dev) | 117 | void (*output) (int dev) |
119 | ) | 118 | ) |
120 | { | 119 | { |
121 | uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc; | 120 | struct uart401_devc *devc = (struct uart401_devc *) |
121 | midi_devs[dev]->devc; | ||
122 | 122 | ||
123 | if (devc->opened) | 123 | if (devc->opened) |
124 | return -EBUSY; | 124 | return -EBUSY; |
@@ -138,7 +138,8 @@ uart401_open(int dev, int mode, | |||
138 | 138 | ||
139 | static void uart401_close(int dev) | 139 | static void uart401_close(int dev) |
140 | { | 140 | { |
141 | uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc; | 141 | struct uart401_devc *devc = (struct uart401_devc *) |
142 | midi_devs[dev]->devc; | ||
142 | 143 | ||
143 | reset_uart401(devc); | 144 | reset_uart401(devc); |
144 | devc->opened = 0; | 145 | devc->opened = 0; |
@@ -148,7 +149,8 @@ static int uart401_out(int dev, unsigned char midi_byte) | |||
148 | { | 149 | { |
149 | int timeout; | 150 | int timeout; |
150 | unsigned long flags; | 151 | unsigned long flags; |
151 | uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc; | 152 | struct uart401_devc *devc = (struct uart401_devc *) |
153 | midi_devs[dev]->devc; | ||
152 | 154 | ||
153 | if (devc->disabled) | 155 | if (devc->disabled) |
154 | return 1; | 156 | return 1; |
@@ -219,7 +221,7 @@ static const struct midi_operations uart401_operations = | |||
219 | .buffer_status = uart401_buffer_status, | 221 | .buffer_status = uart401_buffer_status, |
220 | }; | 222 | }; |
221 | 223 | ||
222 | static void enter_uart_mode(uart401_devc * devc) | 224 | static void enter_uart_mode(struct uart401_devc *devc) |
223 | { | 225 | { |
224 | int ok, timeout; | 226 | int ok, timeout; |
225 | unsigned long flags; | 227 | unsigned long flags; |
@@ -241,7 +243,7 @@ static void enter_uart_mode(uart401_devc * devc) | |||
241 | spin_unlock_irqrestore(&devc->lock,flags); | 243 | spin_unlock_irqrestore(&devc->lock,flags); |
242 | } | 244 | } |
243 | 245 | ||
244 | static int reset_uart401(uart401_devc * devc) | 246 | static int reset_uart401(struct uart401_devc *devc) |
245 | { | 247 | { |
246 | int ok, timeout, n; | 248 | int ok, timeout, n; |
247 | 249 | ||
@@ -285,7 +287,7 @@ static int reset_uart401(uart401_devc * devc) | |||
285 | 287 | ||
286 | int probe_uart401(struct address_info *hw_config, struct module *owner) | 288 | int probe_uart401(struct address_info *hw_config, struct module *owner) |
287 | { | 289 | { |
288 | uart401_devc *devc; | 290 | struct uart401_devc *devc; |
289 | char *name = "MPU-401 (UART) MIDI"; | 291 | char *name = "MPU-401 (UART) MIDI"; |
290 | int ok = 0; | 292 | int ok = 0; |
291 | unsigned long flags; | 293 | unsigned long flags; |
@@ -300,7 +302,7 @@ int probe_uart401(struct address_info *hw_config, struct module *owner) | |||
300 | return 0; | 302 | return 0; |
301 | } | 303 | } |
302 | 304 | ||
303 | devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL); | 305 | devc = kmalloc(sizeof(struct uart401_devc), GFP_KERNEL); |
304 | if (!devc) { | 306 | if (!devc) { |
305 | printk(KERN_WARNING "uart401: Can't allocate memory\n"); | 307 | printk(KERN_WARNING "uart401: Can't allocate memory\n"); |
306 | goto cleanup_region; | 308 | goto cleanup_region; |
@@ -392,7 +394,7 @@ cleanup_region: | |||
392 | 394 | ||
393 | void unload_uart401(struct address_info *hw_config) | 395 | void unload_uart401(struct address_info *hw_config) |
394 | { | 396 | { |
395 | uart401_devc *devc; | 397 | struct uart401_devc *devc; |
396 | int n=hw_config->slots[4]; | 398 | int n=hw_config->slots[4]; |
397 | 399 | ||
398 | /* Not set up */ | 400 | /* Not set up */ |
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index 672af8b56542..b36ea47527e8 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c | |||
@@ -92,7 +92,7 @@ static unsigned short levels[SOUND_MIXER_NRDEVICES] = { | |||
92 | 0x0000 /* Monitor */ | 92 | 0x0000 /* Monitor */ |
93 | }; | 93 | }; |
94 | 94 | ||
95 | typedef struct { | 95 | struct wavnc_info { |
96 | struct address_info hw; /* hardware */ | 96 | struct address_info hw; /* hardware */ |
97 | char *chip_name; | 97 | char *chip_name; |
98 | 98 | ||
@@ -119,7 +119,7 @@ typedef struct { | |||
119 | unsigned int line_mute_state :1;/* set by ioctl or autoselect */ | 119 | unsigned int line_mute_state :1;/* set by ioctl or autoselect */ |
120 | unsigned int use_slider :1;/* use slider setting for o/p vol */ | 120 | unsigned int use_slider :1;/* use slider setting for o/p vol */ |
121 | #endif | 121 | #endif |
122 | } wavnc_info; | 122 | }; |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * This is the implementation specific mixer information. | 125 | * This is the implementation specific mixer information. |
@@ -129,29 +129,30 @@ struct waveartist_mixer_info { | |||
129 | unsigned int recording_devs; /* Recordable devies */ | 129 | unsigned int recording_devs; /* Recordable devies */ |
130 | unsigned int stereo_devs; /* Stereo devices */ | 130 | unsigned int stereo_devs; /* Stereo devices */ |
131 | 131 | ||
132 | unsigned int (*select_input)(wavnc_info *, unsigned int, | 132 | unsigned int (*select_input)(struct wavnc_info *, unsigned int, |
133 | unsigned char *, unsigned char *); | 133 | unsigned char *, unsigned char *); |
134 | int (*decode_mixer)(wavnc_info *, int, | 134 | int (*decode_mixer)(struct wavnc_info *, int, |
135 | unsigned char, unsigned char); | 135 | unsigned char, unsigned char); |
136 | int (*get_mixer)(wavnc_info *, int); | 136 | int (*get_mixer)(struct wavnc_info *, int); |
137 | }; | 137 | }; |
138 | 138 | ||
139 | typedef struct wavnc_port_info { | 139 | struct wavnc_port_info { |
140 | int open_mode; | 140 | int open_mode; |
141 | int speed; | 141 | int speed; |
142 | int channels; | 142 | int channels; |
143 | int audio_format; | 143 | int audio_format; |
144 | } wavnc_port_info; | 144 | }; |
145 | 145 | ||
146 | static int nr_waveartist_devs; | 146 | static int nr_waveartist_devs; |
147 | static wavnc_info adev_info[MAX_AUDIO_DEV]; | 147 | static struct wavnc_info adev_info[MAX_AUDIO_DEV]; |
148 | static DEFINE_SPINLOCK(waveartist_lock); | 148 | static DEFINE_SPINLOCK(waveartist_lock); |
149 | 149 | ||
150 | #ifndef CONFIG_ARCH_NETWINDER | 150 | #ifndef CONFIG_ARCH_NETWINDER |
151 | #define machine_is_netwinder() 0 | 151 | #define machine_is_netwinder() 0 |
152 | #else | 152 | #else |
153 | static struct timer_list vnc_timer; | 153 | static struct timer_list vnc_timer; |
154 | static void vnc_configure_mixer(wavnc_info *devc, unsigned int input_mask); | 154 | static void vnc_configure_mixer(struct wavnc_info *devc, |
155 | unsigned int input_mask); | ||
155 | static int vnc_private_ioctl(int dev, unsigned int cmd, int __user *arg); | 156 | static int vnc_private_ioctl(int dev, unsigned int cmd, int __user *arg); |
156 | static void vnc_slider_tick(unsigned long data); | 157 | static void vnc_slider_tick(unsigned long data); |
157 | #endif | 158 | #endif |
@@ -169,7 +170,7 @@ waveartist_set_ctlr(struct address_info *hw, unsigned char clear, unsigned char | |||
169 | /* Toggle IRQ acknowledge line | 170 | /* Toggle IRQ acknowledge line |
170 | */ | 171 | */ |
171 | static inline void | 172 | static inline void |
172 | waveartist_iack(wavnc_info *devc) | 173 | waveartist_iack(struct wavnc_info *devc) |
173 | { | 174 | { |
174 | unsigned int ctlr_port = devc->hw.io_base + CTLR; | 175 | unsigned int ctlr_port = devc->hw.io_base + CTLR; |
175 | int old_ctlr; | 176 | int old_ctlr; |
@@ -188,7 +189,7 @@ waveartist_sleep(int timeout_ms) | |||
188 | } | 189 | } |
189 | 190 | ||
190 | static int | 191 | static int |
191 | waveartist_reset(wavnc_info *devc) | 192 | waveartist_reset(struct wavnc_info *devc) |
192 | { | 193 | { |
193 | struct address_info *hw = &devc->hw; | 194 | struct address_info *hw = &devc->hw; |
194 | unsigned int timeout, res = -1; | 195 | unsigned int timeout, res = -1; |
@@ -223,7 +224,7 @@ waveartist_reset(wavnc_info *devc) | |||
223 | * and can send or receive multiple words. | 224 | * and can send or receive multiple words. |
224 | */ | 225 | */ |
225 | static int | 226 | static int |
226 | waveartist_cmd(wavnc_info *devc, | 227 | waveartist_cmd(struct wavnc_info *devc, |
227 | int nr_cmd, unsigned int *cmd, | 228 | int nr_cmd, unsigned int *cmd, |
228 | int nr_resp, unsigned int *resp) | 229 | int nr_resp, unsigned int *resp) |
229 | { | 230 | { |
@@ -299,7 +300,7 @@ waveartist_cmd(wavnc_info *devc, | |||
299 | * Send one command word | 300 | * Send one command word |
300 | */ | 301 | */ |
301 | static inline int | 302 | static inline int |
302 | waveartist_cmd1(wavnc_info *devc, unsigned int cmd) | 303 | waveartist_cmd1(struct wavnc_info *devc, unsigned int cmd) |
303 | { | 304 | { |
304 | return waveartist_cmd(devc, 1, &cmd, 0, NULL); | 305 | return waveartist_cmd(devc, 1, &cmd, 0, NULL); |
305 | } | 306 | } |
@@ -308,7 +309,7 @@ waveartist_cmd1(wavnc_info *devc, unsigned int cmd) | |||
308 | * Send one command, receive one word | 309 | * Send one command, receive one word |
309 | */ | 310 | */ |
310 | static inline unsigned int | 311 | static inline unsigned int |
311 | waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd) | 312 | waveartist_cmd1_r(struct wavnc_info *devc, unsigned int cmd) |
312 | { | 313 | { |
313 | unsigned int ret; | 314 | unsigned int ret; |
314 | 315 | ||
@@ -322,7 +323,7 @@ waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd) | |||
322 | * word (and throw it away) | 323 | * word (and throw it away) |
323 | */ | 324 | */ |
324 | static inline int | 325 | static inline int |
325 | waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg) | 326 | waveartist_cmd2(struct wavnc_info *devc, unsigned int cmd, unsigned int arg) |
326 | { | 327 | { |
327 | unsigned int vals[2]; | 328 | unsigned int vals[2]; |
328 | 329 | ||
@@ -336,7 +337,7 @@ waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg) | |||
336 | * Send a triple command | 337 | * Send a triple command |
337 | */ | 338 | */ |
338 | static inline int | 339 | static inline int |
339 | waveartist_cmd3(wavnc_info *devc, unsigned int cmd, | 340 | waveartist_cmd3(struct wavnc_info *devc, unsigned int cmd, |
340 | unsigned int arg1, unsigned int arg2) | 341 | unsigned int arg1, unsigned int arg2) |
341 | { | 342 | { |
342 | unsigned int vals[3]; | 343 | unsigned int vals[3]; |
@@ -349,7 +350,7 @@ waveartist_cmd3(wavnc_info *devc, unsigned int cmd, | |||
349 | } | 350 | } |
350 | 351 | ||
351 | static int | 352 | static int |
352 | waveartist_getrev(wavnc_info *devc, char *rev) | 353 | waveartist_getrev(struct wavnc_info *devc, char *rev) |
353 | { | 354 | { |
354 | unsigned int temp[2]; | 355 | unsigned int temp[2]; |
355 | unsigned int cmd = WACMD_GETREV; | 356 | unsigned int cmd = WACMD_GETREV; |
@@ -371,15 +372,15 @@ static void waveartist_trigger(int dev, int state); | |||
371 | static int | 372 | static int |
372 | waveartist_open(int dev, int mode) | 373 | waveartist_open(int dev, int mode) |
373 | { | 374 | { |
374 | wavnc_info *devc; | 375 | struct wavnc_info *devc; |
375 | wavnc_port_info *portc; | 376 | struct wavnc_port_info *portc; |
376 | unsigned long flags; | 377 | unsigned long flags; |
377 | 378 | ||
378 | if (dev < 0 || dev >= num_audiodevs) | 379 | if (dev < 0 || dev >= num_audiodevs) |
379 | return -ENXIO; | 380 | return -ENXIO; |
380 | 381 | ||
381 | devc = (wavnc_info *) audio_devs[dev]->devc; | 382 | devc = (struct wavnc_info *) audio_devs[dev]->devc; |
382 | portc = (wavnc_port_info *) audio_devs[dev]->portc; | 383 | portc = (struct wavnc_port_info *) audio_devs[dev]->portc; |
383 | 384 | ||
384 | spin_lock_irqsave(&waveartist_lock, flags); | 385 | spin_lock_irqsave(&waveartist_lock, flags); |
385 | if (portc->open_mode || (devc->open_mode & mode)) { | 386 | if (portc->open_mode || (devc->open_mode & mode)) { |
@@ -404,8 +405,10 @@ waveartist_open(int dev, int mode) | |||
404 | static void | 405 | static void |
405 | waveartist_close(int dev) | 406 | waveartist_close(int dev) |
406 | { | 407 | { |
407 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 408 | struct wavnc_info *devc = (struct wavnc_info *) |
408 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 409 | audio_devs[dev]->devc; |
410 | struct wavnc_port_info *portc = (struct wavnc_port_info *) | ||
411 | audio_devs[dev]->portc; | ||
409 | unsigned long flags; | 412 | unsigned long flags; |
410 | 413 | ||
411 | spin_lock_irqsave(&waveartist_lock, flags); | 414 | spin_lock_irqsave(&waveartist_lock, flags); |
@@ -422,8 +425,10 @@ waveartist_close(int dev) | |||
422 | static void | 425 | static void |
423 | waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag) | 426 | waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag) |
424 | { | 427 | { |
425 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 428 | struct wavnc_port_info *portc = (struct wavnc_port_info *) |
426 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 429 | audio_devs[dev]->portc; |
430 | struct wavnc_info *devc = (struct wavnc_info *) | ||
431 | audio_devs[dev]->devc; | ||
427 | unsigned long flags; | 432 | unsigned long flags; |
428 | unsigned int count = __count; | 433 | unsigned int count = __count; |
429 | 434 | ||
@@ -467,8 +472,10 @@ waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag) | |||
467 | static void | 472 | static void |
468 | waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag) | 473 | waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag) |
469 | { | 474 | { |
470 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 475 | struct wavnc_port_info *portc = (struct wavnc_port_info *) |
471 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 476 | audio_devs[dev]->portc; |
477 | struct wavnc_info *devc = (struct wavnc_info *) | ||
478 | audio_devs[dev]->devc; | ||
472 | unsigned long flags; | 479 | unsigned long flags; |
473 | unsigned int count = __count; | 480 | unsigned int count = __count; |
474 | 481 | ||
@@ -514,7 +521,7 @@ waveartist_ioctl(int dev, unsigned int cmd, void __user * arg) | |||
514 | } | 521 | } |
515 | 522 | ||
516 | static unsigned int | 523 | static unsigned int |
517 | waveartist_get_speed(wavnc_port_info *portc) | 524 | waveartist_get_speed(struct wavnc_port_info *portc) |
518 | { | 525 | { |
519 | unsigned int speed; | 526 | unsigned int speed; |
520 | 527 | ||
@@ -542,7 +549,7 @@ waveartist_get_speed(wavnc_port_info *portc) | |||
542 | } | 549 | } |
543 | 550 | ||
544 | static unsigned int | 551 | static unsigned int |
545 | waveartist_get_bits(wavnc_port_info *portc) | 552 | waveartist_get_bits(struct wavnc_port_info *portc) |
546 | { | 553 | { |
547 | unsigned int bits; | 554 | unsigned int bits; |
548 | 555 | ||
@@ -560,8 +567,10 @@ static int | |||
560 | waveartist_prepare_for_input(int dev, int bsize, int bcount) | 567 | waveartist_prepare_for_input(int dev, int bsize, int bcount) |
561 | { | 568 | { |
562 | unsigned long flags; | 569 | unsigned long flags; |
563 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 570 | struct wavnc_info *devc = (struct wavnc_info *) |
564 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 571 | audio_devs[dev]->devc; |
572 | struct wavnc_port_info *portc = (struct wavnc_port_info *) | ||
573 | audio_devs[dev]->portc; | ||
565 | unsigned int speed, bits; | 574 | unsigned int speed, bits; |
566 | 575 | ||
567 | if (devc->audio_mode) | 576 | if (devc->audio_mode) |
@@ -615,8 +624,10 @@ static int | |||
615 | waveartist_prepare_for_output(int dev, int bsize, int bcount) | 624 | waveartist_prepare_for_output(int dev, int bsize, int bcount) |
616 | { | 625 | { |
617 | unsigned long flags; | 626 | unsigned long flags; |
618 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 627 | struct wavnc_info *devc = (struct wavnc_info *) |
619 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 628 | audio_devs[dev]->devc; |
629 | struct wavnc_port_info *portc = (struct wavnc_port_info *) | ||
630 | audio_devs[dev]->portc; | ||
620 | unsigned int speed, bits; | 631 | unsigned int speed, bits; |
621 | 632 | ||
622 | /* | 633 | /* |
@@ -660,8 +671,9 @@ waveartist_prepare_for_output(int dev, int bsize, int bcount) | |||
660 | static void | 671 | static void |
661 | waveartist_halt(int dev) | 672 | waveartist_halt(int dev) |
662 | { | 673 | { |
663 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 674 | struct wavnc_port_info *portc = (struct wavnc_port_info *) |
664 | wavnc_info *devc; | 675 | audio_devs[dev]->portc; |
676 | struct wavnc_info *devc; | ||
665 | 677 | ||
666 | if (portc->open_mode & OPEN_WRITE) | 678 | if (portc->open_mode & OPEN_WRITE) |
667 | waveartist_halt_output(dev); | 679 | waveartist_halt_output(dev); |
@@ -669,14 +681,15 @@ waveartist_halt(int dev) | |||
669 | if (portc->open_mode & OPEN_READ) | 681 | if (portc->open_mode & OPEN_READ) |
670 | waveartist_halt_input(dev); | 682 | waveartist_halt_input(dev); |
671 | 683 | ||
672 | devc = (wavnc_info *) audio_devs[dev]->devc; | 684 | devc = (struct wavnc_info *) audio_devs[dev]->devc; |
673 | devc->audio_mode = 0; | 685 | devc->audio_mode = 0; |
674 | } | 686 | } |
675 | 687 | ||
676 | static void | 688 | static void |
677 | waveartist_halt_input(int dev) | 689 | waveartist_halt_input(int dev) |
678 | { | 690 | { |
679 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 691 | struct wavnc_info *devc = (struct wavnc_info *) |
692 | audio_devs[dev]->devc; | ||
680 | unsigned long flags; | 693 | unsigned long flags; |
681 | 694 | ||
682 | spin_lock_irqsave(&waveartist_lock, flags); | 695 | spin_lock_irqsave(&waveartist_lock, flags); |
@@ -703,7 +716,8 @@ waveartist_halt_input(int dev) | |||
703 | static void | 716 | static void |
704 | waveartist_halt_output(int dev) | 717 | waveartist_halt_output(int dev) |
705 | { | 718 | { |
706 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 719 | struct wavnc_info *devc = (struct wavnc_info *) |
720 | audio_devs[dev]->devc; | ||
707 | unsigned long flags; | 721 | unsigned long flags; |
708 | 722 | ||
709 | spin_lock_irqsave(&waveartist_lock, flags); | 723 | spin_lock_irqsave(&waveartist_lock, flags); |
@@ -727,8 +741,10 @@ waveartist_halt_output(int dev) | |||
727 | static void | 741 | static void |
728 | waveartist_trigger(int dev, int state) | 742 | waveartist_trigger(int dev, int state) |
729 | { | 743 | { |
730 | wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; | 744 | struct wavnc_info *devc = (struct wavnc_info *) |
731 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 745 | audio_devs[dev]->devc; |
746 | struct wavnc_port_info *portc = (struct wavnc_port_info *) | ||
747 | audio_devs[dev]->portc; | ||
732 | unsigned long flags; | 748 | unsigned long flags; |
733 | 749 | ||
734 | if (debug_flg & DEBUG_TRIGGER) { | 750 | if (debug_flg & DEBUG_TRIGGER) { |
@@ -764,7 +780,8 @@ waveartist_trigger(int dev, int state) | |||
764 | static int | 780 | static int |
765 | waveartist_set_speed(int dev, int arg) | 781 | waveartist_set_speed(int dev, int arg) |
766 | { | 782 | { |
767 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 783 | struct wavnc_port_info *portc = (struct wavnc_port_info *) |
784 | audio_devs[dev]->portc; | ||
768 | 785 | ||
769 | if (arg <= 0) | 786 | if (arg <= 0) |
770 | return portc->speed; | 787 | return portc->speed; |
@@ -782,7 +799,8 @@ waveartist_set_speed(int dev, int arg) | |||
782 | static short | 799 | static short |
783 | waveartist_set_channels(int dev, short arg) | 800 | waveartist_set_channels(int dev, short arg) |
784 | { | 801 | { |
785 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 802 | struct wavnc_port_info *portc = (struct wavnc_port_info *) |
803 | audio_devs[dev]->portc; | ||
786 | 804 | ||
787 | if (arg != 1 && arg != 2) | 805 | if (arg != 1 && arg != 2) |
788 | return portc->channels; | 806 | return portc->channels; |
@@ -794,7 +812,8 @@ waveartist_set_channels(int dev, short arg) | |||
794 | static unsigned int | 812 | static unsigned int |
795 | waveartist_set_bits(int dev, unsigned int arg) | 813 | waveartist_set_bits(int dev, unsigned int arg) |
796 | { | 814 | { |
797 | wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; | 815 | struct wavnc_port_info *portc = (struct wavnc_port_info *) |
816 | audio_devs[dev]->portc; | ||
798 | 817 | ||
799 | if (arg == 0) | 818 | if (arg == 0) |
800 | return portc->audio_format; | 819 | return portc->audio_format; |
@@ -829,7 +848,7 @@ static struct audio_driver waveartist_audio_driver = { | |||
829 | static irqreturn_t | 848 | static irqreturn_t |
830 | waveartist_intr(int irq, void *dev_id) | 849 | waveartist_intr(int irq, void *dev_id) |
831 | { | 850 | { |
832 | wavnc_info *devc = dev_id; | 851 | struct wavnc_info *devc = dev_id; |
833 | int irqstatus, status; | 852 | int irqstatus, status; |
834 | 853 | ||
835 | spin_lock(&waveartist_lock); | 854 | spin_lock(&waveartist_lock); |
@@ -912,7 +931,7 @@ static const struct mix_ent mix_devs[SOUND_MIXER_NRDEVICES] = { | |||
912 | }; | 931 | }; |
913 | 932 | ||
914 | static void | 933 | static void |
915 | waveartist_mixer_update(wavnc_info *devc, int whichDev) | 934 | waveartist_mixer_update(struct wavnc_info *devc, int whichDev) |
916 | { | 935 | { |
917 | unsigned int lev_left, lev_right; | 936 | unsigned int lev_left, lev_right; |
918 | 937 | ||
@@ -973,7 +992,8 @@ waveartist_mixer_update(wavnc_info *devc, int whichDev) | |||
973 | * relevant *_select_input function has done that for us. | 992 | * relevant *_select_input function has done that for us. |
974 | */ | 993 | */ |
975 | static void | 994 | static void |
976 | waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev) | 995 | waveartist_set_adc_mux(struct wavnc_info *devc, char left_dev, |
996 | char right_dev) | ||
977 | { | 997 | { |
978 | unsigned int reg_08, reg_09; | 998 | unsigned int reg_08, reg_09; |
979 | 999 | ||
@@ -996,7 +1016,7 @@ waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev) | |||
996 | * SOUND_MASK_MIC Mic Microphone | 1016 | * SOUND_MASK_MIC Mic Microphone |
997 | */ | 1017 | */ |
998 | static unsigned int | 1018 | static unsigned int |
999 | waveartist_select_input(wavnc_info *devc, unsigned int recmask, | 1019 | waveartist_select_input(struct wavnc_info *devc, unsigned int recmask, |
1000 | unsigned char *dev_l, unsigned char *dev_r) | 1020 | unsigned char *dev_l, unsigned char *dev_r) |
1001 | { | 1021 | { |
1002 | unsigned int recdev = ADC_MUX_NONE; | 1022 | unsigned int recdev = ADC_MUX_NONE; |
@@ -1024,7 +1044,8 @@ waveartist_select_input(wavnc_info *devc, unsigned int recmask, | |||
1024 | } | 1044 | } |
1025 | 1045 | ||
1026 | static int | 1046 | static int |
1027 | waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, | 1047 | waveartist_decode_mixer(struct wavnc_info *devc, int dev, |
1048 | unsigned char lev_l, | ||
1028 | unsigned char lev_r) | 1049 | unsigned char lev_r) |
1029 | { | 1050 | { |
1030 | switch (dev) { | 1051 | switch (dev) { |
@@ -1050,7 +1071,7 @@ waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, | |||
1050 | return dev; | 1071 | return dev; |
1051 | } | 1072 | } |
1052 | 1073 | ||
1053 | static int waveartist_get_mixer(wavnc_info *devc, int dev) | 1074 | static int waveartist_get_mixer(struct wavnc_info *devc, int dev) |
1054 | { | 1075 | { |
1055 | return devc->levels[dev]; | 1076 | return devc->levels[dev]; |
1056 | } | 1077 | } |
@@ -1068,7 +1089,7 @@ static const struct waveartist_mixer_info waveartist_mixer = { | |||
1068 | }; | 1089 | }; |
1069 | 1090 | ||
1070 | static void | 1091 | static void |
1071 | waveartist_set_recmask(wavnc_info *devc, unsigned int recmask) | 1092 | waveartist_set_recmask(struct wavnc_info *devc, unsigned int recmask) |
1072 | { | 1093 | { |
1073 | unsigned char dev_l, dev_r; | 1094 | unsigned char dev_l, dev_r; |
1074 | 1095 | ||
@@ -1092,7 +1113,7 @@ waveartist_set_recmask(wavnc_info *devc, unsigned int recmask) | |||
1092 | } | 1113 | } |
1093 | 1114 | ||
1094 | static int | 1115 | static int |
1095 | waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level) | 1116 | waveartist_set_mixer(struct wavnc_info *devc, int dev, unsigned int level) |
1096 | { | 1117 | { |
1097 | unsigned int lev_left = level & 0x00ff; | 1118 | unsigned int lev_left = level & 0x00ff; |
1098 | unsigned int lev_right = (level & 0xff00) >> 8; | 1119 | unsigned int lev_right = (level & 0xff00) >> 8; |
@@ -1120,7 +1141,7 @@ waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level) | |||
1120 | static int | 1141 | static int |
1121 | waveartist_mixer_ioctl(int dev, unsigned int cmd, void __user * arg) | 1142 | waveartist_mixer_ioctl(int dev, unsigned int cmd, void __user * arg) |
1122 | { | 1143 | { |
1123 | wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc; | 1144 | struct wavnc_info *devc = (struct wavnc_info *)audio_devs[dev]->devc; |
1124 | int ret = 0, val, nr; | 1145 | int ret = 0, val, nr; |
1125 | 1146 | ||
1126 | /* | 1147 | /* |
@@ -1204,7 +1225,7 @@ static struct mixer_operations waveartist_mixer_operations = | |||
1204 | }; | 1225 | }; |
1205 | 1226 | ||
1206 | static void | 1227 | static void |
1207 | waveartist_mixer_reset(wavnc_info *devc) | 1228 | waveartist_mixer_reset(struct wavnc_info *devc) |
1208 | { | 1229 | { |
1209 | int i; | 1230 | int i; |
1210 | 1231 | ||
@@ -1241,9 +1262,9 @@ waveartist_mixer_reset(wavnc_info *devc) | |||
1241 | waveartist_mixer_update(devc, i); | 1262 | waveartist_mixer_update(devc, i); |
1242 | } | 1263 | } |
1243 | 1264 | ||
1244 | static int __init waveartist_init(wavnc_info *devc) | 1265 | static int __init waveartist_init(struct wavnc_info *devc) |
1245 | { | 1266 | { |
1246 | wavnc_port_info *portc; | 1267 | struct wavnc_port_info *portc; |
1247 | char rev[3], dev_name[64]; | 1268 | char rev[3], dev_name[64]; |
1248 | int my_dev; | 1269 | int my_dev; |
1249 | 1270 | ||
@@ -1261,7 +1282,7 @@ static int __init waveartist_init(wavnc_info *devc) | |||
1261 | conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq, | 1282 | conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq, |
1262 | devc->hw.dma, devc->hw.dma2); | 1283 | devc->hw.dma, devc->hw.dma2); |
1263 | 1284 | ||
1264 | portc = kzalloc(sizeof(wavnc_port_info), GFP_KERNEL); | 1285 | portc = kzalloc(sizeof(struct wavnc_port_info), GFP_KERNEL); |
1265 | if (portc == NULL) | 1286 | if (portc == NULL) |
1266 | goto nomem; | 1287 | goto nomem; |
1267 | 1288 | ||
@@ -1330,7 +1351,7 @@ nomem: | |||
1330 | 1351 | ||
1331 | static int __init probe_waveartist(struct address_info *hw_config) | 1352 | static int __init probe_waveartist(struct address_info *hw_config) |
1332 | { | 1353 | { |
1333 | wavnc_info *devc = &adev_info[nr_waveartist_devs]; | 1354 | struct wavnc_info *devc = &adev_info[nr_waveartist_devs]; |
1334 | 1355 | ||
1335 | if (nr_waveartist_devs >= MAX_AUDIO_DEV) { | 1356 | if (nr_waveartist_devs >= MAX_AUDIO_DEV) { |
1336 | printk(KERN_WARNING "waveartist: too many audio devices\n"); | 1357 | printk(KERN_WARNING "waveartist: too many audio devices\n"); |
@@ -1367,7 +1388,7 @@ static int __init probe_waveartist(struct address_info *hw_config) | |||
1367 | static void __init | 1388 | static void __init |
1368 | attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *mix) | 1389 | attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *mix) |
1369 | { | 1390 | { |
1370 | wavnc_info *devc = &adev_info[nr_waveartist_devs]; | 1391 | struct wavnc_info *devc = &adev_info[nr_waveartist_devs]; |
1371 | 1392 | ||
1372 | /* | 1393 | /* |
1373 | * NOTE! If irq < 0, there is another driver which has allocated the | 1394 | * NOTE! If irq < 0, there is another driver which has allocated the |
@@ -1410,7 +1431,7 @@ attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *m | |||
1410 | 1431 | ||
1411 | static void __exit unload_waveartist(struct address_info *hw) | 1432 | static void __exit unload_waveartist(struct address_info *hw) |
1412 | { | 1433 | { |
1413 | wavnc_info *devc = NULL; | 1434 | struct wavnc_info *devc = NULL; |
1414 | int i; | 1435 | int i; |
1415 | 1436 | ||
1416 | for (i = 0; i < nr_waveartist_devs; i++) | 1437 | for (i = 0; i < nr_waveartist_devs; i++) |
@@ -1478,7 +1499,7 @@ static void __exit unload_waveartist(struct address_info *hw) | |||
1478 | #define VNC_DISABLE_AUTOSWITCH 0x80 | 1499 | #define VNC_DISABLE_AUTOSWITCH 0x80 |
1479 | 1500 | ||
1480 | static inline void | 1501 | static inline void |
1481 | vnc_mute_spkr(wavnc_info *devc) | 1502 | vnc_mute_spkr(struct wavnc_info *devc) |
1482 | { | 1503 | { |
1483 | unsigned long flags; | 1504 | unsigned long flags; |
1484 | 1505 | ||
@@ -1488,7 +1509,7 @@ vnc_mute_spkr(wavnc_info *devc) | |||
1488 | } | 1509 | } |
1489 | 1510 | ||
1490 | static void | 1511 | static void |
1491 | vnc_mute_lout(wavnc_info *devc) | 1512 | vnc_mute_lout(struct wavnc_info *devc) |
1492 | { | 1513 | { |
1493 | unsigned int left, right; | 1514 | unsigned int left, right; |
1494 | 1515 | ||
@@ -1507,7 +1528,7 @@ vnc_mute_lout(wavnc_info *devc) | |||
1507 | } | 1528 | } |
1508 | 1529 | ||
1509 | static int | 1530 | static int |
1510 | vnc_volume_slider(wavnc_info *devc) | 1531 | vnc_volume_slider(struct wavnc_info *devc) |
1511 | { | 1532 | { |
1512 | static signed int old_slider_volume; | 1533 | static signed int old_slider_volume; |
1513 | unsigned long flags; | 1534 | unsigned long flags; |
@@ -1567,7 +1588,7 @@ vnc_volume_slider(wavnc_info *devc) | |||
1567 | * SOUND_MASK_MIC Right Mic Builtin microphone | 1588 | * SOUND_MASK_MIC Right Mic Builtin microphone |
1568 | */ | 1589 | */ |
1569 | static unsigned int | 1590 | static unsigned int |
1570 | netwinder_select_input(wavnc_info *devc, unsigned int recmask, | 1591 | netwinder_select_input(struct wavnc_info *devc, unsigned int recmask, |
1571 | unsigned char *dev_l, unsigned char *dev_r) | 1592 | unsigned char *dev_l, unsigned char *dev_r) |
1572 | { | 1593 | { |
1573 | unsigned int recdev_l = ADC_MUX_NONE, recdev_r = ADC_MUX_NONE; | 1594 | unsigned int recdev_l = ADC_MUX_NONE, recdev_r = ADC_MUX_NONE; |
@@ -1604,7 +1625,7 @@ netwinder_select_input(wavnc_info *devc, unsigned int recmask, | |||
1604 | } | 1625 | } |
1605 | 1626 | ||
1606 | static int | 1627 | static int |
1607 | netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, | 1628 | netwinder_decode_mixer(struct wavnc_info *devc, int dev, unsigned char lev_l, |
1608 | unsigned char lev_r) | 1629 | unsigned char lev_r) |
1609 | { | 1630 | { |
1610 | switch (dev) { | 1631 | switch (dev) { |
@@ -1643,7 +1664,7 @@ netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, | |||
1643 | return dev; | 1664 | return dev; |
1644 | } | 1665 | } |
1645 | 1666 | ||
1646 | static int netwinder_get_mixer(wavnc_info *devc, int dev) | 1667 | static int netwinder_get_mixer(struct wavnc_info *devc, int dev) |
1647 | { | 1668 | { |
1648 | int levels; | 1669 | int levels; |
1649 | 1670 | ||
@@ -1703,7 +1724,7 @@ static const struct waveartist_mixer_info netwinder_mixer = { | |||
1703 | }; | 1724 | }; |
1704 | 1725 | ||
1705 | static void | 1726 | static void |
1706 | vnc_configure_mixer(wavnc_info *devc, unsigned int recmask) | 1727 | vnc_configure_mixer(struct wavnc_info *devc, unsigned int recmask) |
1707 | { | 1728 | { |
1708 | if (!devc->no_autoselect) { | 1729 | if (!devc->no_autoselect) { |
1709 | if (devc->handset_detect) { | 1730 | if (devc->handset_detect) { |
@@ -1729,7 +1750,7 @@ vnc_configure_mixer(wavnc_info *devc, unsigned int recmask) | |||
1729 | } | 1750 | } |
1730 | 1751 | ||
1731 | static int | 1752 | static int |
1732 | vnc_slider(wavnc_info *devc) | 1753 | vnc_slider(struct wavnc_info *devc) |
1733 | { | 1754 | { |
1734 | signed int slider_volume; | 1755 | signed int slider_volume; |
1735 | unsigned int temp, old_hs, old_td; | 1756 | unsigned int temp, old_hs, old_td; |
@@ -1795,7 +1816,7 @@ vnc_slider_tick(unsigned long data) | |||
1795 | static int | 1816 | static int |
1796 | vnc_private_ioctl(int dev, unsigned int cmd, int __user * arg) | 1817 | vnc_private_ioctl(int dev, unsigned int cmd, int __user * arg) |
1797 | { | 1818 | { |
1798 | wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc; | 1819 | struct wavnc_info *devc = (struct wavnc_info *)audio_devs[dev]->devc; |
1799 | int val; | 1820 | int val; |
1800 | 1821 | ||
1801 | switch (cmd) { | 1822 | switch (cmd) { |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5db1948699d8..aa302fb03fc5 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -265,6 +265,7 @@ enum { | |||
265 | AZX_DRIVER_TERA, | 265 | AZX_DRIVER_TERA, |
266 | AZX_DRIVER_CTX, | 266 | AZX_DRIVER_CTX, |
267 | AZX_DRIVER_CTHDA, | 267 | AZX_DRIVER_CTHDA, |
268 | AZX_DRIVER_CMEDIA, | ||
268 | AZX_DRIVER_GENERIC, | 269 | AZX_DRIVER_GENERIC, |
269 | AZX_NUM_DRIVERS, /* keep this as last entry */ | 270 | AZX_NUM_DRIVERS, /* keep this as last entry */ |
270 | }; | 271 | }; |
@@ -330,6 +331,7 @@ static char *driver_short_names[] = { | |||
330 | [AZX_DRIVER_TERA] = "HDA Teradici", | 331 | [AZX_DRIVER_TERA] = "HDA Teradici", |
331 | [AZX_DRIVER_CTX] = "HDA Creative", | 332 | [AZX_DRIVER_CTX] = "HDA Creative", |
332 | [AZX_DRIVER_CTHDA] = "HDA Creative", | 333 | [AZX_DRIVER_CTHDA] = "HDA Creative", |
334 | [AZX_DRIVER_CMEDIA] = "HDA C-Media", | ||
333 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", | 335 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", |
334 | }; | 336 | }; |
335 | 337 | ||
@@ -1373,6 +1375,7 @@ static void azx_check_snoop_available(struct azx *chip) | |||
1373 | snoop = false; | 1375 | snoop = false; |
1374 | break; | 1376 | break; |
1375 | case AZX_DRIVER_CTHDA: | 1377 | case AZX_DRIVER_CTHDA: |
1378 | case AZX_DRIVER_CMEDIA: | ||
1376 | snoop = false; | 1379 | snoop = false; |
1377 | break; | 1380 | break; |
1378 | } | 1381 | } |
@@ -2154,6 +2157,10 @@ static const struct pci_device_id azx_ids[] = { | |||
2154 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | | 2157 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | |
2155 | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, | 2158 | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, |
2156 | #endif | 2159 | #endif |
2160 | /* CM8888 */ | ||
2161 | { PCI_DEVICE(0x13f6, 0x5011), | ||
2162 | .driver_data = AZX_DRIVER_CMEDIA | | ||
2163 | AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB }, | ||
2157 | /* Vortex86MX */ | 2164 | /* Vortex86MX */ |
2158 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | 2165 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, |
2159 | /* VMware HDAudio */ | 2166 | /* VMware HDAudio */ |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 4f3aba78f720..5d8455e2dacd 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -4376,6 +4376,9 @@ static void ca0132_download_dsp(struct hda_codec *codec) | |||
4376 | return; /* NOP */ | 4376 | return; /* NOP */ |
4377 | #endif | 4377 | #endif |
4378 | 4378 | ||
4379 | if (spec->dsp_state == DSP_DOWNLOAD_FAILED) | ||
4380 | return; /* don't retry failures */ | ||
4381 | |||
4379 | chipio_enable_clocks(codec); | 4382 | chipio_enable_clocks(codec); |
4380 | spec->dsp_state = DSP_DOWNLOADING; | 4383 | spec->dsp_state = DSP_DOWNLOADING; |
4381 | if (!ca0132_download_dsp_images(codec)) | 4384 | if (!ca0132_download_dsp_images(codec)) |
@@ -4552,7 +4555,8 @@ static int ca0132_init(struct hda_codec *codec) | |||
4552 | struct auto_pin_cfg *cfg = &spec->autocfg; | 4555 | struct auto_pin_cfg *cfg = &spec->autocfg; |
4553 | int i; | 4556 | int i; |
4554 | 4557 | ||
4555 | spec->dsp_state = DSP_DOWNLOAD_INIT; | 4558 | if (spec->dsp_state != DSP_DOWNLOAD_FAILED) |
4559 | spec->dsp_state = DSP_DOWNLOAD_INIT; | ||
4556 | spec->curr_chip_addx = INVALID_CHIP_ADDRESS; | 4560 | spec->curr_chip_addx = INVALID_CHIP_ADDRESS; |
4557 | 4561 | ||
4558 | snd_hda_power_up(codec); | 4562 | snd_hda_power_up(codec); |
@@ -4663,6 +4667,7 @@ static int patch_ca0132(struct hda_codec *codec) | |||
4663 | codec->spec = spec; | 4667 | codec->spec = spec; |
4664 | spec->codec = codec; | 4668 | spec->codec = codec; |
4665 | 4669 | ||
4670 | spec->dsp_state = DSP_DOWNLOAD_INIT; | ||
4666 | spec->num_mixers = 1; | 4671 | spec->num_mixers = 1; |
4667 | spec->mixers[0] = ca0132_mixer; | 4672 | spec->mixers[0] = ca0132_mixer; |
4668 | 4673 | ||
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index ed3d133ffbb6..c895a8f21192 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -75,15 +75,62 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
75 | return err; | 75 | return err; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int patch_cmi8888(struct hda_codec *codec) | ||
79 | { | ||
80 | struct cmi_spec *spec; | ||
81 | struct auto_pin_cfg *cfg; | ||
82 | int err; | ||
83 | |||
84 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
85 | if (!spec) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | codec->spec = spec; | ||
89 | cfg = &spec->gen.autocfg; | ||
90 | snd_hda_gen_spec_init(&spec->gen); | ||
91 | |||
92 | /* mask NID 0x10 from the playback volume selection; | ||
93 | * it's a headphone boost volume handled manually below | ||
94 | */ | ||
95 | spec->gen.out_vol_mask = (1ULL << 0x10); | ||
96 | |||
97 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); | ||
98 | if (err < 0) | ||
99 | goto error; | ||
100 | err = snd_hda_gen_parse_auto_config(codec, cfg); | ||
101 | if (err < 0) | ||
102 | goto error; | ||
103 | |||
104 | if (get_defcfg_device(snd_hda_codec_get_pincfg(codec, 0x10)) == | ||
105 | AC_JACK_HP_OUT) { | ||
106 | static const struct snd_kcontrol_new amp_kctl = | ||
107 | HDA_CODEC_VOLUME("Headphone Amp Playback Volume", | ||
108 | 0x10, 0, HDA_OUTPUT); | ||
109 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &_kctl)) { | ||
110 | err = -ENOMEM; | ||
111 | goto error; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | codec->patch_ops = cmi_auto_patch_ops; | ||
116 | return 0; | ||
117 | |||
118 | error: | ||
119 | snd_hda_gen_free(codec); | ||
120 | return err; | ||
121 | } | ||
122 | |||
78 | /* | 123 | /* |
79 | * patch entries | 124 | * patch entries |
80 | */ | 125 | */ |
81 | static const struct hda_codec_preset snd_hda_preset_cmedia[] = { | 126 | static const struct hda_codec_preset snd_hda_preset_cmedia[] = { |
127 | { .id = 0x13f68888, .name = "CMI8888", .patch = patch_cmi8888 }, | ||
82 | { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, | 128 | { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, |
83 | { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, | 129 | { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, |
84 | {} /* terminator */ | 130 | {} /* terminator */ |
85 | }; | 131 | }; |
86 | 132 | ||
133 | MODULE_ALIAS("snd-hda-codec-id:13f68888"); | ||
87 | MODULE_ALIAS("snd-hda-codec-id:13f69880"); | 134 | MODULE_ALIAS("snd-hda-codec-id:13f69880"); |
88 | MODULE_ALIAS("snd-hda-codec-id:434d4980"); | 135 | MODULE_ALIAS("snd-hda-codec-id:434d4980"); |
89 | 136 | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 7627a69ca6d7..6f2fa838b635 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <sound/core.h> | 27 | #include <sound/core.h> |
28 | #include <sound/jack.h> | 28 | #include <sound/jack.h> |
29 | #include <sound/tlv.h> | ||
29 | 30 | ||
30 | #include "hda_codec.h" | 31 | #include "hda_codec.h" |
31 | #include "hda_local.h" | 32 | #include "hda_local.h" |
@@ -859,6 +860,11 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
859 | if (err < 0) | 860 | if (err < 0) |
860 | goto error; | 861 | goto error; |
861 | 862 | ||
863 | if (codec->vendor_id == 0x14f15051) { | ||
864 | /* minimum value is actually mute */ | ||
865 | spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; | ||
866 | } | ||
867 | |||
862 | codec->patch_ops = cx_auto_patch_ops; | 868 | codec->patch_ops = cx_auto_patch_ops; |
863 | 869 | ||
864 | /* Some laptops with Conexant chips show stalls in S3 resume, | 870 | /* Some laptops with Conexant chips show stalls in S3 resume, |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 36badba2dcec..99d7d7fecaad 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -50,6 +50,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); | |||
50 | #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec)) | 50 | #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec)) |
51 | 51 | ||
52 | #define is_valleyview(codec) ((codec)->vendor_id == 0x80862882) | 52 | #define is_valleyview(codec) ((codec)->vendor_id == 0x80862882) |
53 | #define is_cherryview(codec) ((codec)->vendor_id == 0x80862883) | ||
54 | #define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec)) | ||
53 | 55 | ||
54 | struct hdmi_spec_per_cvt { | 56 | struct hdmi_spec_per_cvt { |
55 | hda_nid_t cvt_nid; | 57 | hda_nid_t cvt_nid; |
@@ -1459,7 +1461,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
1459 | mux_idx); | 1461 | mux_idx); |
1460 | 1462 | ||
1461 | /* configure unused pins to choose other converters */ | 1463 | /* configure unused pins to choose other converters */ |
1462 | if (is_haswell_plus(codec) || is_valleyview(codec)) | 1464 | if (is_haswell_plus(codec) || is_valleyview_plus(codec)) |
1463 | intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx); | 1465 | intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx); |
1464 | 1466 | ||
1465 | snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); | 1467 | snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); |
@@ -1598,7 +1600,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
1598 | * and this can make HW reset converter selection on a pin. | 1600 | * and this can make HW reset converter selection on a pin. |
1599 | */ | 1601 | */ |
1600 | if (eld->eld_valid && !old_eld_valid && per_pin->setup) { | 1602 | if (eld->eld_valid && !old_eld_valid && per_pin->setup) { |
1601 | if (is_haswell_plus(codec) || is_valleyview(codec)) { | 1603 | if (is_haswell_plus(codec) || |
1604 | is_valleyview_plus(codec)) { | ||
1602 | intel_verify_pin_cvt_connect(codec, per_pin); | 1605 | intel_verify_pin_cvt_connect(codec, per_pin); |
1603 | intel_not_share_assigned_cvt(codec, pin_nid, | 1606 | intel_not_share_assigned_cvt(codec, pin_nid, |
1604 | per_pin->mux_idx); | 1607 | per_pin->mux_idx); |
@@ -1779,7 +1782,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1779 | bool non_pcm; | 1782 | bool non_pcm; |
1780 | int pinctl; | 1783 | int pinctl; |
1781 | 1784 | ||
1782 | if (is_haswell_plus(codec) || is_valleyview(codec)) { | 1785 | if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { |
1783 | /* Verify pin:cvt selections to avoid silent audio after S3. | 1786 | /* Verify pin:cvt selections to avoid silent audio after S3. |
1784 | * After S3, the audio driver restores pin:cvt selections | 1787 | * After S3, the audio driver restores pin:cvt selections |
1785 | * but this can happen before gfx is ready and such selection | 1788 | * but this can happen before gfx is ready and such selection |
@@ -2330,9 +2333,8 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
2330 | intel_haswell_fixup_enable_dp12(codec); | 2333 | intel_haswell_fixup_enable_dp12(codec); |
2331 | } | 2334 | } |
2332 | 2335 | ||
2333 | if (is_haswell(codec) || is_valleyview(codec)) { | 2336 | if (is_haswell_plus(codec) || is_valleyview_plus(codec)) |
2334 | codec->depop_delay = 0; | 2337 | codec->depop_delay = 0; |
2335 | } | ||
2336 | 2338 | ||
2337 | if (hdmi_parse_codec(codec) < 0) { | 2339 | if (hdmi_parse_codec(codec) < 0) { |
2338 | codec->spec = NULL; | 2340 | codec->spec = NULL; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 654c8f16d150..d71270a3f73f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec) | |||
181 | spec->pll_coef_idx); | 181 | spec->pll_coef_idx); |
182 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, | 182 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, |
183 | AC_VERB_GET_PROC_COEF, 0); | 183 | AC_VERB_GET_PROC_COEF, 0); |
184 | if (val == -1) | ||
185 | return; | ||
184 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | 186 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, |
185 | spec->pll_coef_idx); | 187 | spec->pll_coef_idx); |
186 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, | 188 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, |
@@ -2782,9 +2784,32 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
2782 | return alc_parse_auto_config(codec, alc269_ignore, ssids); | 2784 | return alc_parse_auto_config(codec, alc269_ignore, ssids); |
2783 | } | 2785 | } |
2784 | 2786 | ||
2787 | static int find_ext_mic_pin(struct hda_codec *codec); | ||
2788 | |||
2789 | static void alc286_shutup(struct hda_codec *codec) | ||
2790 | { | ||
2791 | int i; | ||
2792 | int mic_pin = find_ext_mic_pin(codec); | ||
2793 | /* don't shut up pins when unloading the driver; otherwise it breaks | ||
2794 | * the default pin setup at the next load of the driver | ||
2795 | */ | ||
2796 | if (codec->bus->shutdown) | ||
2797 | return; | ||
2798 | for (i = 0; i < codec->init_pins.used; i++) { | ||
2799 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
2800 | /* use read here for syncing after issuing each verb */ | ||
2801 | if (pin->nid != mic_pin) | ||
2802 | snd_hda_codec_read(codec, pin->nid, 0, | ||
2803 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
2804 | } | ||
2805 | codec->pins_shutup = 1; | ||
2806 | } | ||
2807 | |||
2785 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) | 2808 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) |
2786 | { | 2809 | { |
2787 | int val = alc_read_coef_idx(codec, 0x04); | 2810 | int val = alc_read_coef_idx(codec, 0x04); |
2811 | if (val == -1) | ||
2812 | return; | ||
2788 | if (power_up) | 2813 | if (power_up) |
2789 | val |= 1 << 11; | 2814 | val |= 1 << 11; |
2790 | else | 2815 | else |
@@ -3243,6 +3268,15 @@ static int alc269_resume(struct hda_codec *codec) | |||
3243 | snd_hda_codec_resume_cache(codec); | 3268 | snd_hda_codec_resume_cache(codec); |
3244 | alc_inv_dmic_sync(codec, true); | 3269 | alc_inv_dmic_sync(codec, true); |
3245 | hda_call_check_power_status(codec, 0x01); | 3270 | hda_call_check_power_status(codec, 0x01); |
3271 | |||
3272 | /* on some machine, the BIOS will clear the codec gpio data when enter | ||
3273 | * suspend, and won't restore the data after resume, so we restore it | ||
3274 | * in the driver. | ||
3275 | */ | ||
3276 | if (spec->gpio_led) | ||
3277 | snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DATA, | ||
3278 | spec->gpio_led); | ||
3279 | |||
3246 | if (spec->has_alc5505_dsp) | 3280 | if (spec->has_alc5505_dsp) |
3247 | alc5505_dsp_resume(codec); | 3281 | alc5505_dsp_resume(codec); |
3248 | 3282 | ||
@@ -4072,7 +4106,7 @@ static unsigned int alc_power_filter_xps13(struct hda_codec *codec, | |||
4072 | 4106 | ||
4073 | /* Avoid pop noises when headphones are plugged in */ | 4107 | /* Avoid pop noises when headphones are plugged in */ |
4074 | if (spec->gen.hp_jack_present) | 4108 | if (spec->gen.hp_jack_present) |
4075 | if (nid == codec->afg || nid == 0x02) | 4109 | if (nid == codec->afg || nid == 0x02 || nid == 0x15) |
4076 | return AC_PWRST_D0; | 4110 | return AC_PWRST_D0; |
4077 | return power_state; | 4111 | return power_state; |
4078 | } | 4112 | } |
@@ -4082,8 +4116,19 @@ static void alc_fixup_dell_xps13(struct hda_codec *codec, | |||
4082 | { | 4116 | { |
4083 | if (action == HDA_FIXUP_ACT_PROBE) { | 4117 | if (action == HDA_FIXUP_ACT_PROBE) { |
4084 | struct alc_spec *spec = codec->spec; | 4118 | struct alc_spec *spec = codec->spec; |
4119 | struct hda_input_mux *imux = &spec->gen.input_mux; | ||
4120 | int i; | ||
4121 | |||
4085 | spec->shutup = alc_no_shutup; | 4122 | spec->shutup = alc_no_shutup; |
4086 | codec->power_filter = alc_power_filter_xps13; | 4123 | codec->power_filter = alc_power_filter_xps13; |
4124 | |||
4125 | /* Make the internal mic the default input source. */ | ||
4126 | for (i = 0; i < imux->num_items; i++) { | ||
4127 | if (spec->gen.imux_pins[i] == 0x12) { | ||
4128 | spec->gen.cur_mux[0] = i; | ||
4129 | break; | ||
4130 | } | ||
4131 | } | ||
4087 | } | 4132 | } |
4088 | } | 4133 | } |
4089 | 4134 | ||
@@ -5279,27 +5324,30 @@ static void alc269_fill_coef(struct hda_codec *codec) | |||
5279 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { | 5324 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
5280 | val = alc_read_coef_idx(codec, 0x04); | 5325 | val = alc_read_coef_idx(codec, 0x04); |
5281 | /* Power up output pin */ | 5326 | /* Power up output pin */ |
5282 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | 5327 | if (val != -1) |
5328 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | ||
5283 | } | 5329 | } |
5284 | 5330 | ||
5285 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { | 5331 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
5286 | val = alc_read_coef_idx(codec, 0xd); | 5332 | val = alc_read_coef_idx(codec, 0xd); |
5287 | if ((val & 0x0c00) >> 10 != 0x1) { | 5333 | if (val != -1 && (val & 0x0c00) >> 10 != 0x1) { |
5288 | /* Capless ramp up clock control */ | 5334 | /* Capless ramp up clock control */ |
5289 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); | 5335 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); |
5290 | } | 5336 | } |
5291 | val = alc_read_coef_idx(codec, 0x17); | 5337 | val = alc_read_coef_idx(codec, 0x17); |
5292 | if ((val & 0x01c0) >> 6 != 0x4) { | 5338 | if (val != -1 && (val & 0x01c0) >> 6 != 0x4) { |
5293 | /* Class D power on reset */ | 5339 | /* Class D power on reset */ |
5294 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); | 5340 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); |
5295 | } | 5341 | } |
5296 | } | 5342 | } |
5297 | 5343 | ||
5298 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ | 5344 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ |
5299 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 5345 | if (val != -1) |
5346 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | ||
5300 | 5347 | ||
5301 | val = alc_read_coef_idx(codec, 0x4); /* HP */ | 5348 | val = alc_read_coef_idx(codec, 0x4); /* HP */ |
5302 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | 5349 | if (val != -1) |
5350 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | ||
5303 | } | 5351 | } |
5304 | 5352 | ||
5305 | /* | 5353 | /* |
@@ -5384,6 +5432,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
5384 | case 0x10ec0286: | 5432 | case 0x10ec0286: |
5385 | case 0x10ec0288: | 5433 | case 0x10ec0288: |
5386 | spec->codec_variant = ALC269_TYPE_ALC286; | 5434 | spec->codec_variant = ALC269_TYPE_ALC286; |
5435 | spec->shutup = alc286_shutup; | ||
5387 | break; | 5436 | break; |
5388 | case 0x10ec0255: | 5437 | case 0x10ec0255: |
5389 | spec->codec_variant = ALC269_TYPE_ALC255; | 5438 | spec->codec_variant = ALC269_TYPE_ALC255; |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index bd41ee4da078..2c71f16bd661 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -1278,6 +1278,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
1278 | else | 1278 | else |
1279 | rates = &arizona_48k_bclk_rates[0]; | 1279 | rates = &arizona_48k_bclk_rates[0]; |
1280 | 1280 | ||
1281 | wl = snd_pcm_format_width(params_format(params)); | ||
1282 | |||
1281 | if (tdm_slots) { | 1283 | if (tdm_slots) { |
1282 | arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n", | 1284 | arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n", |
1283 | tdm_slots, tdm_width); | 1285 | tdm_slots, tdm_width); |
@@ -1285,6 +1287,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
1285 | channels = tdm_slots; | 1287 | channels = tdm_slots; |
1286 | } else { | 1288 | } else { |
1287 | bclk_target = snd_soc_params_to_bclk(params); | 1289 | bclk_target = snd_soc_params_to_bclk(params); |
1290 | tdm_width = wl; | ||
1288 | } | 1291 | } |
1289 | 1292 | ||
1290 | if (chan_limit && chan_limit < channels) { | 1293 | if (chan_limit && chan_limit < channels) { |
@@ -1319,8 +1322,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
1319 | arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", | 1322 | arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", |
1320 | rates[bclk], rates[bclk] / lrclk); | 1323 | rates[bclk], rates[bclk] / lrclk); |
1321 | 1324 | ||
1322 | wl = snd_pcm_format_width(params_format(params)); | 1325 | frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width; |
1323 | frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; | ||
1324 | 1326 | ||
1325 | reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame); | 1327 | reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame); |
1326 | 1328 | ||
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 163ec3855fd4..0c8aefab404c 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -259,13 +259,13 @@ static const struct soc_enum pcm512x_veds = | |||
259 | pcm512x_ramp_step_text); | 259 | pcm512x_ramp_step_text); |
260 | 260 | ||
261 | static const struct snd_kcontrol_new pcm512x_controls[] = { | 261 | static const struct snd_kcontrol_new pcm512x_controls[] = { |
262 | SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2, | 262 | SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, |
263 | PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), | 263 | PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), |
264 | SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, | 264 | SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, |
265 | PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), | 265 | PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), |
266 | SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, | 266 | SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, |
267 | PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), | 267 | PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), |
268 | SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, | 268 | SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, |
269 | PCM512x_RQMR_SHIFT, 1, 1), | 269 | PCM512x_RQMR_SHIFT, 1, 1), |
270 | 270 | ||
271 | SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), | 271 | SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index c28508da34cf..6a6b2ff7d7d7 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -403,7 +403,8 @@ out: | |||
403 | return ret; | 403 | return ret; |
404 | } | 404 | } |
405 | 405 | ||
406 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | 406 | static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, |
407 | int div, bool explicit) | ||
407 | { | 408 | { |
408 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | 409 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); |
409 | 410 | ||
@@ -420,7 +421,8 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div | |||
420 | ACLKXDIV(div - 1), ACLKXDIV_MASK); | 421 | ACLKXDIV(div - 1), ACLKXDIV_MASK); |
421 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, | 422 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, |
422 | ACLKRDIV(div - 1), ACLKRDIV_MASK); | 423 | ACLKRDIV(div - 1), ACLKRDIV_MASK); |
423 | mcasp->bclk_div = div; | 424 | if (explicit) |
425 | mcasp->bclk_div = div; | ||
424 | break; | 426 | break; |
425 | 427 | ||
426 | case 2: /* BCLK/LRCLK ratio */ | 428 | case 2: /* BCLK/LRCLK ratio */ |
@@ -434,6 +436,12 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div | |||
434 | return 0; | 436 | return 0; |
435 | } | 437 | } |
436 | 438 | ||
439 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, | ||
440 | int div) | ||
441 | { | ||
442 | return __davinci_mcasp_set_clkdiv(dai, div_id, div, 1); | ||
443 | } | ||
444 | |||
437 | static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, | 445 | static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, |
438 | unsigned int freq, int dir) | 446 | unsigned int freq, int dir) |
439 | { | 447 | { |
@@ -738,7 +746,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
738 | "Inaccurate BCLK: %u Hz / %u != %u Hz\n", | 746 | "Inaccurate BCLK: %u Hz / %u != %u Hz\n", |
739 | mcasp->sysclk_freq, div, bclk_freq); | 747 | mcasp->sysclk_freq, div, bclk_freq); |
740 | } | 748 | } |
741 | davinci_mcasp_set_clkdiv(cpu_dai, 1, div); | 749 | __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0); |
742 | } | 750 | } |
743 | 751 | ||
744 | ret = mcasp_common_hw_param(mcasp, substream->stream, | 752 | ret = mcasp_common_hw_param(mcasp, substream->stream, |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index f54a8fc99291..f3012b645b51 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -49,7 +49,6 @@ config SND_SOC_FSL_ESAI | |||
49 | tristate "Enhanced Serial Audio Interface (ESAI) module support" | 49 | tristate "Enhanced Serial Audio Interface (ESAI) module support" |
50 | select REGMAP_MMIO | 50 | select REGMAP_MMIO |
51 | select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n | 51 | select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n |
52 | select SND_SOC_FSL_UTILS | ||
53 | help | 52 | help |
54 | Say Y if you want to add Enhanced Synchronous Audio Interface | 53 | Say Y if you want to add Enhanced Synchronous Audio Interface |
55 | (ESAI) support for the Freescale CPUs. | 54 | (ESAI) support for the Freescale CPUs. |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 72d154e7dd03..a3b29ed84963 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include "fsl_esai.h" | 19 | #include "fsl_esai.h" |
20 | #include "imx-pcm.h" | 20 | #include "imx-pcm.h" |
21 | #include "fsl_utils.h" | ||
22 | 21 | ||
23 | #define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 | 22 | #define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 |
24 | #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ | 23 | #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ |
@@ -607,7 +606,6 @@ static struct snd_soc_dai_ops fsl_esai_dai_ops = { | |||
607 | .hw_params = fsl_esai_hw_params, | 606 | .hw_params = fsl_esai_hw_params, |
608 | .set_sysclk = fsl_esai_set_dai_sysclk, | 607 | .set_sysclk = fsl_esai_set_dai_sysclk, |
609 | .set_fmt = fsl_esai_set_dai_fmt, | 608 | .set_fmt = fsl_esai_set_dai_fmt, |
610 | .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask, | ||
611 | .set_tdm_slot = fsl_esai_set_dai_tdm_slot, | 609 | .set_tdm_slot = fsl_esai_set_dai_tdm_slot, |
612 | }; | 610 | }; |
613 | 611 | ||
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c index 42edc6f4fc4a..03d0a166b635 100644 --- a/sound/soc/intel/sst-acpi.c +++ b/sound/soc/intel/sst-acpi.c | |||
@@ -246,8 +246,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = { | |||
246 | }; | 246 | }; |
247 | 247 | ||
248 | static struct sst_acpi_mach baytrail_machines[] = { | 248 | static struct sst_acpi_mach baytrail_machines[] = { |
249 | { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" }, | 249 | { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, |
250 | { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-i2s_master" }, | 250 | { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, |
251 | {} | 251 | {} |
252 | }; | 252 | }; |
253 | 253 | ||
diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/sst-baytrail-ipc.c index 67673a2c0f41..b4ad98c43e5c 100644 --- a/sound/soc/intel/sst-baytrail-ipc.c +++ b/sound/soc/intel/sst-baytrail-ipc.c | |||
@@ -817,7 +817,7 @@ static struct sst_dsp_device byt_dev = { | |||
817 | .ops = &sst_byt_ops, | 817 | .ops = &sst_byt_ops, |
818 | }; | 818 | }; |
819 | 819 | ||
820 | int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) | 820 | int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata) |
821 | { | 821 | { |
822 | struct sst_byt *byt = pdata->dsp; | 822 | struct sst_byt *byt = pdata->dsp; |
823 | 823 | ||
@@ -826,14 +826,6 @@ int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) | |||
826 | sst_byt_drop_all(byt); | 826 | sst_byt_drop_all(byt); |
827 | dev_dbg(byt->dev, "dsp in reset\n"); | 827 | dev_dbg(byt->dev, "dsp in reset\n"); |
828 | 828 | ||
829 | return 0; | ||
830 | } | ||
831 | EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_noirq); | ||
832 | |||
833 | int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata) | ||
834 | { | ||
835 | struct sst_byt *byt = pdata->dsp; | ||
836 | |||
837 | dev_dbg(byt->dev, "free all blocks and unload fw\n"); | 829 | dev_dbg(byt->dev, "free all blocks and unload fw\n"); |
838 | sst_fw_unload(byt->fw); | 830 | sst_fw_unload(byt->fw); |
839 | 831 | ||
diff --git a/sound/soc/intel/sst-baytrail-ipc.h b/sound/soc/intel/sst-baytrail-ipc.h index 06a4d202689b..8faff6dcf25d 100644 --- a/sound/soc/intel/sst-baytrail-ipc.h +++ b/sound/soc/intel/sst-baytrail-ipc.h | |||
@@ -66,7 +66,6 @@ int sst_byt_get_dsp_position(struct sst_byt *byt, | |||
66 | int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata); | 66 | int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata); |
67 | void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata); | 67 | void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata); |
68 | struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt); | 68 | struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt); |
69 | int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata); | ||
70 | int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata); | 69 | int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata); |
71 | int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata); | 70 | int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata); |
72 | int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata); | 71 | int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata); |
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c index 599401c0c655..eab1c7d85187 100644 --- a/sound/soc/intel/sst-baytrail-pcm.c +++ b/sound/soc/intel/sst-baytrail-pcm.c | |||
@@ -59,6 +59,9 @@ struct sst_byt_priv_data { | |||
59 | 59 | ||
60 | /* DAI data */ | 60 | /* DAI data */ |
61 | struct sst_byt_pcm_data pcm[BYT_PCM_COUNT]; | 61 | struct sst_byt_pcm_data pcm[BYT_PCM_COUNT]; |
62 | |||
63 | /* flag indicating is stream context restore needed after suspend */ | ||
64 | bool restore_stream; | ||
62 | }; | 65 | }; |
63 | 66 | ||
64 | /* this may get called several times by oss emulation */ | 67 | /* this may get called several times by oss emulation */ |
@@ -184,7 +187,10 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
184 | sst_byt_stream_start(byt, pcm_data->stream, 0); | 187 | sst_byt_stream_start(byt, pcm_data->stream, 0); |
185 | break; | 188 | break; |
186 | case SNDRV_PCM_TRIGGER_RESUME: | 189 | case SNDRV_PCM_TRIGGER_RESUME: |
187 | schedule_work(&pcm_data->work); | 190 | if (pdata->restore_stream == true) |
191 | schedule_work(&pcm_data->work); | ||
192 | else | ||
193 | sst_byt_stream_resume(byt, pcm_data->stream); | ||
188 | break; | 194 | break; |
189 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 195 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
190 | sst_byt_stream_resume(byt, pcm_data->stream); | 196 | sst_byt_stream_resume(byt, pcm_data->stream); |
@@ -193,6 +199,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
193 | sst_byt_stream_stop(byt, pcm_data->stream); | 199 | sst_byt_stream_stop(byt, pcm_data->stream); |
194 | break; | 200 | break; |
195 | case SNDRV_PCM_TRIGGER_SUSPEND: | 201 | case SNDRV_PCM_TRIGGER_SUSPEND: |
202 | pdata->restore_stream = false; | ||
196 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 203 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
197 | sst_byt_stream_pause(byt, pcm_data->stream); | 204 | sst_byt_stream_pause(byt, pcm_data->stream); |
198 | break; | 205 | break; |
@@ -404,26 +411,10 @@ static const struct snd_soc_component_driver byt_dai_component = { | |||
404 | }; | 411 | }; |
405 | 412 | ||
406 | #ifdef CONFIG_PM | 413 | #ifdef CONFIG_PM |
407 | static int sst_byt_pcm_dev_suspend_noirq(struct device *dev) | ||
408 | { | ||
409 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | ||
410 | int ret; | ||
411 | |||
412 | dev_dbg(dev, "suspending noirq\n"); | ||
413 | |||
414 | /* at this point all streams will be stopped and context saved */ | ||
415 | ret = sst_byt_dsp_suspend_noirq(dev, sst_pdata); | ||
416 | if (ret < 0) { | ||
417 | dev_err(dev, "failed to suspend %d\n", ret); | ||
418 | return ret; | ||
419 | } | ||
420 | |||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | static int sst_byt_pcm_dev_suspend_late(struct device *dev) | 414 | static int sst_byt_pcm_dev_suspend_late(struct device *dev) |
425 | { | 415 | { |
426 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | 416 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); |
417 | struct sst_byt_priv_data *priv_data = dev_get_drvdata(dev); | ||
427 | int ret; | 418 | int ret; |
428 | 419 | ||
429 | dev_dbg(dev, "suspending late\n"); | 420 | dev_dbg(dev, "suspending late\n"); |
@@ -434,34 +425,30 @@ static int sst_byt_pcm_dev_suspend_late(struct device *dev) | |||
434 | return ret; | 425 | return ret; |
435 | } | 426 | } |
436 | 427 | ||
428 | priv_data->restore_stream = true; | ||
429 | |||
437 | return ret; | 430 | return ret; |
438 | } | 431 | } |
439 | 432 | ||
440 | static int sst_byt_pcm_dev_resume_early(struct device *dev) | 433 | static int sst_byt_pcm_dev_resume_early(struct device *dev) |
441 | { | 434 | { |
442 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | 435 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); |
436 | int ret; | ||
443 | 437 | ||
444 | dev_dbg(dev, "resume early\n"); | 438 | dev_dbg(dev, "resume early\n"); |
445 | 439 | ||
446 | /* load fw and boot DSP */ | 440 | /* load fw and boot DSP */ |
447 | return sst_byt_dsp_boot(dev, sst_pdata); | 441 | ret = sst_byt_dsp_boot(dev, sst_pdata); |
448 | } | 442 | if (ret) |
449 | 443 | return ret; | |
450 | static int sst_byt_pcm_dev_resume(struct device *dev) | ||
451 | { | ||
452 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | ||
453 | |||
454 | dev_dbg(dev, "resume\n"); | ||
455 | 444 | ||
456 | /* wait for FW to finish booting */ | 445 | /* wait for FW to finish booting */ |
457 | return sst_byt_dsp_wait_for_ready(dev, sst_pdata); | 446 | return sst_byt_dsp_wait_for_ready(dev, sst_pdata); |
458 | } | 447 | } |
459 | 448 | ||
460 | static const struct dev_pm_ops sst_byt_pm_ops = { | 449 | static const struct dev_pm_ops sst_byt_pm_ops = { |
461 | .suspend_noirq = sst_byt_pcm_dev_suspend_noirq, | ||
462 | .suspend_late = sst_byt_pcm_dev_suspend_late, | 450 | .suspend_late = sst_byt_pcm_dev_suspend_late, |
463 | .resume_early = sst_byt_pcm_dev_resume_early, | 451 | .resume_early = sst_byt_pcm_dev_resume_early, |
464 | .resume = sst_byt_pcm_dev_resume, | ||
465 | }; | 452 | }; |
466 | 453 | ||
467 | #define SST_BYT_PM_OPS (&sst_byt_pm_ops) | 454 | #define SST_BYT_PM_OPS (&sst_byt_pm_ops) |
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 0109f6c2334e..a8e097433074 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -765,9 +765,7 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai) | |||
765 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ | 765 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ |
766 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | 766 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) |
767 | 767 | ||
768 | #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | 768 | #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) |
769 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
770 | SNDRV_PCM_FMTBIT_S32_LE) | ||
771 | 769 | ||
772 | static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { | 770 | static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { |
773 | .startup = pxa_ssp_startup, | 771 | .startup = pxa_ssp_startup, |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8348352dc2c6..177bd8639ef9 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -2860,12 +2860,14 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, | |||
2860 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); | 2860 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); |
2861 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2861 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2862 | unsigned int reg_val, val; | 2862 | unsigned int reg_val, val; |
2863 | int ret = 0; | ||
2864 | 2863 | ||
2865 | if (e->reg != SND_SOC_NOPM) | 2864 | if (e->reg != SND_SOC_NOPM) { |
2866 | ret = soc_dapm_read(dapm, e->reg, ®_val); | 2865 | int ret = soc_dapm_read(dapm, e->reg, ®_val); |
2867 | else | 2866 | if (ret) |
2867 | return ret; | ||
2868 | } else { | ||
2868 | reg_val = dapm_kcontrol_get_value(kcontrol); | 2869 | reg_val = dapm_kcontrol_get_value(kcontrol); |
2870 | } | ||
2869 | 2871 | ||
2870 | val = (reg_val >> e->shift_l) & e->mask; | 2872 | val = (reg_val >> e->shift_l) & e->mask; |
2871 | ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); | 2873 | ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); |
@@ -2875,7 +2877,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, | |||
2875 | ucontrol->value.enumerated.item[1] = val; | 2877 | ucontrol->value.enumerated.item[1] = val; |
2876 | } | 2878 | } |
2877 | 2879 | ||
2878 | return ret; | 2880 | return 0; |
2879 | } | 2881 | } |
2880 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); | 2882 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); |
2881 | 2883 | ||
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index f652b10ce905..223c47b33ba3 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1581,6 +1581,35 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1581 | } | 1581 | } |
1582 | }, | 1582 | }, |
1583 | { | 1583 | { |
1584 | /* BOSS ME-25 */ | ||
1585 | USB_DEVICE(0x0582, 0x0113), | ||
1586 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1587 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1588 | .type = QUIRK_COMPOSITE, | ||
1589 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1590 | { | ||
1591 | .ifnum = 0, | ||
1592 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1593 | }, | ||
1594 | { | ||
1595 | .ifnum = 1, | ||
1596 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1597 | }, | ||
1598 | { | ||
1599 | .ifnum = 2, | ||
1600 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1601 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1602 | .out_cables = 0x0001, | ||
1603 | .in_cables = 0x0001 | ||
1604 | } | ||
1605 | }, | ||
1606 | { | ||
1607 | .ifnum = -1 | ||
1608 | } | ||
1609 | } | ||
1610 | } | ||
1611 | }, | ||
1612 | { | ||
1584 | /* only 44.1 kHz works at the moment */ | 1613 | /* only 44.1 kHz works at the moment */ |
1585 | USB_DEVICE(0x0582, 0x0120), | 1614 | USB_DEVICE(0x0582, 0x0120), |
1586 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1615 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index d0396af99fa0..5b1b807265a1 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -267,90 +267,90 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) | |||
267 | /* | 267 | /* |
268 | * Example Format w/ field column widths: | 268 | * Example Format w/ field column widths: |
269 | * | 269 | * |
270 | * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt | 270 | * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt |
271 | * 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 | 271 | * 123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678 |
272 | */ | 272 | */ |
273 | 273 | ||
274 | void print_header(void) | 274 | void print_header(void) |
275 | { | 275 | { |
276 | if (show_pkg) | 276 | if (show_pkg) |
277 | outp += sprintf(outp, "Package "); | 277 | outp += sprintf(outp, " Package"); |
278 | if (show_core) | 278 | if (show_core) |
279 | outp += sprintf(outp, " Core "); | 279 | outp += sprintf(outp, " Core"); |
280 | if (show_cpu) | 280 | if (show_cpu) |
281 | outp += sprintf(outp, " CPU "); | 281 | outp += sprintf(outp, " CPU"); |
282 | if (has_aperf) | 282 | if (has_aperf) |
283 | outp += sprintf(outp, "Avg_MHz "); | 283 | outp += sprintf(outp, " Avg_MHz"); |
284 | if (do_nhm_cstates) | 284 | if (do_nhm_cstates) |
285 | outp += sprintf(outp, " %%Busy "); | 285 | outp += sprintf(outp, " %%Busy"); |
286 | if (has_aperf) | 286 | if (has_aperf) |
287 | outp += sprintf(outp, "Bzy_MHz "); | 287 | outp += sprintf(outp, " Bzy_MHz"); |
288 | outp += sprintf(outp, "TSC_MHz "); | 288 | outp += sprintf(outp, " TSC_MHz"); |
289 | if (do_smi) | 289 | if (do_smi) |
290 | outp += sprintf(outp, " SMI "); | 290 | outp += sprintf(outp, " SMI"); |
291 | if (extra_delta_offset32) | 291 | if (extra_delta_offset32) |
292 | outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32); | 292 | outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); |
293 | if (extra_delta_offset64) | 293 | if (extra_delta_offset64) |
294 | outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64); | 294 | outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); |
295 | if (extra_msr_offset32) | 295 | if (extra_msr_offset32) |
296 | outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32); | 296 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); |
297 | if (extra_msr_offset64) | 297 | if (extra_msr_offset64) |
298 | outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64); | 298 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); |
299 | if (do_nhm_cstates) | 299 | if (do_nhm_cstates) |
300 | outp += sprintf(outp, " CPU%%c1 "); | 300 | outp += sprintf(outp, " CPU%%c1"); |
301 | if (do_nhm_cstates && !do_slm_cstates) | 301 | if (do_nhm_cstates && !do_slm_cstates) |
302 | outp += sprintf(outp, " CPU%%c3 "); | 302 | outp += sprintf(outp, " CPU%%c3"); |
303 | if (do_nhm_cstates) | 303 | if (do_nhm_cstates) |
304 | outp += sprintf(outp, " CPU%%c6 "); | 304 | outp += sprintf(outp, " CPU%%c6"); |
305 | if (do_snb_cstates) | 305 | if (do_snb_cstates) |
306 | outp += sprintf(outp, " CPU%%c7 "); | 306 | outp += sprintf(outp, " CPU%%c7"); |
307 | 307 | ||
308 | if (do_dts) | 308 | if (do_dts) |
309 | outp += sprintf(outp, "CoreTmp "); | 309 | outp += sprintf(outp, " CoreTmp"); |
310 | if (do_ptm) | 310 | if (do_ptm) |
311 | outp += sprintf(outp, " PkgTmp "); | 311 | outp += sprintf(outp, " PkgTmp"); |
312 | 312 | ||
313 | if (do_snb_cstates) | 313 | if (do_snb_cstates) |
314 | outp += sprintf(outp, "Pkg%%pc2 "); | 314 | outp += sprintf(outp, " Pkg%%pc2"); |
315 | if (do_nhm_cstates && !do_slm_cstates) | 315 | if (do_nhm_cstates && !do_slm_cstates) |
316 | outp += sprintf(outp, "Pkg%%pc3 "); | 316 | outp += sprintf(outp, " Pkg%%pc3"); |
317 | if (do_nhm_cstates && !do_slm_cstates) | 317 | if (do_nhm_cstates && !do_slm_cstates) |
318 | outp += sprintf(outp, "Pkg%%pc6 "); | 318 | outp += sprintf(outp, " Pkg%%pc6"); |
319 | if (do_snb_cstates) | 319 | if (do_snb_cstates) |
320 | outp += sprintf(outp, "Pkg%%pc7 "); | 320 | outp += sprintf(outp, " Pkg%%pc7"); |
321 | if (do_c8_c9_c10) { | 321 | if (do_c8_c9_c10) { |
322 | outp += sprintf(outp, "Pkg%%pc8 "); | 322 | outp += sprintf(outp, " Pkg%%pc8"); |
323 | outp += sprintf(outp, "Pkg%%pc9 "); | 323 | outp += sprintf(outp, " Pkg%%pc9"); |
324 | outp += sprintf(outp, "Pk%%pc10 "); | 324 | outp += sprintf(outp, " Pk%%pc10"); |
325 | } | 325 | } |
326 | 326 | ||
327 | if (do_rapl && !rapl_joules) { | 327 | if (do_rapl && !rapl_joules) { |
328 | if (do_rapl & RAPL_PKG) | 328 | if (do_rapl & RAPL_PKG) |
329 | outp += sprintf(outp, "PkgWatt "); | 329 | outp += sprintf(outp, " PkgWatt"); |
330 | if (do_rapl & RAPL_CORES) | 330 | if (do_rapl & RAPL_CORES) |
331 | outp += sprintf(outp, "CorWatt "); | 331 | outp += sprintf(outp, " CorWatt"); |
332 | if (do_rapl & RAPL_GFX) | 332 | if (do_rapl & RAPL_GFX) |
333 | outp += sprintf(outp, "GFXWatt "); | 333 | outp += sprintf(outp, " GFXWatt"); |
334 | if (do_rapl & RAPL_DRAM) | 334 | if (do_rapl & RAPL_DRAM) |
335 | outp += sprintf(outp, "RAMWatt "); | 335 | outp += sprintf(outp, " RAMWatt"); |
336 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 336 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
337 | outp += sprintf(outp, " PKG_%% "); | 337 | outp += sprintf(outp, " PKG_%%"); |
338 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 338 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
339 | outp += sprintf(outp, " RAM_%% "); | 339 | outp += sprintf(outp, " RAM_%%"); |
340 | } else { | 340 | } else { |
341 | if (do_rapl & RAPL_PKG) | 341 | if (do_rapl & RAPL_PKG) |
342 | outp += sprintf(outp, " Pkg_J "); | 342 | outp += sprintf(outp, " Pkg_J"); |
343 | if (do_rapl & RAPL_CORES) | 343 | if (do_rapl & RAPL_CORES) |
344 | outp += sprintf(outp, " Cor_J "); | 344 | outp += sprintf(outp, " Cor_J"); |
345 | if (do_rapl & RAPL_GFX) | 345 | if (do_rapl & RAPL_GFX) |
346 | outp += sprintf(outp, " GFX_J "); | 346 | outp += sprintf(outp, " GFX_J"); |
347 | if (do_rapl & RAPL_DRAM) | 347 | if (do_rapl & RAPL_DRAM) |
348 | outp += sprintf(outp, " RAM_W "); | 348 | outp += sprintf(outp, " RAM_W"); |
349 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 349 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
350 | outp += sprintf(outp, " PKG_%% "); | 350 | outp += sprintf(outp, " PKG_%%"); |
351 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 351 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
352 | outp += sprintf(outp, " RAM_%% "); | 352 | outp += sprintf(outp, " RAM_%%"); |
353 | outp += sprintf(outp, " time "); | 353 | outp += sprintf(outp, " time"); |
354 | 354 | ||
355 | } | 355 | } |
356 | outp += sprintf(outp, "\n"); | 356 | outp += sprintf(outp, "\n"); |
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index bf06577fea51..5819a2708d7e 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -526,8 +526,10 @@ static int assign_guest_irq(struct kvm *kvm, | |||
526 | dev->irq_requested_type |= guest_irq_type; | 526 | dev->irq_requested_type |= guest_irq_type; |
527 | if (dev->ack_notifier.gsi != -1) | 527 | if (dev->ack_notifier.gsi != -1) |
528 | kvm_register_irq_ack_notifier(kvm, &dev->ack_notifier); | 528 | kvm_register_irq_ack_notifier(kvm, &dev->ack_notifier); |
529 | } else | 529 | } else { |
530 | kvm_free_irq_source_id(kvm, dev->irq_source_id); | 530 | kvm_free_irq_source_id(kvm, dev->irq_source_id); |
531 | dev->irq_source_id = -1; | ||
532 | } | ||
531 | 533 | ||
532 | return r; | 534 | return r; |
533 | } | 535 | } |
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index 0df7d4b34dfe..714b94932312 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
@@ -61,6 +61,14 @@ static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn, | |||
61 | return pfn; | 61 | return pfn; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages) | ||
65 | { | ||
66 | unsigned long i; | ||
67 | |||
68 | for (i = 0; i < npages; ++i) | ||
69 | kvm_release_pfn_clean(pfn + i); | ||
70 | } | ||
71 | |||
64 | int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | 72 | int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) |
65 | { | 73 | { |
66 | gfn_t gfn, end_gfn; | 74 | gfn_t gfn, end_gfn; |
@@ -123,6 +131,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | |||
123 | if (r) { | 131 | if (r) { |
124 | printk(KERN_ERR "kvm_iommu_map_address:" | 132 | printk(KERN_ERR "kvm_iommu_map_address:" |
125 | "iommu failed to map pfn=%llx\n", pfn); | 133 | "iommu failed to map pfn=%llx\n", pfn); |
134 | kvm_unpin_pages(kvm, pfn, page_size); | ||
126 | goto unmap_pages; | 135 | goto unmap_pages; |
127 | } | 136 | } |
128 | 137 | ||
@@ -134,7 +143,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | |||
134 | return 0; | 143 | return 0; |
135 | 144 | ||
136 | unmap_pages: | 145 | unmap_pages: |
137 | kvm_iommu_put_pages(kvm, slot->base_gfn, gfn); | 146 | kvm_iommu_put_pages(kvm, slot->base_gfn, gfn - slot->base_gfn); |
138 | return r; | 147 | return r; |
139 | } | 148 | } |
140 | 149 | ||
@@ -266,14 +275,6 @@ out_unlock: | |||
266 | return r; | 275 | return r; |
267 | } | 276 | } |
268 | 277 | ||
269 | static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages) | ||
270 | { | ||
271 | unsigned long i; | ||
272 | |||
273 | for (i = 0; i < npages; ++i) | ||
274 | kvm_release_pfn_clean(pfn + i); | ||
275 | } | ||
276 | |||
277 | static void kvm_iommu_put_pages(struct kvm *kvm, | 278 | static void kvm_iommu_put_pages(struct kvm *kvm, |
278 | gfn_t base_gfn, unsigned long npages) | 279 | gfn_t base_gfn, unsigned long npages) |
279 | { | 280 | { |