diff options
274 files changed, 2840 insertions, 1642 deletions
@@ -2204,6 +2204,10 @@ S: Post Office Box 371 | |||
2204 | S: North Little Rock, Arkansas 72115 | 2204 | S: North Little Rock, Arkansas 72115 |
2205 | S: USA | 2205 | S: USA |
2206 | 2206 | ||
2207 | N: Christopher Li | ||
2208 | E: sparse@chrisli.org | ||
2209 | D: Sparse maintainer 2009 - 2018 | ||
2210 | |||
2207 | N: Stephan Linz | 2211 | N: Stephan Linz |
2208 | E: linz@mazet.de | 2212 | E: linz@mazet.de |
2209 | E: Stephan.Linz@gmx.de | 2213 | E: Stephan.Linz@gmx.de |
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 81d1d5a74728..19f4423e70d9 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -4713,6 +4713,8 @@ | |||
4713 | prevent spurious wakeup); | 4713 | prevent spurious wakeup); |
4714 | n = USB_QUIRK_DELAY_CTRL_MSG (Device needs a | 4714 | n = USB_QUIRK_DELAY_CTRL_MSG (Device needs a |
4715 | pause after every control message); | 4715 | pause after every control message); |
4716 | o = USB_QUIRK_HUB_SLOW_RESET (Hub needs extra | ||
4717 | delay after resetting its port); | ||
4716 | Example: quirks=0781:5580:bk,0a5c:5834:gij | 4718 | Example: quirks=0781:5580:bk,0a5c:5834:gij |
4717 | 4719 | ||
4718 | usbhid.mousepoll= | 4720 | usbhid.mousepoll= |
diff --git a/Documentation/admin-guide/security-bugs.rst b/Documentation/admin-guide/security-bugs.rst index 164bf71149fd..30187d49dc2c 100644 --- a/Documentation/admin-guide/security-bugs.rst +++ b/Documentation/admin-guide/security-bugs.rst | |||
@@ -32,16 +32,17 @@ Disclosure and embargoed information | |||
32 | The security list is not a disclosure channel. For that, see Coordination | 32 | The security list is not a disclosure channel. For that, see Coordination |
33 | below. | 33 | below. |
34 | 34 | ||
35 | Once a robust fix has been developed, our preference is to release the | 35 | Once a robust fix has been developed, the release process starts. Fixes |
36 | fix in a timely fashion, treating it no differently than any of the other | 36 | for publicly known bugs are released immediately. |
37 | thousands of changes and fixes the Linux kernel project releases every | 37 | |
38 | month. | 38 | Although our preference is to release fixes for publicly undisclosed bugs |
39 | 39 | as soon as they become available, this may be postponed at the request of | |
40 | However, at the request of the reporter, we will postpone releasing the | 40 | the reporter or an affected party for up to 7 calendar days from the start |
41 | fix for up to 5 business days after the date of the report or after the | 41 | of the release process, with an exceptional extension to 14 calendar days |
42 | embargo has lifted; whichever comes first. The only exception to that | 42 | if it is agreed that the criticality of the bug requires more time. The |
43 | rule is if the bug is publicly known, in which case the preference is to | 43 | only valid reason for deferring the publication of a fix is to accommodate |
44 | release the fix as soon as it's available. | 44 | the logistics of QA and large scale rollouts which require release |
45 | coordination. | ||
45 | 46 | ||
46 | Whilst embargoed information may be shared with trusted individuals in | 47 | Whilst embargoed information may be shared with trusted individuals in |
47 | order to develop a fix, such information will not be published alongside | 48 | order to develop a fix, such information will not be published alongside |
diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst index a4e705108f42..dbe96cb5558e 100644 --- a/Documentation/core-api/xarray.rst +++ b/Documentation/core-api/xarray.rst | |||
@@ -74,7 +74,8 @@ using :c:func:`xa_load`. xa_store will overwrite any entry with the | |||
74 | new entry and return the previous entry stored at that index. You can | 74 | new entry and return the previous entry stored at that index. You can |
75 | use :c:func:`xa_erase` instead of calling :c:func:`xa_store` with a | 75 | use :c:func:`xa_erase` instead of calling :c:func:`xa_store` with a |
76 | ``NULL`` entry. There is no difference between an entry that has never | 76 | ``NULL`` entry. There is no difference between an entry that has never |
77 | been stored to and one that has most recently had ``NULL`` stored to it. | 77 | been stored to, one that has been erased and one that has most recently |
78 | had ``NULL`` stored to it. | ||
78 | 79 | ||
79 | You can conditionally replace an entry at an index by using | 80 | You can conditionally replace an entry at an index by using |
80 | :c:func:`xa_cmpxchg`. Like :c:func:`cmpxchg`, it will only succeed if | 81 | :c:func:`xa_cmpxchg`. Like :c:func:`cmpxchg`, it will only succeed if |
@@ -105,23 +106,44 @@ may result in the entry being marked at some, but not all of the other | |||
105 | indices. Storing into one index may result in the entry retrieved by | 106 | indices. Storing into one index may result in the entry retrieved by |
106 | some, but not all of the other indices changing. | 107 | some, but not all of the other indices changing. |
107 | 108 | ||
109 | Sometimes you need to ensure that a subsequent call to :c:func:`xa_store` | ||
110 | will not need to allocate memory. The :c:func:`xa_reserve` function | ||
111 | will store a reserved entry at the indicated index. Users of the normal | ||
112 | API will see this entry as containing ``NULL``. If you do not need to | ||
113 | use the reserved entry, you can call :c:func:`xa_release` to remove the | ||
114 | unused entry. If another user has stored to the entry in the meantime, | ||
115 | :c:func:`xa_release` will do nothing; if instead you want the entry to | ||
116 | become ``NULL``, you should use :c:func:`xa_erase`. | ||
117 | |||
118 | If all entries in the array are ``NULL``, the :c:func:`xa_empty` function | ||
119 | will return ``true``. | ||
120 | |||
108 | Finally, you can remove all entries from an XArray by calling | 121 | Finally, you can remove all entries from an XArray by calling |
109 | :c:func:`xa_destroy`. If the XArray entries are pointers, you may wish | 122 | :c:func:`xa_destroy`. If the XArray entries are pointers, you may wish |
110 | to free the entries first. You can do this by iterating over all present | 123 | to free the entries first. You can do this by iterating over all present |
111 | entries in the XArray using the :c:func:`xa_for_each` iterator. | 124 | entries in the XArray using the :c:func:`xa_for_each` iterator. |
112 | 125 | ||
113 | ID assignment | 126 | Allocating XArrays |
114 | ------------- | 127 | ------------------ |
128 | |||
129 | If you use :c:func:`DEFINE_XARRAY_ALLOC` to define the XArray, or | ||
130 | initialise it by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`, | ||
131 | the XArray changes to track whether entries are in use or not. | ||
115 | 132 | ||
116 | You can call :c:func:`xa_alloc` to store the entry at any unused index | 133 | You can call :c:func:`xa_alloc` to store the entry at any unused index |
117 | in the XArray. If you need to modify the array from interrupt context, | 134 | in the XArray. If you need to modify the array from interrupt context, |
118 | you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable | 135 | you can use :c:func:`xa_alloc_bh` or :c:func:`xa_alloc_irq` to disable |
119 | interrupts while allocating the ID. Unlike :c:func:`xa_store`, allocating | 136 | interrupts while allocating the ID. |
120 | a ``NULL`` pointer does not delete an entry. Instead it reserves an | 137 | |
121 | entry like :c:func:`xa_reserve` and you can release it using either | 138 | Using :c:func:`xa_store`, :c:func:`xa_cmpxchg` or :c:func:`xa_insert` |
122 | :c:func:`xa_erase` or :c:func:`xa_release`. To use ID assignment, the | 139 | will mark the entry as being allocated. Unlike a normal XArray, storing |
123 | XArray must be defined with :c:func:`DEFINE_XARRAY_ALLOC`, or initialised | 140 | ``NULL`` will mark the entry as being in use, like :c:func:`xa_reserve`. |
124 | by passing ``XA_FLAGS_ALLOC`` to :c:func:`xa_init_flags`, | 141 | To free an entry, use :c:func:`xa_erase` (or :c:func:`xa_release` if |
142 | you only want to free the entry if it's ``NULL``). | ||
143 | |||
144 | You cannot use ``XA_MARK_0`` with an allocating XArray as this mark | ||
145 | is used to track whether an entry is free or not. The other marks are | ||
146 | available for your use. | ||
125 | 147 | ||
126 | Memory allocation | 148 | Memory allocation |
127 | ----------------- | 149 | ----------------- |
@@ -158,6 +180,8 @@ Takes RCU read lock: | |||
158 | 180 | ||
159 | Takes xa_lock internally: | 181 | Takes xa_lock internally: |
160 | * :c:func:`xa_store` | 182 | * :c:func:`xa_store` |
183 | * :c:func:`xa_store_bh` | ||
184 | * :c:func:`xa_store_irq` | ||
161 | * :c:func:`xa_insert` | 185 | * :c:func:`xa_insert` |
162 | * :c:func:`xa_erase` | 186 | * :c:func:`xa_erase` |
163 | * :c:func:`xa_erase_bh` | 187 | * :c:func:`xa_erase_bh` |
@@ -167,6 +191,9 @@ Takes xa_lock internally: | |||
167 | * :c:func:`xa_alloc` | 191 | * :c:func:`xa_alloc` |
168 | * :c:func:`xa_alloc_bh` | 192 | * :c:func:`xa_alloc_bh` |
169 | * :c:func:`xa_alloc_irq` | 193 | * :c:func:`xa_alloc_irq` |
194 | * :c:func:`xa_reserve` | ||
195 | * :c:func:`xa_reserve_bh` | ||
196 | * :c:func:`xa_reserve_irq` | ||
170 | * :c:func:`xa_destroy` | 197 | * :c:func:`xa_destroy` |
171 | * :c:func:`xa_set_mark` | 198 | * :c:func:`xa_set_mark` |
172 | * :c:func:`xa_clear_mark` | 199 | * :c:func:`xa_clear_mark` |
@@ -177,6 +204,7 @@ Assumes xa_lock held on entry: | |||
177 | * :c:func:`__xa_erase` | 204 | * :c:func:`__xa_erase` |
178 | * :c:func:`__xa_cmpxchg` | 205 | * :c:func:`__xa_cmpxchg` |
179 | * :c:func:`__xa_alloc` | 206 | * :c:func:`__xa_alloc` |
207 | * :c:func:`__xa_reserve` | ||
180 | * :c:func:`__xa_set_mark` | 208 | * :c:func:`__xa_set_mark` |
181 | * :c:func:`__xa_clear_mark` | 209 | * :c:func:`__xa_clear_mark` |
182 | 210 | ||
@@ -234,7 +262,8 @@ Sharing the XArray with interrupt context is also possible, either | |||
234 | using :c:func:`xa_lock_irqsave` in both the interrupt handler and process | 262 | using :c:func:`xa_lock_irqsave` in both the interrupt handler and process |
235 | context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock` | 263 | context, or :c:func:`xa_lock_irq` in process context and :c:func:`xa_lock` |
236 | in the interrupt handler. Some of the more common patterns have helper | 264 | in the interrupt handler. Some of the more common patterns have helper |
237 | functions such as :c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`. | 265 | functions such as :c:func:`xa_store_bh`, :c:func:`xa_store_irq`, |
266 | :c:func:`xa_erase_bh` and :c:func:`xa_erase_irq`. | ||
238 | 267 | ||
239 | Sometimes you need to protect access to the XArray with a mutex because | 268 | Sometimes you need to protect access to the XArray with a mutex because |
240 | that lock sits above another mutex in the locking hierarchy. That does | 269 | that lock sits above another mutex in the locking hierarchy. That does |
@@ -322,7 +351,8 @@ to :c:func:`xas_retry`, and retry the operation if it returns ``true``. | |||
322 | - :c:func:`xa_is_zero` | 351 | - :c:func:`xa_is_zero` |
323 | - Zero entries appear as ``NULL`` through the Normal API, but occupy | 352 | - Zero entries appear as ``NULL`` through the Normal API, but occupy |
324 | an entry in the XArray which can be used to reserve the index for | 353 | an entry in the XArray which can be used to reserve the index for |
325 | future use. | 354 | future use. This is used by allocating XArrays for allocated entries |
355 | which are ``NULL``. | ||
326 | 356 | ||
327 | Other internal entries may be added in the future. As far as possible, they | 357 | Other internal entries may be added in the future. As far as possible, they |
328 | will be handled by :c:func:`xas_retry`. | 358 | will be handled by :c:func:`xas_retry`. |
diff --git a/Documentation/devicetree/bindings/net/can/holt_hi311x.txt b/Documentation/devicetree/bindings/net/can/holt_hi311x.txt index 903a78da65be..3a9926f99937 100644 --- a/Documentation/devicetree/bindings/net/can/holt_hi311x.txt +++ b/Documentation/devicetree/bindings/net/can/holt_hi311x.txt | |||
@@ -17,7 +17,7 @@ Example: | |||
17 | reg = <1>; | 17 | reg = <1>; |
18 | clocks = <&clk32m>; | 18 | clocks = <&clk32m>; |
19 | interrupt-parent = <&gpio4>; | 19 | interrupt-parent = <&gpio4>; |
20 | interrupts = <13 IRQ_TYPE_EDGE_RISING>; | 20 | interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; |
21 | vdd-supply = <®5v0>; | 21 | vdd-supply = <®5v0>; |
22 | xceiver-supply = <®5v0>; | 22 | xceiver-supply = <®5v0>; |
23 | }; | 23 | }; |
diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt index cc4372842bf3..9936b9ee67c3 100644 --- a/Documentation/devicetree/bindings/net/can/rcar_can.txt +++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt | |||
@@ -5,6 +5,7 @@ Required properties: | |||
5 | - compatible: "renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC. | 5 | - compatible: "renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC. |
6 | "renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC. | 6 | "renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC. |
7 | "renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC. | 7 | "renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC. |
8 | "renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC. | ||
8 | "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC. | 9 | "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC. |
9 | "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC. | 10 | "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC. |
10 | "renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC. | 11 | "renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC. |
@@ -14,26 +15,32 @@ Required properties: | |||
14 | "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC. | 15 | "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC. |
15 | "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC. | 16 | "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC. |
16 | "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC. | 17 | "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC. |
18 | "renesas,can-r8a77965" if CAN controller is a part of R8A77965 SoC. | ||
17 | "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device. | 19 | "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device. |
18 | "renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1 | 20 | "renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1 |
19 | compatible device. | 21 | compatible device. |
20 | "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device. | 22 | "renesas,rcar-gen3-can" for a generic R-Car Gen3 or RZ/G2 |
23 | compatible device. | ||
21 | When compatible with the generic version, nodes must list the | 24 | When compatible with the generic version, nodes must list the |
22 | SoC-specific version corresponding to the platform first | 25 | SoC-specific version corresponding to the platform first |
23 | followed by the generic version. | 26 | followed by the generic version. |
24 | 27 | ||
25 | - reg: physical base address and size of the R-Car CAN register map. | 28 | - reg: physical base address and size of the R-Car CAN register map. |
26 | - interrupts: interrupt specifier for the sole interrupt. | 29 | - interrupts: interrupt specifier for the sole interrupt. |
27 | - clocks: phandles and clock specifiers for 3 CAN clock inputs. | 30 | - clocks: phandles and clock specifiers for 2 CAN clock inputs for RZ/G2 |
28 | - clock-names: 3 clock input name strings: "clkp1", "clkp2", "can_clk". | 31 | devices. |
32 | phandles and clock specifiers for 3 CAN clock inputs for every other | ||
33 | SoC. | ||
34 | - clock-names: 2 clock input name strings for RZ/G2: "clkp1", "can_clk". | ||
35 | 3 clock input name strings for every other SoC: "clkp1", "clkp2", | ||
36 | "can_clk". | ||
29 | - pinctrl-0: pin control group to be used for this controller. | 37 | - pinctrl-0: pin control group to be used for this controller. |
30 | - pinctrl-names: must be "default". | 38 | - pinctrl-names: must be "default". |
31 | 39 | ||
32 | Required properties for "renesas,can-r8a7795" and "renesas,can-r8a7796" | 40 | Required properties for R8A7795, R8A7796 and R8A77965: |
33 | compatible: | 41 | For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can |
34 | In R8A7795 and R8A7796 SoCs, "clkp2" can be CANFD clock. This is a div6 clock | 42 | be used by both CAN and CAN FD controller at the same time. It needs to be |
35 | and can be used by both CAN and CAN FD controller at the same time. It needs to | 43 | scaled to maximum frequency if any of these controllers use it. This is done |
36 | be scaled to maximum frequency if any of these controllers use it. This is done | ||
37 | using the below properties: | 44 | using the below properties: |
38 | 45 | ||
39 | - assigned-clocks: phandle of clkp2(CANFD) clock. | 46 | - assigned-clocks: phandle of clkp2(CANFD) clock. |
@@ -42,8 +49,9 @@ using the below properties: | |||
42 | Optional properties: | 49 | Optional properties: |
43 | - renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are: | 50 | - renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are: |
44 | <0x0> (default) : Peripheral clock (clkp1) | 51 | <0x0> (default) : Peripheral clock (clkp1) |
45 | <0x1> : Peripheral clock (clkp2) | 52 | <0x1> : Peripheral clock (clkp2) (not supported by |
46 | <0x3> : Externally input clock | 53 | RZ/G2 devices) |
54 | <0x3> : External input clock | ||
47 | 55 | ||
48 | Example | 56 | Example |
49 | ------- | 57 | ------- |
diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt index 3ceeb8de1196..35694c0c376b 100644 --- a/Documentation/devicetree/bindings/net/dsa/dsa.txt +++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt | |||
@@ -7,7 +7,7 @@ limitations. | |||
7 | Current Binding | 7 | Current Binding |
8 | --------------- | 8 | --------------- |
9 | 9 | ||
10 | Switches are true Linux devices and can be probes by any means. Once | 10 | Switches are true Linux devices and can be probed by any means. Once |
11 | probed, they register to the DSA framework, passing a node | 11 | probed, they register to the DSA framework, passing a node |
12 | pointer. This node is expected to fulfil the following binding, and | 12 | pointer. This node is expected to fulfil the following binding, and |
13 | may contain additional properties as required by the device it is | 13 | may contain additional properties as required by the device it is |
diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index cef220c176a4..a8c0873beb95 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst | |||
@@ -190,16 +190,7 @@ A few EV_REL codes have special meanings: | |||
190 | * REL_WHEEL, REL_HWHEEL: | 190 | * REL_WHEEL, REL_HWHEEL: |
191 | 191 | ||
192 | - These codes are used for vertical and horizontal scroll wheels, | 192 | - These codes are used for vertical and horizontal scroll wheels, |
193 | respectively. The value is the number of "notches" moved on the wheel, the | 193 | respectively. |
194 | physical size of which varies by device. For high-resolution wheels (which | ||
195 | report multiple events for each notch of movement, or do not have notches) | ||
196 | this may be an approximation based on the high-resolution scroll events. | ||
197 | |||
198 | * REL_WHEEL_HI_RES: | ||
199 | |||
200 | - If a vertical scroll wheel supports high-resolution scrolling, this code | ||
201 | will be emitted in addition to REL_WHEEL. The value is the (approximate) | ||
202 | distance travelled by the user's finger, in microns. | ||
203 | 194 | ||
204 | EV_ABS | 195 | EV_ABS |
205 | ------ | 196 | ------ |
diff --git a/Documentation/media/uapi/v4l/dev-meta.rst b/Documentation/media/uapi/v4l/dev-meta.rst index f7ac8d0d3af1..b65dc078abeb 100644 --- a/Documentation/media/uapi/v4l/dev-meta.rst +++ b/Documentation/media/uapi/v4l/dev-meta.rst | |||
@@ -40,7 +40,7 @@ To use the :ref:`format` ioctls applications set the ``type`` field of the | |||
40 | the desired operation. Both drivers and applications must set the remainder of | 40 | the desired operation. Both drivers and applications must set the remainder of |
41 | the :c:type:`v4l2_format` structure to 0. | 41 | the :c:type:`v4l2_format` structure to 0. |
42 | 42 | ||
43 | .. _v4l2-meta-format: | 43 | .. c:type:: v4l2_meta_format |
44 | 44 | ||
45 | .. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}| | 45 | .. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}| |
46 | 46 | ||
diff --git a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst index 3ead350e099f..9ea494a8faca 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst | |||
@@ -133,6 +133,11 @@ The format as returned by :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` must be identical | |||
133 | - Definition of a data format, see :ref:`pixfmt`, used by SDR | 133 | - Definition of a data format, see :ref:`pixfmt`, used by SDR |
134 | capture and output devices. | 134 | capture and output devices. |
135 | * - | 135 | * - |
136 | - struct :c:type:`v4l2_meta_format` | ||
137 | - ``meta`` | ||
138 | - Definition of a metadata format, see :ref:`meta-formats`, used by | ||
139 | metadata capture devices. | ||
140 | * - | ||
136 | - __u8 | 141 | - __u8 |
137 | - ``raw_data``\ [200] | 142 | - ``raw_data``\ [200] |
138 | - Place holder for future extensions. | 143 | - Place holder for future extensions. |
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt index 605e00cdd6be..89f1302d593a 100644 --- a/Documentation/networking/rxrpc.txt +++ b/Documentation/networking/rxrpc.txt | |||
@@ -1056,18 +1056,23 @@ The kernel interface functions are as follows: | |||
1056 | 1056 | ||
1057 | u32 rxrpc_kernel_check_life(struct socket *sock, | 1057 | u32 rxrpc_kernel_check_life(struct socket *sock, |
1058 | struct rxrpc_call *call); | 1058 | struct rxrpc_call *call); |
1059 | void rxrpc_kernel_probe_life(struct socket *sock, | ||
1060 | struct rxrpc_call *call); | ||
1059 | 1061 | ||
1060 | This returns a number that is updated when ACKs are received from the peer | 1062 | The first function returns a number that is updated when ACKs are received |
1061 | (notably including PING RESPONSE ACKs which we can elicit by sending PING | 1063 | from the peer (notably including PING RESPONSE ACKs which we can elicit by |
1062 | ACKs to see if the call still exists on the server). The caller should | 1064 | sending PING ACKs to see if the call still exists on the server). The |
1063 | compare the numbers of two calls to see if the call is still alive after | 1065 | caller should compare the numbers of two calls to see if the call is still |
1064 | waiting for a suitable interval. | 1066 | alive after waiting for a suitable interval. |
1065 | 1067 | ||
1066 | This allows the caller to work out if the server is still contactable and | 1068 | This allows the caller to work out if the server is still contactable and |
1067 | if the call is still alive on the server whilst waiting for the server to | 1069 | if the call is still alive on the server whilst waiting for the server to |
1068 | process a client operation. | 1070 | process a client operation. |
1069 | 1071 | ||
1070 | This function may transmit a PING ACK. | 1072 | The second function causes a ping ACK to be transmitted to try to provoke |
1073 | the peer into responding, which would then cause the value returned by the | ||
1074 | first function to change. Note that this must be called in TASK_RUNNING | ||
1075 | state. | ||
1071 | 1076 | ||
1072 | (*) Get reply timestamp. | 1077 | (*) Get reply timestamp. |
1073 | 1078 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 1026150ae90f..254b7b267731 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -180,6 +180,7 @@ F: drivers/net/hamradio/6pack.c | |||
180 | 180 | ||
181 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER | 181 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER |
182 | M: Realtek linux nic maintainers <nic_swsd@realtek.com> | 182 | M: Realtek linux nic maintainers <nic_swsd@realtek.com> |
183 | M: Heiner Kallweit <hkallweit1@gmail.com> | ||
183 | L: netdev@vger.kernel.org | 184 | L: netdev@vger.kernel.org |
184 | S: Maintained | 185 | S: Maintained |
185 | F: drivers/net/ethernet/realtek/r8169.c | 186 | F: drivers/net/ethernet/realtek/r8169.c |
@@ -717,7 +718,7 @@ F: include/linux/mfd/altera-a10sr.h | |||
717 | F: include/dt-bindings/reset/altr,rst-mgr-a10sr.h | 718 | F: include/dt-bindings/reset/altr,rst-mgr-a10sr.h |
718 | 719 | ||
719 | ALTERA TRIPLE SPEED ETHERNET DRIVER | 720 | ALTERA TRIPLE SPEED ETHERNET DRIVER |
720 | M: Vince Bridgers <vbridger@opensource.altera.com> | 721 | M: Thor Thayer <thor.thayer@linux.intel.com> |
721 | L: netdev@vger.kernel.org | 722 | L: netdev@vger.kernel.org |
722 | L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) | 723 | L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) |
723 | S: Maintained | 724 | S: Maintained |
@@ -3276,6 +3277,12 @@ F: include/uapi/linux/caif/ | |||
3276 | F: include/net/caif/ | 3277 | F: include/net/caif/ |
3277 | F: net/caif/ | 3278 | F: net/caif/ |
3278 | 3279 | ||
3280 | CAKE QDISC | ||
3281 | M: Toke Høiland-Jørgensen <toke@toke.dk> | ||
3282 | L: cake@lists.bufferbloat.net (moderated for non-subscribers) | ||
3283 | S: Maintained | ||
3284 | F: net/sched/sch_cake.c | ||
3285 | |||
3279 | CALGARY x86-64 IOMMU | 3286 | CALGARY x86-64 IOMMU |
3280 | M: Muli Ben-Yehuda <mulix@mulix.org> | 3287 | M: Muli Ben-Yehuda <mulix@mulix.org> |
3281 | M: Jon Mason <jdmason@kudzu.us> | 3288 | M: Jon Mason <jdmason@kudzu.us> |
@@ -5541,6 +5548,7 @@ F: net/bridge/ | |||
5541 | ETHERNET PHY LIBRARY | 5548 | ETHERNET PHY LIBRARY |
5542 | M: Andrew Lunn <andrew@lunn.ch> | 5549 | M: Andrew Lunn <andrew@lunn.ch> |
5543 | M: Florian Fainelli <f.fainelli@gmail.com> | 5550 | M: Florian Fainelli <f.fainelli@gmail.com> |
5551 | M: Heiner Kallweit <hkallweit1@gmail.com> | ||
5544 | L: netdev@vger.kernel.org | 5552 | L: netdev@vger.kernel.org |
5545 | S: Maintained | 5553 | S: Maintained |
5546 | F: Documentation/ABI/testing/sysfs-bus-mdio | 5554 | F: Documentation/ABI/testing/sysfs-bus-mdio |
@@ -6312,6 +6320,7 @@ F: tools/testing/selftests/gpio/ | |||
6312 | 6320 | ||
6313 | GPIO SUBSYSTEM | 6321 | GPIO SUBSYSTEM |
6314 | M: Linus Walleij <linus.walleij@linaro.org> | 6322 | M: Linus Walleij <linus.walleij@linaro.org> |
6323 | M: Bartosz Golaszewski <bgolaszewski@baylibre.com> | ||
6315 | L: linux-gpio@vger.kernel.org | 6324 | L: linux-gpio@vger.kernel.org |
6316 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git | 6325 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git |
6317 | S: Maintained | 6326 | S: Maintained |
@@ -7449,6 +7458,20 @@ S: Maintained | |||
7449 | F: Documentation/fb/intelfb.txt | 7458 | F: Documentation/fb/intelfb.txt |
7450 | F: drivers/video/fbdev/intelfb/ | 7459 | F: drivers/video/fbdev/intelfb/ |
7451 | 7460 | ||
7461 | INTEL GPIO DRIVERS | ||
7462 | M: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
7463 | L: linux-gpio@vger.kernel.org | ||
7464 | S: Maintained | ||
7465 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git | ||
7466 | F: drivers/gpio/gpio-ich.c | ||
7467 | F: drivers/gpio/gpio-intel-mid.c | ||
7468 | F: drivers/gpio/gpio-lynxpoint.c | ||
7469 | F: drivers/gpio/gpio-merrifield.c | ||
7470 | F: drivers/gpio/gpio-ml-ioh.c | ||
7471 | F: drivers/gpio/gpio-pch.c | ||
7472 | F: drivers/gpio/gpio-sch.c | ||
7473 | F: drivers/gpio/gpio-sodaville.c | ||
7474 | |||
7452 | INTEL GVT-g DRIVERS (Intel GPU Virtualization) | 7475 | INTEL GVT-g DRIVERS (Intel GPU Virtualization) |
7453 | M: Zhenyu Wang <zhenyuw@linux.intel.com> | 7476 | M: Zhenyu Wang <zhenyuw@linux.intel.com> |
7454 | M: Zhi Wang <zhi.a.wang@intel.com> | 7477 | M: Zhi Wang <zhi.a.wang@intel.com> |
@@ -7459,12 +7482,6 @@ T: git https://github.com/intel/gvt-linux.git | |||
7459 | S: Supported | 7482 | S: Supported |
7460 | F: drivers/gpu/drm/i915/gvt/ | 7483 | F: drivers/gpu/drm/i915/gvt/ |
7461 | 7484 | ||
7462 | INTEL PMIC GPIO DRIVER | ||
7463 | R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
7464 | S: Maintained | ||
7465 | F: drivers/gpio/gpio-*cove.c | ||
7466 | F: drivers/gpio/gpio-msic.c | ||
7467 | |||
7468 | INTEL HID EVENT DRIVER | 7485 | INTEL HID EVENT DRIVER |
7469 | M: Alex Hung <alex.hung@canonical.com> | 7486 | M: Alex Hung <alex.hung@canonical.com> |
7470 | L: platform-driver-x86@vger.kernel.org | 7487 | L: platform-driver-x86@vger.kernel.org |
@@ -7552,12 +7569,6 @@ W: https://01.org/linux-acpi | |||
7552 | S: Supported | 7569 | S: Supported |
7553 | F: drivers/platform/x86/intel_menlow.c | 7570 | F: drivers/platform/x86/intel_menlow.c |
7554 | 7571 | ||
7555 | INTEL MERRIFIELD GPIO DRIVER | ||
7556 | M: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
7557 | L: linux-gpio@vger.kernel.org | ||
7558 | S: Maintained | ||
7559 | F: drivers/gpio/gpio-merrifield.c | ||
7560 | |||
7561 | INTEL MIC DRIVERS (mic) | 7572 | INTEL MIC DRIVERS (mic) |
7562 | M: Sudeep Dutt <sudeep.dutt@intel.com> | 7573 | M: Sudeep Dutt <sudeep.dutt@intel.com> |
7563 | M: Ashutosh Dixit <ashutosh.dixit@intel.com> | 7574 | M: Ashutosh Dixit <ashutosh.dixit@intel.com> |
@@ -7590,6 +7601,13 @@ F: drivers/platform/x86/intel_punit_ipc.c | |||
7590 | F: arch/x86/include/asm/intel_pmc_ipc.h | 7601 | F: arch/x86/include/asm/intel_pmc_ipc.h |
7591 | F: arch/x86/include/asm/intel_punit_ipc.h | 7602 | F: arch/x86/include/asm/intel_punit_ipc.h |
7592 | 7603 | ||
7604 | INTEL PMIC GPIO DRIVERS | ||
7605 | M: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
7606 | S: Maintained | ||
7607 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git | ||
7608 | F: drivers/gpio/gpio-*cove.c | ||
7609 | F: drivers/gpio/gpio-msic.c | ||
7610 | |||
7593 | INTEL MULTIFUNCTION PMIC DEVICE DRIVERS | 7611 | INTEL MULTIFUNCTION PMIC DEVICE DRIVERS |
7594 | R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 7612 | R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
7595 | S: Maintained | 7613 | S: Maintained |
@@ -13991,11 +14009,10 @@ F: drivers/tty/serial/sunzilog.h | |||
13991 | F: drivers/tty/vcc.c | 14009 | F: drivers/tty/vcc.c |
13992 | 14010 | ||
13993 | SPARSE CHECKER | 14011 | SPARSE CHECKER |
13994 | M: "Christopher Li" <sparse@chrisli.org> | 14012 | M: "Luc Van Oostenryck" <luc.vanoostenryck@gmail.com> |
13995 | L: linux-sparse@vger.kernel.org | 14013 | L: linux-sparse@vger.kernel.org |
13996 | W: https://sparse.wiki.kernel.org/ | 14014 | W: https://sparse.wiki.kernel.org/ |
13997 | T: git git://git.kernel.org/pub/scm/devel/sparse/sparse.git | 14015 | T: git git://git.kernel.org/pub/scm/devel/sparse/sparse.git |
13998 | T: git git://git.kernel.org/pub/scm/devel/sparse/chrisl/sparse.git | ||
13999 | S: Maintained | 14016 | S: Maintained |
14000 | F: include/linux/compiler.h | 14017 | F: include/linux/compiler.h |
14001 | 14018 | ||
@@ -14092,6 +14109,7 @@ F: Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt | |||
14092 | 14109 | ||
14093 | STABLE BRANCH | 14110 | STABLE BRANCH |
14094 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 14111 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
14112 | M: Sasha Levin <sashal@kernel.org> | ||
14095 | L: stable@vger.kernel.org | 14113 | L: stable@vger.kernel.org |
14096 | S: Supported | 14114 | S: Supported |
14097 | F: Documentation/process/stable-kernel-rules.rst | 14115 | F: Documentation/process/stable-kernel-rules.rst |
@@ -2,8 +2,8 @@ | |||
2 | VERSION = 4 | 2 | VERSION = 4 |
3 | PATCHLEVEL = 20 | 3 | PATCHLEVEL = 20 |
4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
5 | EXTRAVERSION = -rc3 | 5 | EXTRAVERSION = -rc4 |
6 | NAME = "People's Front" | 6 | NAME = Shy Crocodile |
7 | 7 | ||
8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
9 | # To see a list of typical targets execute "make help" | 9 | # To see a list of typical targets execute "make help" |
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 0c909c4a932f..842fb9572661 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h | |||
@@ -468,7 +468,7 @@ | |||
468 | SCTLR_ELx_SA | SCTLR_ELx_I | SCTLR_ELx_WXN | \ | 468 | SCTLR_ELx_SA | SCTLR_ELx_I | SCTLR_ELx_WXN | \ |
469 | SCTLR_ELx_DSSBS | ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0) | 469 | SCTLR_ELx_DSSBS | ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0) |
470 | 470 | ||
471 | #if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffff | 471 | #if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffffUL |
472 | #error "Inconsistent SCTLR_EL2 set/clear bits" | 472 | #error "Inconsistent SCTLR_EL2 set/clear bits" |
473 | #endif | 473 | #endif |
474 | 474 | ||
@@ -509,7 +509,7 @@ | |||
509 | SCTLR_EL1_UMA | SCTLR_ELx_WXN | ENDIAN_CLEAR_EL1 |\ | 509 | SCTLR_EL1_UMA | SCTLR_ELx_WXN | ENDIAN_CLEAR_EL1 |\ |
510 | SCTLR_ELx_DSSBS | SCTLR_EL1_NTWI | SCTLR_EL1_RES0) | 510 | SCTLR_ELx_DSSBS | SCTLR_EL1_NTWI | SCTLR_EL1_RES0) |
511 | 511 | ||
512 | #if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffff | 512 | #if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffffUL |
513 | #error "Inconsistent SCTLR_EL1 set/clear bits" | 513 | #error "Inconsistent SCTLR_EL1 set/clear bits" |
514 | #endif | 514 | #endif |
515 | 515 | ||
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index af50064dea51..aec5ecb85737 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c | |||
@@ -1333,7 +1333,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { | |||
1333 | .cpu_enable = cpu_enable_hw_dbm, | 1333 | .cpu_enable = cpu_enable_hw_dbm, |
1334 | }, | 1334 | }, |
1335 | #endif | 1335 | #endif |
1336 | #ifdef CONFIG_ARM64_SSBD | ||
1337 | { | 1336 | { |
1338 | .desc = "CRC32 instructions", | 1337 | .desc = "CRC32 instructions", |
1339 | .capability = ARM64_HAS_CRC32, | 1338 | .capability = ARM64_HAS_CRC32, |
@@ -1343,6 +1342,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { | |||
1343 | .field_pos = ID_AA64ISAR0_CRC32_SHIFT, | 1342 | .field_pos = ID_AA64ISAR0_CRC32_SHIFT, |
1344 | .min_field_value = 1, | 1343 | .min_field_value = 1, |
1345 | }, | 1344 | }, |
1345 | #ifdef CONFIG_ARM64_SSBD | ||
1346 | { | 1346 | { |
1347 | .desc = "Speculative Store Bypassing Safe (SSBS)", | 1347 | .desc = "Speculative Store Bypassing Safe (SSBS)", |
1348 | .capability = ARM64_SSBS, | 1348 | .capability = ARM64_SSBS, |
diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index 490b12af103c..c52d0efacd14 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig | |||
@@ -140,6 +140,7 @@ CONFIG_RTC_CLASS=y | |||
140 | CONFIG_RTC_DRV_DS1307=y | 140 | CONFIG_RTC_DRV_DS1307=y |
141 | CONFIG_STAGING=y | 141 | CONFIG_STAGING=y |
142 | CONFIG_OCTEON_ETHERNET=y | 142 | CONFIG_OCTEON_ETHERNET=y |
143 | CONFIG_OCTEON_USB=y | ||
143 | # CONFIG_IOMMU_SUPPORT is not set | 144 | # CONFIG_IOMMU_SUPPORT is not set |
144 | CONFIG_RAS=y | 145 | CONFIG_RAS=y |
145 | CONFIG_EXT4_FS=y | 146 | CONFIG_EXT4_FS=y |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index ea09ed6a80a9..8c6c48ed786a 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -794,6 +794,7 @@ static void __init arch_mem_init(char **cmdline_p) | |||
794 | 794 | ||
795 | /* call board setup routine */ | 795 | /* call board setup routine */ |
796 | plat_mem_setup(); | 796 | plat_mem_setup(); |
797 | memblock_set_bottom_up(true); | ||
797 | 798 | ||
798 | /* | 799 | /* |
799 | * Make sure all kernel memory is in the maps. The "UP" and | 800 | * Make sure all kernel memory is in the maps. The "UP" and |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 0f852e1b5891..15e103c6d799 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -2260,10 +2260,8 @@ void __init trap_init(void) | |||
2260 | unsigned long size = 0x200 + VECTORSPACING*64; | 2260 | unsigned long size = 0x200 + VECTORSPACING*64; |
2261 | phys_addr_t ebase_pa; | 2261 | phys_addr_t ebase_pa; |
2262 | 2262 | ||
2263 | memblock_set_bottom_up(true); | ||
2264 | ebase = (unsigned long) | 2263 | ebase = (unsigned long) |
2265 | memblock_alloc_from(size, 1 << fls(size), 0); | 2264 | memblock_alloc_from(size, 1 << fls(size), 0); |
2266 | memblock_set_bottom_up(false); | ||
2267 | 2265 | ||
2268 | /* | 2266 | /* |
2269 | * Try to ensure ebase resides in KSeg0 if possible. | 2267 | * Try to ensure ebase resides in KSeg0 if possible. |
@@ -2307,6 +2305,7 @@ void __init trap_init(void) | |||
2307 | if (board_ebase_setup) | 2305 | if (board_ebase_setup) |
2308 | board_ebase_setup(); | 2306 | board_ebase_setup(); |
2309 | per_cpu_trap_init(true); | 2307 | per_cpu_trap_init(true); |
2308 | memblock_set_bottom_up(false); | ||
2310 | 2309 | ||
2311 | /* | 2310 | /* |
2312 | * Copy the generic exception handlers to their final destination. | 2311 | * Copy the generic exception handlers to their final destination. |
diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c index 622761878cd1..60bf0a1cb757 100644 --- a/arch/mips/loongson64/loongson-3/numa.c +++ b/arch/mips/loongson64/loongson-3/numa.c | |||
@@ -231,6 +231,8 @@ static __init void prom_meminit(void) | |||
231 | cpumask_clear(&__node_data[(node)]->cpumask); | 231 | cpumask_clear(&__node_data[(node)]->cpumask); |
232 | } | 232 | } |
233 | } | 233 | } |
234 | max_low_pfn = PHYS_PFN(memblock_end_of_DRAM()); | ||
235 | |||
234 | for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { | 236 | for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { |
235 | node = cpu / loongson_sysconf.cores_per_node; | 237 | node = cpu / loongson_sysconf.cores_per_node; |
236 | if (node >= num_online_nodes()) | 238 | if (node >= num_online_nodes()) |
@@ -248,19 +250,9 @@ static __init void prom_meminit(void) | |||
248 | 250 | ||
249 | void __init paging_init(void) | 251 | void __init paging_init(void) |
250 | { | 252 | { |
251 | unsigned node; | ||
252 | unsigned long zones_size[MAX_NR_ZONES] = {0, }; | 253 | unsigned long zones_size[MAX_NR_ZONES] = {0, }; |
253 | 254 | ||
254 | pagetable_init(); | 255 | pagetable_init(); |
255 | |||
256 | for_each_online_node(node) { | ||
257 | unsigned long start_pfn, end_pfn; | ||
258 | |||
259 | get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | ||
260 | |||
261 | if (end_pfn > max_low_pfn) | ||
262 | max_low_pfn = end_pfn; | ||
263 | } | ||
264 | #ifdef CONFIG_ZONE_DMA32 | 256 | #ifdef CONFIG_ZONE_DMA32 |
265 | zones_size[ZONE_DMA32] = MAX_DMA32_PFN; | 257 | zones_size[ZONE_DMA32] = MAX_DMA32_PFN; |
266 | #endif | 258 | #endif |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index d8b8444d6795..813d13f92957 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -435,6 +435,7 @@ void __init prom_meminit(void) | |||
435 | 435 | ||
436 | mlreset(); | 436 | mlreset(); |
437 | szmem(); | 437 | szmem(); |
438 | max_low_pfn = PHYS_PFN(memblock_end_of_DRAM()); | ||
438 | 439 | ||
439 | for (node = 0; node < MAX_COMPACT_NODES; node++) { | 440 | for (node = 0; node < MAX_COMPACT_NODES; node++) { |
440 | if (node_online(node)) { | 441 | if (node_online(node)) { |
@@ -455,18 +456,8 @@ extern void setup_zero_pages(void); | |||
455 | void __init paging_init(void) | 456 | void __init paging_init(void) |
456 | { | 457 | { |
457 | unsigned long zones_size[MAX_NR_ZONES] = {0, }; | 458 | unsigned long zones_size[MAX_NR_ZONES] = {0, }; |
458 | unsigned node; | ||
459 | 459 | ||
460 | pagetable_init(); | 460 | pagetable_init(); |
461 | |||
462 | for_each_online_node(node) { | ||
463 | unsigned long start_pfn, end_pfn; | ||
464 | |||
465 | get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | ||
466 | |||
467 | if (end_pfn > max_low_pfn) | ||
468 | max_low_pfn = end_pfn; | ||
469 | } | ||
470 | zones_size[ZONE_NORMAL] = max_low_pfn; | 461 | zones_size[ZONE_NORMAL] = max_low_pfn; |
471 | free_area_init_nodes(zones_size); | 462 | free_area_init_nodes(zones_size); |
472 | } | 463 | } |
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 4af153a182b0..4b594f2e4f7e 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile | |||
@@ -71,6 +71,10 @@ KBUILD_CFLAGS += $(call cc-option,-mstrict-align) | |||
71 | # arch specific predefines for sparse | 71 | # arch specific predefines for sparse |
72 | CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) | 72 | CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) |
73 | 73 | ||
74 | # Default target when executing plain make | ||
75 | boot := arch/riscv/boot | ||
76 | KBUILD_IMAGE := $(boot)/Image.gz | ||
77 | |||
74 | head-y := arch/riscv/kernel/head.o | 78 | head-y := arch/riscv/kernel/head.o |
75 | 79 | ||
76 | core-y += arch/riscv/kernel/ arch/riscv/mm/ | 80 | core-y += arch/riscv/kernel/ arch/riscv/mm/ |
@@ -81,4 +85,13 @@ PHONY += vdso_install | |||
81 | vdso_install: | 85 | vdso_install: |
82 | $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ | 86 | $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ |
83 | 87 | ||
84 | all: vmlinux | 88 | all: Image.gz |
89 | |||
90 | Image: vmlinux | ||
91 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
92 | |||
93 | Image.%: Image | ||
94 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
95 | |||
96 | zinstall install: | ||
97 | $(Q)$(MAKE) $(build)=$(boot) $@ | ||
diff --git a/arch/riscv/boot/.gitignore b/arch/riscv/boot/.gitignore new file mode 100644 index 000000000000..8dab0bb6ae66 --- /dev/null +++ b/arch/riscv/boot/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | Image | ||
2 | Image.gz | ||
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile new file mode 100644 index 000000000000..0990a9fdbe5d --- /dev/null +++ b/arch/riscv/boot/Makefile | |||
@@ -0,0 +1,33 @@ | |||
1 | # | ||
2 | # arch/riscv/boot/Makefile | ||
3 | # | ||
4 | # This file is included by the global makefile so that you can add your own | ||
5 | # architecture-specific flags and dependencies. | ||
6 | # | ||
7 | # This file is subject to the terms and conditions of the GNU General Public | ||
8 | # License. See the file "COPYING" in the main directory of this archive | ||
9 | # for more details. | ||
10 | # | ||
11 | # Copyright (C) 2018, Anup Patel. | ||
12 | # Author: Anup Patel <anup@brainfault.org> | ||
13 | # | ||
14 | # Based on the ia64 and arm64 boot/Makefile. | ||
15 | # | ||
16 | |||
17 | OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S | ||
18 | |||
19 | targets := Image | ||
20 | |||
21 | $(obj)/Image: vmlinux FORCE | ||
22 | $(call if_changed,objcopy) | ||
23 | |||
24 | $(obj)/Image.gz: $(obj)/Image FORCE | ||
25 | $(call if_changed,gzip) | ||
26 | |||
27 | install: | ||
28 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | ||
29 | $(obj)/Image System.map "$(INSTALL_PATH)" | ||
30 | |||
31 | zinstall: | ||
32 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | ||
33 | $(obj)/Image.gz System.map "$(INSTALL_PATH)" | ||
diff --git a/arch/riscv/boot/install.sh b/arch/riscv/boot/install.sh new file mode 100644 index 000000000000..18c39159c0ff --- /dev/null +++ b/arch/riscv/boot/install.sh | |||
@@ -0,0 +1,60 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # arch/riscv/boot/install.sh | ||
4 | # | ||
5 | # This file is subject to the terms and conditions of the GNU General Public | ||
6 | # License. See the file "COPYING" in the main directory of this archive | ||
7 | # for more details. | ||
8 | # | ||
9 | # Copyright (C) 1995 by Linus Torvalds | ||
10 | # | ||
11 | # Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin | ||
12 | # Adapted from code in arch/i386/boot/install.sh by Russell King | ||
13 | # | ||
14 | # "make install" script for the RISC-V Linux port | ||
15 | # | ||
16 | # Arguments: | ||
17 | # $1 - kernel version | ||
18 | # $2 - kernel image file | ||
19 | # $3 - kernel map file | ||
20 | # $4 - default install path (blank if root directory) | ||
21 | # | ||
22 | |||
23 | verify () { | ||
24 | if [ ! -f "$1" ]; then | ||
25 | echo "" 1>&2 | ||
26 | echo " *** Missing file: $1" 1>&2 | ||
27 | echo ' *** You need to run "make" before "make install".' 1>&2 | ||
28 | echo "" 1>&2 | ||
29 | exit 1 | ||
30 | fi | ||
31 | } | ||
32 | |||
33 | # Make sure the files actually exist | ||
34 | verify "$2" | ||
35 | verify "$3" | ||
36 | |||
37 | # User may have a custom install script | ||
38 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi | ||
39 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi | ||
40 | |||
41 | if [ "$(basename $2)" = "Image.gz" ]; then | ||
42 | # Compressed install | ||
43 | echo "Installing compressed kernel" | ||
44 | base=vmlinuz | ||
45 | else | ||
46 | # Normal install | ||
47 | echo "Installing normal kernel" | ||
48 | base=vmlinux | ||
49 | fi | ||
50 | |||
51 | if [ -f $4/$base-$1 ]; then | ||
52 | mv $4/$base-$1 $4/$base-$1.old | ||
53 | fi | ||
54 | cat $2 > $4/$base-$1 | ||
55 | |||
56 | # Install system map file | ||
57 | if [ -f $4/System.map-$1 ]; then | ||
58 | mv $4/System.map-$1 $4/System.map-$1.old | ||
59 | fi | ||
60 | cp $3 $4/System.map-$1 | ||
diff --git a/arch/riscv/include/asm/module.h b/arch/riscv/include/asm/module.h index 349df33808c4..cd2af4b013e3 100644 --- a/arch/riscv/include/asm/module.h +++ b/arch/riscv/include/asm/module.h | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #define MODULE_ARCH_VERMAGIC "riscv" | 9 | #define MODULE_ARCH_VERMAGIC "riscv" |
10 | 10 | ||
11 | struct module; | ||
11 | u64 module_emit_got_entry(struct module *mod, u64 val); | 12 | u64 module_emit_got_entry(struct module *mod, u64 val); |
12 | u64 module_emit_plt_entry(struct module *mod, u64 val); | 13 | u64 module_emit_plt_entry(struct module *mod, u64 val); |
13 | 14 | ||
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index 473cfc84e412..8c3e3e3c8be1 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h | |||
@@ -400,13 +400,13 @@ extern unsigned long __must_check __asm_copy_from_user(void *to, | |||
400 | static inline unsigned long | 400 | static inline unsigned long |
401 | raw_copy_from_user(void *to, const void __user *from, unsigned long n) | 401 | raw_copy_from_user(void *to, const void __user *from, unsigned long n) |
402 | { | 402 | { |
403 | return __asm_copy_to_user(to, from, n); | 403 | return __asm_copy_from_user(to, from, n); |
404 | } | 404 | } |
405 | 405 | ||
406 | static inline unsigned long | 406 | static inline unsigned long |
407 | raw_copy_to_user(void __user *to, const void *from, unsigned long n) | 407 | raw_copy_to_user(void __user *to, const void *from, unsigned long n) |
408 | { | 408 | { |
409 | return __asm_copy_from_user(to, from, n); | 409 | return __asm_copy_to_user(to, from, n); |
410 | } | 410 | } |
411 | 411 | ||
412 | extern long strncpy_from_user(char *dest, const char __user *src, long count); | 412 | extern long strncpy_from_user(char *dest, const char __user *src, long count); |
diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h index eff7aa9aa163..fef96f117b4d 100644 --- a/arch/riscv/include/asm/unistd.h +++ b/arch/riscv/include/asm/unistd.h | |||
@@ -13,10 +13,9 @@ | |||
13 | 13 | ||
14 | /* | 14 | /* |
15 | * There is explicitly no include guard here because this file is expected to | 15 | * There is explicitly no include guard here because this file is expected to |
16 | * be included multiple times. See uapi/asm/syscalls.h for more info. | 16 | * be included multiple times. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define __ARCH_WANT_NEW_STAT | ||
20 | #define __ARCH_WANT_SYS_CLONE | 19 | #define __ARCH_WANT_SYS_CLONE |
20 | |||
21 | #include <uapi/asm/unistd.h> | 21 | #include <uapi/asm/unistd.h> |
22 | #include <uapi/asm/syscalls.h> | ||
diff --git a/arch/riscv/include/uapi/asm/syscalls.h b/arch/riscv/include/uapi/asm/unistd.h index 206dc4b0f6ea..1f3bd3ebbb0d 100644 --- a/arch/riscv/include/uapi/asm/syscalls.h +++ b/arch/riscv/include/uapi/asm/unistd.h | |||
@@ -1,13 +1,25 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ |
2 | /* | 2 | /* |
3 | * Copyright (C) 2017-2018 SiFive | 3 | * Copyright (C) 2018 David Abdurachmanov <david.abdurachmanov@gmail.com> |
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
4 | */ | 16 | */ |
5 | 17 | ||
6 | /* | 18 | #ifdef __LP64__ |
7 | * There is explicitly no include guard here because this file is expected to | 19 | #define __ARCH_WANT_NEW_STAT |
8 | * be included multiple times in order to define the syscall macros via | 20 | #endif /* __LP64__ */ |
9 | * __SYSCALL. | 21 | |
10 | */ | 22 | #include <asm-generic/unistd.h> |
11 | 23 | ||
12 | /* | 24 | /* |
13 | * Allows the instruction cache to be flushed from userspace. Despite RISC-V | 25 | * Allows the instruction cache to be flushed from userspace. Despite RISC-V |
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 3a5a2ee31547..b4a7d4427fbb 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c | |||
@@ -64,7 +64,7 @@ int riscv_of_processor_hartid(struct device_node *node) | |||
64 | 64 | ||
65 | static void print_isa(struct seq_file *f, const char *orig_isa) | 65 | static void print_isa(struct seq_file *f, const char *orig_isa) |
66 | { | 66 | { |
67 | static const char *ext = "mafdc"; | 67 | static const char *ext = "mafdcsu"; |
68 | const char *isa = orig_isa; | 68 | const char *isa = orig_isa; |
69 | const char *e; | 69 | const char *e; |
70 | 70 | ||
@@ -88,11 +88,14 @@ static void print_isa(struct seq_file *f, const char *orig_isa) | |||
88 | /* | 88 | /* |
89 | * Check the rest of the ISA string for valid extensions, printing those | 89 | * Check the rest of the ISA string for valid extensions, printing those |
90 | * we find. RISC-V ISA strings define an order, so we only print the | 90 | * we find. RISC-V ISA strings define an order, so we only print the |
91 | * extension bits when they're in order. | 91 | * extension bits when they're in order. Hide the supervisor (S) |
92 | * extension from userspace as it's not accessible from there. | ||
92 | */ | 93 | */ |
93 | for (e = ext; *e != '\0'; ++e) { | 94 | for (e = ext; *e != '\0'; ++e) { |
94 | if (isa[0] == e[0]) { | 95 | if (isa[0] == e[0]) { |
95 | seq_write(f, isa, 1); | 96 | if (isa[0] != 's') |
97 | seq_write(f, isa, 1); | ||
98 | |||
96 | isa++; | 99 | isa++; |
97 | } | 100 | } |
98 | } | 101 | } |
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 711190d473d4..fe884cd69abd 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S | |||
@@ -44,6 +44,16 @@ ENTRY(_start) | |||
44 | amoadd.w a3, a2, (a3) | 44 | amoadd.w a3, a2, (a3) |
45 | bnez a3, .Lsecondary_start | 45 | bnez a3, .Lsecondary_start |
46 | 46 | ||
47 | /* Clear BSS for flat non-ELF images */ | ||
48 | la a3, __bss_start | ||
49 | la a4, __bss_stop | ||
50 | ble a4, a3, clear_bss_done | ||
51 | clear_bss: | ||
52 | REG_S zero, (a3) | ||
53 | add a3, a3, RISCV_SZPTR | ||
54 | blt a3, a4, clear_bss | ||
55 | clear_bss_done: | ||
56 | |||
47 | /* Save hart ID and DTB physical address */ | 57 | /* Save hart ID and DTB physical address */ |
48 | mv s0, a0 | 58 | mv s0, a0 |
49 | mv s1, a1 | 59 | mv s1, a1 |
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index ece84991609c..65df1dfdc303 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S | |||
@@ -74,7 +74,7 @@ SECTIONS | |||
74 | *(.sbss*) | 74 | *(.sbss*) |
75 | } | 75 | } |
76 | 76 | ||
77 | BSS_SECTION(0, 0, 0) | 77 | BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) |
78 | 78 | ||
79 | EXCEPTION_TABLE(0x10) | 79 | EXCEPTION_TABLE(0x10) |
80 | NOTES | 80 | NOTES |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index eaa60c94205a..1f32caa87686 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -30,6 +30,7 @@ static const struct acpi_device_id forbidden_id_list[] = { | |||
30 | {"PNP0200", 0}, /* AT DMA Controller */ | 30 | {"PNP0200", 0}, /* AT DMA Controller */ |
31 | {"ACPI0009", 0}, /* IOxAPIC */ | 31 | {"ACPI0009", 0}, /* IOxAPIC */ |
32 | {"ACPI000A", 0}, /* IOAPIC */ | 32 | {"ACPI000A", 0}, /* IOAPIC */ |
33 | {"SMB0001", 0}, /* ACPI SMBUS virtual device */ | ||
33 | {"", 0}, | 34 | {"", 0}, |
34 | }; | 35 | }; |
35 | 36 | ||
diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c index 3f0e2a14895a..22b53bf26817 100644 --- a/drivers/cpufreq/ti-cpufreq.c +++ b/drivers/cpufreq/ti-cpufreq.c | |||
@@ -201,19 +201,28 @@ static const struct of_device_id ti_cpufreq_of_match[] = { | |||
201 | {}, | 201 | {}, |
202 | }; | 202 | }; |
203 | 203 | ||
204 | static const struct of_device_id *ti_cpufreq_match_node(void) | ||
205 | { | ||
206 | struct device_node *np; | ||
207 | const struct of_device_id *match; | ||
208 | |||
209 | np = of_find_node_by_path("/"); | ||
210 | match = of_match_node(ti_cpufreq_of_match, np); | ||
211 | of_node_put(np); | ||
212 | |||
213 | return match; | ||
214 | } | ||
215 | |||
204 | static int ti_cpufreq_probe(struct platform_device *pdev) | 216 | static int ti_cpufreq_probe(struct platform_device *pdev) |
205 | { | 217 | { |
206 | u32 version[VERSION_COUNT]; | 218 | u32 version[VERSION_COUNT]; |
207 | struct device_node *np; | ||
208 | const struct of_device_id *match; | 219 | const struct of_device_id *match; |
209 | struct opp_table *ti_opp_table; | 220 | struct opp_table *ti_opp_table; |
210 | struct ti_cpufreq_data *opp_data; | 221 | struct ti_cpufreq_data *opp_data; |
211 | const char * const reg_names[] = {"vdd", "vbb"}; | 222 | const char * const reg_names[] = {"vdd", "vbb"}; |
212 | int ret; | 223 | int ret; |
213 | 224 | ||
214 | np = of_find_node_by_path("/"); | 225 | match = dev_get_platdata(&pdev->dev); |
215 | match = of_match_node(ti_cpufreq_of_match, np); | ||
216 | of_node_put(np); | ||
217 | if (!match) | 226 | if (!match) |
218 | return -ENODEV; | 227 | return -ENODEV; |
219 | 228 | ||
@@ -290,7 +299,14 @@ fail_put_node: | |||
290 | 299 | ||
291 | static int ti_cpufreq_init(void) | 300 | static int ti_cpufreq_init(void) |
292 | { | 301 | { |
293 | platform_device_register_simple("ti-cpufreq", -1, NULL, 0); | 302 | const struct of_device_id *match; |
303 | |||
304 | /* Check to ensure we are on a compatible platform */ | ||
305 | match = ti_cpufreq_match_node(); | ||
306 | if (match) | ||
307 | platform_device_register_data(NULL, "ti-cpufreq", -1, match, | ||
308 | sizeof(*match)); | ||
309 | |||
294 | return 0; | 310 | return 0; |
295 | } | 311 | } |
296 | module_init(ti_cpufreq_init); | 312 | module_init(ti_cpufreq_init); |
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 5b44ef226904..fc359ca4503d 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c | |||
@@ -184,6 +184,7 @@ static long udmabuf_create(const struct udmabuf_create_list *head, | |||
184 | exp_info.ops = &udmabuf_ops; | 184 | exp_info.ops = &udmabuf_ops; |
185 | exp_info.size = ubuf->pagecount << PAGE_SHIFT; | 185 | exp_info.size = ubuf->pagecount << PAGE_SHIFT; |
186 | exp_info.priv = ubuf; | 186 | exp_info.priv = ubuf; |
187 | exp_info.flags = O_RDWR; | ||
187 | 188 | ||
188 | buf = dma_buf_export(&exp_info); | 189 | buf = dma_buf_export(&exp_info); |
189 | if (IS_ERR(buf)) { | 190 | if (IS_ERR(buf)) { |
diff --git a/drivers/gnss/serial.c b/drivers/gnss/serial.c index b01ba4438501..31e891f00175 100644 --- a/drivers/gnss/serial.c +++ b/drivers/gnss/serial.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/pm.h> | 14 | #include <linux/pm.h> |
15 | #include <linux/pm_runtime.h> | 15 | #include <linux/pm_runtime.h> |
16 | #include <linux/sched.h> | ||
16 | #include <linux/serdev.h> | 17 | #include <linux/serdev.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | 19 | ||
@@ -63,7 +64,7 @@ static int gnss_serial_write_raw(struct gnss_device *gdev, | |||
63 | int ret; | 64 | int ret; |
64 | 65 | ||
65 | /* write is only buffered synchronously */ | 66 | /* write is only buffered synchronously */ |
66 | ret = serdev_device_write(serdev, buf, count, 0); | 67 | ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT); |
67 | if (ret < 0) | 68 | if (ret < 0) |
68 | return ret; | 69 | return ret; |
69 | 70 | ||
diff --git a/drivers/gnss/sirf.c b/drivers/gnss/sirf.c index 79cb98950013..71d014edd167 100644 --- a/drivers/gnss/sirf.c +++ b/drivers/gnss/sirf.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
17 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
18 | #include <linux/regulator/consumer.h> | 18 | #include <linux/regulator/consumer.h> |
19 | #include <linux/sched.h> | ||
19 | #include <linux/serdev.h> | 20 | #include <linux/serdev.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
@@ -83,7 +84,7 @@ static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf, | |||
83 | int ret; | 84 | int ret; |
84 | 85 | ||
85 | /* write is only buffered synchronously */ | 86 | /* write is only buffered synchronously */ |
86 | ret = serdev_device_write(serdev, buf, count, 0); | 87 | ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT); |
87 | if (ret < 0) | 88 | if (ret < 0) |
88 | return ret; | 89 | return ret; |
89 | 90 | ||
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 8269cffc2967..6a50f9f59c90 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c | |||
@@ -35,8 +35,8 @@ | |||
35 | #define gpio_mockup_err(...) pr_err(GPIO_MOCKUP_NAME ": " __VA_ARGS__) | 35 | #define gpio_mockup_err(...) pr_err(GPIO_MOCKUP_NAME ": " __VA_ARGS__) |
36 | 36 | ||
37 | enum { | 37 | enum { |
38 | GPIO_MOCKUP_DIR_OUT = 0, | 38 | GPIO_MOCKUP_DIR_IN = 0, |
39 | GPIO_MOCKUP_DIR_IN = 1, | 39 | GPIO_MOCKUP_DIR_OUT = 1, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* | 42 | /* |
@@ -131,7 +131,7 @@ static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset) | |||
131 | { | 131 | { |
132 | struct gpio_mockup_chip *chip = gpiochip_get_data(gc); | 132 | struct gpio_mockup_chip *chip = gpiochip_get_data(gc); |
133 | 133 | ||
134 | return chip->lines[offset].dir; | 134 | return !chip->lines[offset].dir; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset) | 137 | static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset) |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index bfe4c5c9f41c..e9600b556f39 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -268,8 +268,8 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
268 | 268 | ||
269 | if (pxa_gpio_has_pinctrl()) { | 269 | if (pxa_gpio_has_pinctrl()) { |
270 | ret = pinctrl_gpio_direction_input(chip->base + offset); | 270 | ret = pinctrl_gpio_direction_input(chip->base + offset); |
271 | if (!ret) | 271 | if (ret) |
272 | return 0; | 272 | return ret; |
273 | } | 273 | } |
274 | 274 | ||
275 | spin_lock_irqsave(&gpio_lock, flags); | 275 | spin_lock_irqsave(&gpio_lock, flags); |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 230e41562462..a2cbb474901c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1295,7 +1295,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, | |||
1295 | gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); | 1295 | gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); |
1296 | if (!gdev->descs) { | 1296 | if (!gdev->descs) { |
1297 | status = -ENOMEM; | 1297 | status = -ENOMEM; |
1298 | goto err_free_gdev; | 1298 | goto err_free_ida; |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | if (chip->ngpio == 0) { | 1301 | if (chip->ngpio == 0) { |
@@ -1427,8 +1427,9 @@ err_free_label: | |||
1427 | kfree_const(gdev->label); | 1427 | kfree_const(gdev->label); |
1428 | err_free_descs: | 1428 | err_free_descs: |
1429 | kfree(gdev->descs); | 1429 | kfree(gdev->descs); |
1430 | err_free_gdev: | 1430 | err_free_ida: |
1431 | ida_simple_remove(&gpio_ida, gdev->id); | 1431 | ida_simple_remove(&gpio_ida, gdev->id); |
1432 | err_free_gdev: | ||
1432 | /* failures here can mean systems won't boot... */ | 1433 | /* failures here can mean systems won't boot... */ |
1433 | pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__, | 1434 | pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__, |
1434 | gdev->base, gdev->base + gdev->ngpio - 1, | 1435 | gdev->base, gdev->base + gdev->ngpio - 1, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 60f9a87e9c74..bcf1666fb31d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | |||
@@ -501,8 +501,11 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle) | |||
501 | { | 501 | { |
502 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 502 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
503 | 503 | ||
504 | amdgpu_dpm_switch_power_profile(adev, | 504 | if (adev->powerplay.pp_funcs && |
505 | PP_SMC_POWER_PROFILE_COMPUTE, !idle); | 505 | adev->powerplay.pp_funcs->switch_power_profile) |
506 | amdgpu_dpm_switch_power_profile(adev, | ||
507 | PP_SMC_POWER_PROFILE_COMPUTE, | ||
508 | !idle); | ||
506 | } | 509 | } |
507 | 510 | ||
508 | bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) | 511 | bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 6748cd7fc129..686a26de50f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
@@ -626,6 +626,13 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev) | |||
626 | "dither", | 626 | "dither", |
627 | amdgpu_dither_enum_list, sz); | 627 | amdgpu_dither_enum_list, sz); |
628 | 628 | ||
629 | if (amdgpu_device_has_dc_support(adev)) { | ||
630 | adev->mode_info.max_bpc_property = | ||
631 | drm_property_create_range(adev->ddev, 0, "max bpc", 8, 16); | ||
632 | if (!adev->mode_info.max_bpc_property) | ||
633 | return -ENOMEM; | ||
634 | } | ||
635 | |||
629 | return 0; | 636 | return 0; |
630 | } | 637 | } |
631 | 638 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 11723d8fffbd..0dc2c5c57015 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
@@ -338,6 +338,8 @@ struct amdgpu_mode_info { | |||
338 | struct drm_property *audio_property; | 338 | struct drm_property *audio_property; |
339 | /* FMT dithering */ | 339 | /* FMT dithering */ |
340 | struct drm_property *dither_property; | 340 | struct drm_property *dither_property; |
341 | /* maximum number of bits per channel for monitor color */ | ||
342 | struct drm_property *max_bpc_property; | ||
341 | /* hardcoded DFP edid from BIOS */ | 343 | /* hardcoded DFP edid from BIOS */ |
342 | struct edid *bios_hardcoded_edid; | 344 | struct edid *bios_hardcoded_edid; |
343 | int bios_hardcoded_edid_size; | 345 | int bios_hardcoded_edid_size; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 2821d1d846e4..9fc3296592fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | |||
@@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/tahiti_mc.bin"); | |||
46 | MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin"); | 46 | MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin"); |
47 | MODULE_FIRMWARE("amdgpu/verde_mc.bin"); | 47 | MODULE_FIRMWARE("amdgpu/verde_mc.bin"); |
48 | MODULE_FIRMWARE("amdgpu/oland_mc.bin"); | 48 | MODULE_FIRMWARE("amdgpu/oland_mc.bin"); |
49 | MODULE_FIRMWARE("amdgpu/hainan_mc.bin"); | ||
49 | MODULE_FIRMWARE("amdgpu/si58_mc.bin"); | 50 | MODULE_FIRMWARE("amdgpu/si58_mc.bin"); |
50 | 51 | ||
51 | #define MC_SEQ_MISC0__MT__MASK 0xf0000000 | 52 | #define MC_SEQ_MISC0__MT__MASK 0xf0000000 |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index bf5e6a413dee..4cc0dcb1a187 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c | |||
@@ -65,6 +65,13 @@ | |||
65 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba | 65 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba |
66 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 | 66 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 |
67 | 67 | ||
68 | /* for Vega20 register name change */ | ||
69 | #define mmHDP_MEM_POWER_CTRL 0x00d4 | ||
70 | #define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK 0x00000001L | ||
71 | #define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK 0x00000002L | ||
72 | #define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK 0x00010000L | ||
73 | #define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK 0x00020000L | ||
74 | #define mmHDP_MEM_POWER_CTRL_BASE_IDX 0 | ||
68 | /* | 75 | /* |
69 | * Indirect registers accessor | 76 | * Indirect registers accessor |
70 | */ | 77 | */ |
@@ -870,15 +877,33 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable | |||
870 | { | 877 | { |
871 | uint32_t def, data; | 878 | uint32_t def, data; |
872 | 879 | ||
873 | def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); | 880 | if (adev->asic_type == CHIP_VEGA20) { |
881 | def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL)); | ||
874 | 882 | ||
875 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) | 883 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) |
876 | data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; | 884 | data |= HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK | |
877 | else | 885 | HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK | |
878 | data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; | 886 | HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK | |
887 | HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK; | ||
888 | else | ||
889 | data &= ~(HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK | | ||
890 | HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK | | ||
891 | HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK | | ||
892 | HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK); | ||
879 | 893 | ||
880 | if (def != data) | 894 | if (def != data) |
881 | WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data); | 895 | WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL), data); |
896 | } else { | ||
897 | def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); | ||
898 | |||
899 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) | ||
900 | data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; | ||
901 | else | ||
902 | data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; | ||
903 | |||
904 | if (def != data) | ||
905 | WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data); | ||
906 | } | ||
882 | } | 907 | } |
883 | 908 | ||
884 | static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) | 909 | static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index aa43bb253ea2..d8d0b206a79c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
@@ -2422,8 +2422,15 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode, | |||
2422 | static enum dc_color_depth | 2422 | static enum dc_color_depth |
2423 | convert_color_depth_from_display_info(const struct drm_connector *connector) | 2423 | convert_color_depth_from_display_info(const struct drm_connector *connector) |
2424 | { | 2424 | { |
2425 | struct dm_connector_state *dm_conn_state = | ||
2426 | to_dm_connector_state(connector->state); | ||
2425 | uint32_t bpc = connector->display_info.bpc; | 2427 | uint32_t bpc = connector->display_info.bpc; |
2426 | 2428 | ||
2429 | /* TODO: Remove this when there's support for max_bpc in drm */ | ||
2430 | if (dm_conn_state && bpc > dm_conn_state->max_bpc) | ||
2431 | /* Round down to nearest even number. */ | ||
2432 | bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1); | ||
2433 | |||
2427 | switch (bpc) { | 2434 | switch (bpc) { |
2428 | case 0: | 2435 | case 0: |
2429 | /* | 2436 | /* |
@@ -3007,6 +3014,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector, | |||
3007 | } else if (property == adev->mode_info.underscan_property) { | 3014 | } else if (property == adev->mode_info.underscan_property) { |
3008 | dm_new_state->underscan_enable = val; | 3015 | dm_new_state->underscan_enable = val; |
3009 | ret = 0; | 3016 | ret = 0; |
3017 | } else if (property == adev->mode_info.max_bpc_property) { | ||
3018 | dm_new_state->max_bpc = val; | ||
3019 | ret = 0; | ||
3010 | } | 3020 | } |
3011 | 3021 | ||
3012 | return ret; | 3022 | return ret; |
@@ -3049,6 +3059,9 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector, | |||
3049 | } else if (property == adev->mode_info.underscan_property) { | 3059 | } else if (property == adev->mode_info.underscan_property) { |
3050 | *val = dm_state->underscan_enable; | 3060 | *val = dm_state->underscan_enable; |
3051 | ret = 0; | 3061 | ret = 0; |
3062 | } else if (property == adev->mode_info.max_bpc_property) { | ||
3063 | *val = dm_state->max_bpc; | ||
3064 | ret = 0; | ||
3052 | } | 3065 | } |
3053 | return ret; | 3066 | return ret; |
3054 | } | 3067 | } |
@@ -3859,6 +3872,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, | |||
3859 | drm_object_attach_property(&aconnector->base.base, | 3872 | drm_object_attach_property(&aconnector->base.base, |
3860 | adev->mode_info.underscan_vborder_property, | 3873 | adev->mode_info.underscan_vborder_property, |
3861 | 0); | 3874 | 0); |
3875 | drm_object_attach_property(&aconnector->base.base, | ||
3876 | adev->mode_info.max_bpc_property, | ||
3877 | 0); | ||
3862 | 3878 | ||
3863 | } | 3879 | } |
3864 | 3880 | ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index d6960644d714..607c3cdd7d0c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | |||
@@ -252,6 +252,7 @@ struct dm_connector_state { | |||
252 | enum amdgpu_rmx_type scaling; | 252 | enum amdgpu_rmx_type scaling; |
253 | uint8_t underscan_vborder; | 253 | uint8_t underscan_vborder; |
254 | uint8_t underscan_hborder; | 254 | uint8_t underscan_hborder; |
255 | uint8_t max_bpc; | ||
255 | bool underscan_enable; | 256 | bool underscan_enable; |
256 | bool freesync_enable; | 257 | bool freesync_enable; |
257 | bool freesync_capable; | 258 | bool freesync_capable; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index ed35ec0341e6..88f6b35ea6fe 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |||
@@ -4525,12 +4525,12 @@ static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr) | |||
4525 | struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); | 4525 | struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); |
4526 | struct smu7_single_dpm_table *golden_sclk_table = | 4526 | struct smu7_single_dpm_table *golden_sclk_table = |
4527 | &(data->golden_dpm_table.sclk_table); | 4527 | &(data->golden_dpm_table.sclk_table); |
4528 | int value; | 4528 | int value = sclk_table->dpm_levels[sclk_table->count - 1].value; |
4529 | int golden_value = golden_sclk_table->dpm_levels | ||
4530 | [golden_sclk_table->count - 1].value; | ||
4529 | 4531 | ||
4530 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | 4532 | value -= golden_value; |
4531 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | 4533 | value = DIV_ROUND_UP(value * 100, golden_value); |
4532 | 100 / | ||
4533 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
4534 | 4534 | ||
4535 | return value; | 4535 | return value; |
4536 | } | 4536 | } |
@@ -4567,12 +4567,12 @@ static int smu7_get_mclk_od(struct pp_hwmgr *hwmgr) | |||
4567 | struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); | 4567 | struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); |
4568 | struct smu7_single_dpm_table *golden_mclk_table = | 4568 | struct smu7_single_dpm_table *golden_mclk_table = |
4569 | &(data->golden_dpm_table.mclk_table); | 4569 | &(data->golden_dpm_table.mclk_table); |
4570 | int value; | 4570 | int value = mclk_table->dpm_levels[mclk_table->count - 1].value; |
4571 | int golden_value = golden_mclk_table->dpm_levels | ||
4572 | [golden_mclk_table->count - 1].value; | ||
4571 | 4573 | ||
4572 | value = (mclk_table->dpm_levels[mclk_table->count - 1].value - | 4574 | value -= golden_value; |
4573 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * | 4575 | value = DIV_ROUND_UP(value * 100, golden_value); |
4574 | 100 / | ||
4575 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
4576 | 4576 | ||
4577 | return value; | 4577 | return value; |
4578 | } | 4578 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 8c4db86bb4b7..e2bc6e0c229f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | |||
@@ -4522,15 +4522,13 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr) | |||
4522 | struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); | 4522 | struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); |
4523 | struct vega10_single_dpm_table *golden_sclk_table = | 4523 | struct vega10_single_dpm_table *golden_sclk_table = |
4524 | &(data->golden_dpm_table.gfx_table); | 4524 | &(data->golden_dpm_table.gfx_table); |
4525 | int value; | 4525 | int value = sclk_table->dpm_levels[sclk_table->count - 1].value; |
4526 | 4526 | int golden_value = golden_sclk_table->dpm_levels | |
4527 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | ||
4528 | golden_sclk_table->dpm_levels | ||
4529 | [golden_sclk_table->count - 1].value) * | ||
4530 | 100 / | ||
4531 | golden_sclk_table->dpm_levels | ||
4532 | [golden_sclk_table->count - 1].value; | 4527 | [golden_sclk_table->count - 1].value; |
4533 | 4528 | ||
4529 | value -= golden_value; | ||
4530 | value = DIV_ROUND_UP(value * 100, golden_value); | ||
4531 | |||
4534 | return value; | 4532 | return value; |
4535 | } | 4533 | } |
4536 | 4534 | ||
@@ -4575,16 +4573,13 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr) | |||
4575 | struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); | 4573 | struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); |
4576 | struct vega10_single_dpm_table *golden_mclk_table = | 4574 | struct vega10_single_dpm_table *golden_mclk_table = |
4577 | &(data->golden_dpm_table.mem_table); | 4575 | &(data->golden_dpm_table.mem_table); |
4578 | int value; | 4576 | int value = mclk_table->dpm_levels[mclk_table->count - 1].value; |
4579 | 4577 | int golden_value = golden_mclk_table->dpm_levels | |
4580 | value = (mclk_table->dpm_levels | ||
4581 | [mclk_table->count - 1].value - | ||
4582 | golden_mclk_table->dpm_levels | ||
4583 | [golden_mclk_table->count - 1].value) * | ||
4584 | 100 / | ||
4585 | golden_mclk_table->dpm_levels | ||
4586 | [golden_mclk_table->count - 1].value; | 4578 | [golden_mclk_table->count - 1].value; |
4587 | 4579 | ||
4580 | value -= golden_value; | ||
4581 | value = DIV_ROUND_UP(value * 100, golden_value); | ||
4582 | |||
4588 | return value; | 4583 | return value; |
4589 | } | 4584 | } |
4590 | 4585 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 74bc37308dc0..54364444ecd1 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | |||
@@ -2243,12 +2243,12 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr) | |||
2243 | struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); | 2243 | struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); |
2244 | struct vega12_single_dpm_table *golden_sclk_table = | 2244 | struct vega12_single_dpm_table *golden_sclk_table = |
2245 | &(data->golden_dpm_table.gfx_table); | 2245 | &(data->golden_dpm_table.gfx_table); |
2246 | int value; | 2246 | int value = sclk_table->dpm_levels[sclk_table->count - 1].value; |
2247 | int golden_value = golden_sclk_table->dpm_levels | ||
2248 | [golden_sclk_table->count - 1].value; | ||
2247 | 2249 | ||
2248 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | 2250 | value -= golden_value; |
2249 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | 2251 | value = DIV_ROUND_UP(value * 100, golden_value); |
2250 | 100 / | ||
2251 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
2252 | 2252 | ||
2253 | return value; | 2253 | return value; |
2254 | } | 2254 | } |
@@ -2264,16 +2264,13 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr) | |||
2264 | struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); | 2264 | struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); |
2265 | struct vega12_single_dpm_table *golden_mclk_table = | 2265 | struct vega12_single_dpm_table *golden_mclk_table = |
2266 | &(data->golden_dpm_table.mem_table); | 2266 | &(data->golden_dpm_table.mem_table); |
2267 | int value; | 2267 | int value = mclk_table->dpm_levels[mclk_table->count - 1].value; |
2268 | 2268 | int golden_value = golden_mclk_table->dpm_levels | |
2269 | value = (mclk_table->dpm_levels | ||
2270 | [mclk_table->count - 1].value - | ||
2271 | golden_mclk_table->dpm_levels | ||
2272 | [golden_mclk_table->count - 1].value) * | ||
2273 | 100 / | ||
2274 | golden_mclk_table->dpm_levels | ||
2275 | [golden_mclk_table->count - 1].value; | 2269 | [golden_mclk_table->count - 1].value; |
2276 | 2270 | ||
2271 | value -= golden_value; | ||
2272 | value = DIV_ROUND_UP(value * 100, golden_value); | ||
2273 | |||
2277 | return value; | 2274 | return value; |
2278 | } | 2275 | } |
2279 | 2276 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index f2daf00cc911..2679d1240fa1 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | |||
@@ -75,7 +75,17 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) | |||
75 | data->phy_clk_quad_eqn_b = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; | 75 | data->phy_clk_quad_eqn_b = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; |
76 | data->phy_clk_quad_eqn_c = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; | 76 | data->phy_clk_quad_eqn_c = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; |
77 | 77 | ||
78 | data->registry_data.disallowed_features = 0x0; | 78 | /* |
79 | * Disable the following features for now: | ||
80 | * GFXCLK DS | ||
81 | * SOCLK DS | ||
82 | * LCLK DS | ||
83 | * DCEFCLK DS | ||
84 | * FCLK DS | ||
85 | * MP1CLK DS | ||
86 | * MP0CLK DS | ||
87 | */ | ||
88 | data->registry_data.disallowed_features = 0xE0041C00; | ||
79 | data->registry_data.od_state_in_dc_support = 0; | 89 | data->registry_data.od_state_in_dc_support = 0; |
80 | data->registry_data.thermal_support = 1; | 90 | data->registry_data.thermal_support = 1; |
81 | data->registry_data.skip_baco_hardware = 0; | 91 | data->registry_data.skip_baco_hardware = 0; |
@@ -1313,12 +1323,13 @@ static int vega20_get_sclk_od( | |||
1313 | &(data->dpm_table.gfx_table); | 1323 | &(data->dpm_table.gfx_table); |
1314 | struct vega20_single_dpm_table *golden_sclk_table = | 1324 | struct vega20_single_dpm_table *golden_sclk_table = |
1315 | &(data->golden_dpm_table.gfx_table); | 1325 | &(data->golden_dpm_table.gfx_table); |
1316 | int value; | 1326 | int value = sclk_table->dpm_levels[sclk_table->count - 1].value; |
1327 | int golden_value = golden_sclk_table->dpm_levels | ||
1328 | [golden_sclk_table->count - 1].value; | ||
1317 | 1329 | ||
1318 | /* od percentage */ | 1330 | /* od percentage */ |
1319 | value = DIV_ROUND_UP((sclk_table->dpm_levels[sclk_table->count - 1].value - | 1331 | value -= golden_value; |
1320 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * 100, | 1332 | value = DIV_ROUND_UP(value * 100, golden_value); |
1321 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value); | ||
1322 | 1333 | ||
1323 | return value; | 1334 | return value; |
1324 | } | 1335 | } |
@@ -1358,12 +1369,13 @@ static int vega20_get_mclk_od( | |||
1358 | &(data->dpm_table.mem_table); | 1369 | &(data->dpm_table.mem_table); |
1359 | struct vega20_single_dpm_table *golden_mclk_table = | 1370 | struct vega20_single_dpm_table *golden_mclk_table = |
1360 | &(data->golden_dpm_table.mem_table); | 1371 | &(data->golden_dpm_table.mem_table); |
1361 | int value; | 1372 | int value = mclk_table->dpm_levels[mclk_table->count - 1].value; |
1373 | int golden_value = golden_mclk_table->dpm_levels | ||
1374 | [golden_mclk_table->count - 1].value; | ||
1362 | 1375 | ||
1363 | /* od percentage */ | 1376 | /* od percentage */ |
1364 | value = DIV_ROUND_UP((mclk_table->dpm_levels[mclk_table->count - 1].value - | 1377 | value -= golden_value; |
1365 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * 100, | 1378 | value = DIV_ROUND_UP(value * 100, golden_value); |
1366 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value); | ||
1367 | 1379 | ||
1368 | return value; | 1380 | return value; |
1369 | } | 1381 | } |
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 69dab82a3771..bf589c53b908 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c | |||
@@ -60,8 +60,29 @@ static const struct pci_device_id pciidlist[] = { | |||
60 | 60 | ||
61 | MODULE_DEVICE_TABLE(pci, pciidlist); | 61 | MODULE_DEVICE_TABLE(pci, pciidlist); |
62 | 62 | ||
63 | static void ast_kick_out_firmware_fb(struct pci_dev *pdev) | ||
64 | { | ||
65 | struct apertures_struct *ap; | ||
66 | bool primary = false; | ||
67 | |||
68 | ap = alloc_apertures(1); | ||
69 | if (!ap) | ||
70 | return; | ||
71 | |||
72 | ap->ranges[0].base = pci_resource_start(pdev, 0); | ||
73 | ap->ranges[0].size = pci_resource_len(pdev, 0); | ||
74 | |||
75 | #ifdef CONFIG_X86 | ||
76 | primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; | ||
77 | #endif | ||
78 | drm_fb_helper_remove_conflicting_framebuffers(ap, "astdrmfb", primary); | ||
79 | kfree(ap); | ||
80 | } | ||
81 | |||
63 | static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 82 | static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
64 | { | 83 | { |
84 | ast_kick_out_firmware_fb(pdev); | ||
85 | |||
65 | return drm_get_pci_dev(pdev, ent, &driver); | 86 | return drm_get_pci_dev(pdev, ent, &driver); |
66 | } | 87 | } |
67 | 88 | ||
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 5e77d456d9bb..7c6ac3cadb6b 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c | |||
@@ -568,6 +568,7 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc, | |||
568 | } | 568 | } |
569 | ast_bo_unreserve(bo); | 569 | ast_bo_unreserve(bo); |
570 | 570 | ||
571 | ast_set_offset_reg(crtc); | ||
571 | ast_set_start_address_crt1(crtc, (u32)gpu_addr); | 572 | ast_set_start_address_crt1(crtc, (u32)gpu_addr); |
572 | 573 | ||
573 | return 0; | 574 | return 0; |
@@ -1254,7 +1255,7 @@ static int ast_cursor_move(struct drm_crtc *crtc, | |||
1254 | ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07)); | 1255 | ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07)); |
1255 | 1256 | ||
1256 | /* dummy write to fire HWC */ | 1257 | /* dummy write to fire HWC */ |
1257 | ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xCB, 0xFF, 0x00); | 1258 | ast_show_cursor(crtc); |
1258 | 1259 | ||
1259 | return 0; | 1260 | return 0; |
1260 | } | 1261 | } |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 9a69ad7e9f3b..5e9ca6f96379 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -219,6 +219,9 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) | |||
219 | mutex_lock(&fb_helper->lock); | 219 | mutex_lock(&fb_helper->lock); |
220 | drm_connector_list_iter_begin(dev, &conn_iter); | 220 | drm_connector_list_iter_begin(dev, &conn_iter); |
221 | drm_for_each_connector_iter(connector, &conn_iter) { | 221 | drm_for_each_connector_iter(connector, &conn_iter) { |
222 | if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) | ||
223 | continue; | ||
224 | |||
222 | ret = __drm_fb_helper_add_one_connector(fb_helper, connector); | 225 | ret = __drm_fb_helper_add_one_connector(fb_helper, connector); |
223 | if (ret) | 226 | if (ret) |
224 | goto fail; | 227 | goto fail; |
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 127468785f74..1f94b9affe4b 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c | |||
@@ -214,6 +214,12 @@ static int vc4_atomic_commit(struct drm_device *dev, | |||
214 | return 0; | 214 | return 0; |
215 | } | 215 | } |
216 | 216 | ||
217 | /* We know for sure we don't want an async update here. Set | ||
218 | * state->legacy_cursor_update to false to prevent | ||
219 | * drm_atomic_helper_setup_commit() from auto-completing | ||
220 | * commit->flip_done. | ||
221 | */ | ||
222 | state->legacy_cursor_update = false; | ||
217 | ret = drm_atomic_helper_setup_commit(state, nonblock); | 223 | ret = drm_atomic_helper_setup_commit(state, nonblock); |
218 | if (ret) | 224 | if (ret) |
219 | return ret; | 225 | return ret; |
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 1728fb7d00ba..c3ded0ba0441 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c | |||
@@ -854,7 +854,7 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) | |||
854 | static void vc4_plane_atomic_async_update(struct drm_plane *plane, | 854 | static void vc4_plane_atomic_async_update(struct drm_plane *plane, |
855 | struct drm_plane_state *state) | 855 | struct drm_plane_state *state) |
856 | { | 856 | { |
857 | struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); | 857 | struct vc4_plane_state *vc4_state, *new_vc4_state; |
858 | 858 | ||
859 | if (plane->state->fb != state->fb) { | 859 | if (plane->state->fb != state->fb) { |
860 | vc4_plane_async_set_fb(plane, state->fb); | 860 | vc4_plane_async_set_fb(plane, state->fb); |
@@ -875,7 +875,18 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, | |||
875 | plane->state->src_y = state->src_y; | 875 | plane->state->src_y = state->src_y; |
876 | 876 | ||
877 | /* Update the display list based on the new crtc_x/y. */ | 877 | /* Update the display list based on the new crtc_x/y. */ |
878 | vc4_plane_atomic_check(plane, plane->state); | 878 | vc4_plane_atomic_check(plane, state); |
879 | |||
880 | new_vc4_state = to_vc4_plane_state(state); | ||
881 | vc4_state = to_vc4_plane_state(plane->state); | ||
882 | |||
883 | /* Update the current vc4_state pos0, pos2 and ptr0 dlist entries. */ | ||
884 | vc4_state->dlist[vc4_state->pos0_offset] = | ||
885 | new_vc4_state->dlist[vc4_state->pos0_offset]; | ||
886 | vc4_state->dlist[vc4_state->pos2_offset] = | ||
887 | new_vc4_state->dlist[vc4_state->pos2_offset]; | ||
888 | vc4_state->dlist[vc4_state->ptr0_offset] = | ||
889 | new_vc4_state->dlist[vc4_state->ptr0_offset]; | ||
879 | 890 | ||
880 | /* Note that we can't just call vc4_plane_write_dlist() | 891 | /* Note that we can't just call vc4_plane_write_dlist() |
881 | * because that would smash the context data that the HVS is | 892 | * because that would smash the context data that the HVS is |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c0d668944dbe..ed35c9a9a110 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -275,6 +275,9 @@ | |||
275 | 275 | ||
276 | #define USB_VENDOR_ID_CIDC 0x1677 | 276 | #define USB_VENDOR_ID_CIDC 0x1677 |
277 | 277 | ||
278 | #define I2C_VENDOR_ID_CIRQUE 0x0488 | ||
279 | #define I2C_PRODUCT_ID_CIRQUE_121F 0x121F | ||
280 | |||
278 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 | 281 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 |
279 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 | 282 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 |
280 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 | 283 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 |
@@ -707,6 +710,7 @@ | |||
707 | #define USB_VENDOR_ID_LG 0x1fd2 | 710 | #define USB_VENDOR_ID_LG 0x1fd2 |
708 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 | 711 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
709 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 | 712 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 |
713 | #define I2C_DEVICE_ID_LG_8001 0x8001 | ||
710 | 714 | ||
711 | #define USB_VENDOR_ID_LOGITECH 0x046d | 715 | #define USB_VENDOR_ID_LOGITECH 0x046d |
712 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e | 716 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
@@ -805,6 +809,7 @@ | |||
805 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 809 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
806 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da | 810 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da |
807 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd | 811 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd |
812 | #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb | ||
808 | 813 | ||
809 | #define USB_VENDOR_ID_MOJO 0x8282 | 814 | #define USB_VENDOR_ID_MOJO 0x8282 |
810 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 815 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
@@ -1043,6 +1048,7 @@ | |||
1043 | #define USB_VENDOR_ID_SYMBOL 0x05e0 | 1048 | #define USB_VENDOR_ID_SYMBOL 0x05e0 |
1044 | #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 | 1049 | #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 |
1045 | #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 | 1050 | #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 |
1051 | #define USB_DEVICE_ID_SYMBOL_SCANNER_3 0x1200 | ||
1046 | 1052 | ||
1047 | #define USB_VENDOR_ID_SYNAPTICS 0x06cb | 1053 | #define USB_VENDOR_ID_SYNAPTICS 0x06cb |
1048 | #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 | 1054 | #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 |
@@ -1204,6 +1210,8 @@ | |||
1204 | #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22 | 1210 | #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22 |
1205 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 | 1211 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 |
1206 | #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72 | 1212 | #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72 |
1213 | #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f | ||
1214 | #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22 0x4e22 | ||
1207 | 1215 | ||
1208 | 1216 | ||
1209 | #define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */ | 1217 | #define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */ |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a2f74e6adc70..d6fab5798487 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -325,6 +325,9 @@ static const struct hid_device_id hid_battery_quirks[] = { | |||
325 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, | 325 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, |
326 | USB_DEVICE_ID_ELECOM_BM084), | 326 | USB_DEVICE_ID_ELECOM_BM084), |
327 | HID_BATTERY_QUIRK_IGNORE }, | 327 | HID_BATTERY_QUIRK_IGNORE }, |
328 | { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, | ||
329 | USB_DEVICE_ID_SYMBOL_SCANNER_3), | ||
330 | HID_BATTERY_QUIRK_IGNORE }, | ||
328 | {} | 331 | {} |
329 | }; | 332 | }; |
330 | 333 | ||
@@ -1838,47 +1841,3 @@ void hidinput_disconnect(struct hid_device *hid) | |||
1838 | } | 1841 | } |
1839 | EXPORT_SYMBOL_GPL(hidinput_disconnect); | 1842 | EXPORT_SYMBOL_GPL(hidinput_disconnect); |
1840 | 1843 | ||
1841 | /** | ||
1842 | * hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll | ||
1843 | * events given a high-resolution wheel | ||
1844 | * movement. | ||
1845 | * @counter: a hid_scroll_counter struct describing the wheel. | ||
1846 | * @hi_res_value: the movement of the wheel, in the mouse's high-resolution | ||
1847 | * units. | ||
1848 | * | ||
1849 | * Given a high-resolution movement, this function converts the movement into | ||
1850 | * microns and emits high-resolution scroll events for the input device. It also | ||
1851 | * uses the multiplier from &struct hid_scroll_counter to emit low-resolution | ||
1852 | * scroll events when appropriate for backwards-compatibility with userspace | ||
1853 | * input libraries. | ||
1854 | */ | ||
1855 | void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter, | ||
1856 | int hi_res_value) | ||
1857 | { | ||
1858 | int low_res_value, remainder, multiplier; | ||
1859 | |||
1860 | input_report_rel(counter->dev, REL_WHEEL_HI_RES, | ||
1861 | hi_res_value * counter->microns_per_hi_res_unit); | ||
1862 | |||
1863 | /* | ||
1864 | * Update the low-res remainder with the high-res value, | ||
1865 | * but reset if the direction has changed. | ||
1866 | */ | ||
1867 | remainder = counter->remainder; | ||
1868 | if ((remainder ^ hi_res_value) < 0) | ||
1869 | remainder = 0; | ||
1870 | remainder += hi_res_value; | ||
1871 | |||
1872 | /* | ||
1873 | * Then just use the resolution multiplier to see if | ||
1874 | * we should send a low-res (aka regular wheel) event. | ||
1875 | */ | ||
1876 | multiplier = counter->resolution_multiplier; | ||
1877 | low_res_value = remainder / multiplier; | ||
1878 | remainder -= low_res_value * multiplier; | ||
1879 | counter->remainder = remainder; | ||
1880 | |||
1881 | if (low_res_value) | ||
1882 | input_report_rel(counter->dev, REL_WHEEL, low_res_value); | ||
1883 | } | ||
1884 | EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll); | ||
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index f01280898b24..19cc980eebce 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
@@ -64,14 +64,6 @@ MODULE_PARM_DESC(disable_tap_to_click, | |||
64 | #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) | 64 | #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) |
65 | #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) | 65 | #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) |
66 | #define HIDPP_QUIRK_UNIFYING BIT(25) | 66 | #define HIDPP_QUIRK_UNIFYING BIT(25) |
67 | #define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(26) | ||
68 | #define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27) | ||
69 | #define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28) | ||
70 | |||
71 | /* Convenience constant to check for any high-res support. */ | ||
72 | #define HIDPP_QUIRK_HI_RES_SCROLL (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \ | ||
73 | HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \ | ||
74 | HIDPP_QUIRK_HI_RES_SCROLL_X2121) | ||
75 | 67 | ||
76 | #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT | 68 | #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT |
77 | 69 | ||
@@ -157,7 +149,6 @@ struct hidpp_device { | |||
157 | unsigned long capabilities; | 149 | unsigned long capabilities; |
158 | 150 | ||
159 | struct hidpp_battery battery; | 151 | struct hidpp_battery battery; |
160 | struct hid_scroll_counter vertical_wheel_counter; | ||
161 | }; | 152 | }; |
162 | 153 | ||
163 | /* HID++ 1.0 error codes */ | 154 | /* HID++ 1.0 error codes */ |
@@ -409,53 +400,32 @@ static void hidpp_prefix_name(char **name, int name_length) | |||
409 | #define HIDPP_SET_LONG_REGISTER 0x82 | 400 | #define HIDPP_SET_LONG_REGISTER 0x82 |
410 | #define HIDPP_GET_LONG_REGISTER 0x83 | 401 | #define HIDPP_GET_LONG_REGISTER 0x83 |
411 | 402 | ||
412 | /** | 403 | #define HIDPP_REG_GENERAL 0x00 |
413 | * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register. | 404 | |
414 | * @hidpp_dev: the device to set the register on. | 405 | static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) |
415 | * @register_address: the address of the register to modify. | ||
416 | * @byte: the byte of the register to modify. Should be less than 3. | ||
417 | * Return: 0 if successful, otherwise a negative error code. | ||
418 | */ | ||
419 | static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev, | ||
420 | u8 register_address, u8 byte, u8 bit) | ||
421 | { | 406 | { |
422 | struct hidpp_report response; | 407 | struct hidpp_report response; |
423 | int ret; | 408 | int ret; |
424 | u8 params[3] = { 0 }; | 409 | u8 params[3] = { 0 }; |
425 | 410 | ||
426 | ret = hidpp_send_rap_command_sync(hidpp_dev, | 411 | ret = hidpp_send_rap_command_sync(hidpp_dev, |
427 | REPORT_ID_HIDPP_SHORT, | 412 | REPORT_ID_HIDPP_SHORT, |
428 | HIDPP_GET_REGISTER, | 413 | HIDPP_GET_REGISTER, |
429 | register_address, | 414 | HIDPP_REG_GENERAL, |
430 | NULL, 0, &response); | 415 | NULL, 0, &response); |
431 | if (ret) | 416 | if (ret) |
432 | return ret; | 417 | return ret; |
433 | 418 | ||
434 | memcpy(params, response.rap.params, 3); | 419 | memcpy(params, response.rap.params, 3); |
435 | 420 | ||
436 | params[byte] |= BIT(bit); | 421 | /* Set the battery bit */ |
422 | params[0] |= BIT(4); | ||
437 | 423 | ||
438 | return hidpp_send_rap_command_sync(hidpp_dev, | 424 | return hidpp_send_rap_command_sync(hidpp_dev, |
439 | REPORT_ID_HIDPP_SHORT, | 425 | REPORT_ID_HIDPP_SHORT, |
440 | HIDPP_SET_REGISTER, | 426 | HIDPP_SET_REGISTER, |
441 | register_address, | 427 | HIDPP_REG_GENERAL, |
442 | params, 3, &response); | 428 | params, 3, &response); |
443 | } | ||
444 | |||
445 | |||
446 | #define HIDPP_REG_GENERAL 0x00 | ||
447 | |||
448 | static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) | ||
449 | { | ||
450 | return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4); | ||
451 | } | ||
452 | |||
453 | #define HIDPP_REG_FEATURES 0x01 | ||
454 | |||
455 | /* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */ | ||
456 | static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev) | ||
457 | { | ||
458 | return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6); | ||
459 | } | 429 | } |
460 | 430 | ||
461 | #define HIDPP_REG_BATTERY_STATUS 0x07 | 431 | #define HIDPP_REG_BATTERY_STATUS 0x07 |
@@ -1167,100 +1137,6 @@ static int hidpp_battery_get_property(struct power_supply *psy, | |||
1167 | } | 1137 | } |
1168 | 1138 | ||
1169 | /* -------------------------------------------------------------------------- */ | 1139 | /* -------------------------------------------------------------------------- */ |
1170 | /* 0x2120: Hi-resolution scrolling */ | ||
1171 | /* -------------------------------------------------------------------------- */ | ||
1172 | |||
1173 | #define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120 | ||
1174 | |||
1175 | #define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10 | ||
1176 | |||
1177 | static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp, | ||
1178 | bool enabled, u8 *multiplier) | ||
1179 | { | ||
1180 | u8 feature_index; | ||
1181 | u8 feature_type; | ||
1182 | int ret; | ||
1183 | u8 params[1]; | ||
1184 | struct hidpp_report response; | ||
1185 | |||
1186 | ret = hidpp_root_get_feature(hidpp, | ||
1187 | HIDPP_PAGE_HI_RESOLUTION_SCROLLING, | ||
1188 | &feature_index, | ||
1189 | &feature_type); | ||
1190 | if (ret) | ||
1191 | return ret; | ||
1192 | |||
1193 | params[0] = enabled ? BIT(0) : 0; | ||
1194 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
1195 | CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE, | ||
1196 | params, sizeof(params), &response); | ||
1197 | if (ret) | ||
1198 | return ret; | ||
1199 | *multiplier = response.fap.params[1]; | ||
1200 | return 0; | ||
1201 | } | ||
1202 | |||
1203 | /* -------------------------------------------------------------------------- */ | ||
1204 | /* 0x2121: HiRes Wheel */ | ||
1205 | /* -------------------------------------------------------------------------- */ | ||
1206 | |||
1207 | #define HIDPP_PAGE_HIRES_WHEEL 0x2121 | ||
1208 | |||
1209 | #define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00 | ||
1210 | #define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20 | ||
1211 | |||
1212 | static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp, | ||
1213 | u8 *multiplier) | ||
1214 | { | ||
1215 | u8 feature_index; | ||
1216 | u8 feature_type; | ||
1217 | int ret; | ||
1218 | struct hidpp_report response; | ||
1219 | |||
1220 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL, | ||
1221 | &feature_index, &feature_type); | ||
1222 | if (ret) | ||
1223 | goto return_default; | ||
1224 | |||
1225 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
1226 | CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY, | ||
1227 | NULL, 0, &response); | ||
1228 | if (ret) | ||
1229 | goto return_default; | ||
1230 | |||
1231 | *multiplier = response.fap.params[0]; | ||
1232 | return 0; | ||
1233 | return_default: | ||
1234 | hid_warn(hidpp->hid_dev, | ||
1235 | "Couldn't get wheel multiplier (error %d), assuming %d.\n", | ||
1236 | ret, *multiplier); | ||
1237 | return ret; | ||
1238 | } | ||
1239 | |||
1240 | static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert, | ||
1241 | bool high_resolution, bool use_hidpp) | ||
1242 | { | ||
1243 | u8 feature_index; | ||
1244 | u8 feature_type; | ||
1245 | int ret; | ||
1246 | u8 params[1]; | ||
1247 | struct hidpp_report response; | ||
1248 | |||
1249 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL, | ||
1250 | &feature_index, &feature_type); | ||
1251 | if (ret) | ||
1252 | return ret; | ||
1253 | |||
1254 | params[0] = (invert ? BIT(2) : 0) | | ||
1255 | (high_resolution ? BIT(1) : 0) | | ||
1256 | (use_hidpp ? BIT(0) : 0); | ||
1257 | |||
1258 | return hidpp_send_fap_command_sync(hidpp, feature_index, | ||
1259 | CMD_HIRES_WHEEL_SET_WHEEL_MODE, | ||
1260 | params, sizeof(params), &response); | ||
1261 | } | ||
1262 | |||
1263 | /* -------------------------------------------------------------------------- */ | ||
1264 | /* 0x4301: Solar Keyboard */ | 1140 | /* 0x4301: Solar Keyboard */ |
1265 | /* -------------------------------------------------------------------------- */ | 1141 | /* -------------------------------------------------------------------------- */ |
1266 | 1142 | ||
@@ -2523,8 +2399,7 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size) | |||
2523 | input_report_rel(mydata->input, REL_Y, v); | 2399 | input_report_rel(mydata->input, REL_Y, v); |
2524 | 2400 | ||
2525 | v = hid_snto32(data[6], 8); | 2401 | v = hid_snto32(data[6], 8); |
2526 | hid_scroll_counter_handle_scroll( | 2402 | input_report_rel(mydata->input, REL_WHEEL, v); |
2527 | &hidpp->vertical_wheel_counter, v); | ||
2528 | 2403 | ||
2529 | input_sync(mydata->input); | 2404 | input_sync(mydata->input); |
2530 | } | 2405 | } |
@@ -2653,72 +2528,6 @@ static int g920_get_config(struct hidpp_device *hidpp) | |||
2653 | } | 2528 | } |
2654 | 2529 | ||
2655 | /* -------------------------------------------------------------------------- */ | 2530 | /* -------------------------------------------------------------------------- */ |
2656 | /* High-resolution scroll wheels */ | ||
2657 | /* -------------------------------------------------------------------------- */ | ||
2658 | |||
2659 | /** | ||
2660 | * struct hi_res_scroll_info - Stores info on a device's high-res scroll wheel. | ||
2661 | * @product_id: the HID product ID of the device being described. | ||
2662 | * @microns_per_hi_res_unit: the distance moved by the user's finger for each | ||
2663 | * high-resolution unit reported by the device, in | ||
2664 | * 256ths of a millimetre. | ||
2665 | */ | ||
2666 | struct hi_res_scroll_info { | ||
2667 | __u32 product_id; | ||
2668 | int microns_per_hi_res_unit; | ||
2669 | }; | ||
2670 | |||
2671 | static struct hi_res_scroll_info hi_res_scroll_devices[] = { | ||
2672 | { /* Anywhere MX */ | ||
2673 | .product_id = 0x1017, .microns_per_hi_res_unit = 445 }, | ||
2674 | { /* Performance MX */ | ||
2675 | .product_id = 0x101a, .microns_per_hi_res_unit = 406 }, | ||
2676 | { /* M560 */ | ||
2677 | .product_id = 0x402d, .microns_per_hi_res_unit = 435 }, | ||
2678 | { /* MX Master 2S */ | ||
2679 | .product_id = 0x4069, .microns_per_hi_res_unit = 406 }, | ||
2680 | }; | ||
2681 | |||
2682 | static int hi_res_scroll_look_up_microns(__u32 product_id) | ||
2683 | { | ||
2684 | int i; | ||
2685 | int num_devices = sizeof(hi_res_scroll_devices) | ||
2686 | / sizeof(hi_res_scroll_devices[0]); | ||
2687 | for (i = 0; i < num_devices; i++) { | ||
2688 | if (hi_res_scroll_devices[i].product_id == product_id) | ||
2689 | return hi_res_scroll_devices[i].microns_per_hi_res_unit; | ||
2690 | } | ||
2691 | /* We don't have a value for this device, so use a sensible default. */ | ||
2692 | return 406; | ||
2693 | } | ||
2694 | |||
2695 | static int hi_res_scroll_enable(struct hidpp_device *hidpp) | ||
2696 | { | ||
2697 | int ret; | ||
2698 | u8 multiplier = 8; | ||
2699 | |||
2700 | if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) { | ||
2701 | ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false); | ||
2702 | hidpp_hrw_get_wheel_capability(hidpp, &multiplier); | ||
2703 | } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) { | ||
2704 | ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true, | ||
2705 | &multiplier); | ||
2706 | } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ | ||
2707 | ret = hidpp10_enable_scrolling_acceleration(hidpp); | ||
2708 | |||
2709 | if (ret) | ||
2710 | return ret; | ||
2711 | |||
2712 | hidpp->vertical_wheel_counter.resolution_multiplier = multiplier; | ||
2713 | hidpp->vertical_wheel_counter.microns_per_hi_res_unit = | ||
2714 | hi_res_scroll_look_up_microns(hidpp->hid_dev->product); | ||
2715 | hid_info(hidpp->hid_dev, "multiplier = %d, microns = %d\n", | ||
2716 | multiplier, | ||
2717 | hidpp->vertical_wheel_counter.microns_per_hi_res_unit); | ||
2718 | return 0; | ||
2719 | } | ||
2720 | |||
2721 | /* -------------------------------------------------------------------------- */ | ||
2722 | /* Generic HID++ devices */ | 2531 | /* Generic HID++ devices */ |
2723 | /* -------------------------------------------------------------------------- */ | 2532 | /* -------------------------------------------------------------------------- */ |
2724 | 2533 | ||
@@ -2763,11 +2572,6 @@ static void hidpp_populate_input(struct hidpp_device *hidpp, | |||
2763 | wtp_populate_input(hidpp, input, origin_is_hid_core); | 2572 | wtp_populate_input(hidpp, input, origin_is_hid_core); |
2764 | else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) | 2573 | else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) |
2765 | m560_populate_input(hidpp, input, origin_is_hid_core); | 2574 | m560_populate_input(hidpp, input, origin_is_hid_core); |
2766 | |||
2767 | if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) { | ||
2768 | input_set_capability(input, EV_REL, REL_WHEEL_HI_RES); | ||
2769 | hidpp->vertical_wheel_counter.dev = input; | ||
2770 | } | ||
2771 | } | 2575 | } |
2772 | 2576 | ||
2773 | static int hidpp_input_configured(struct hid_device *hdev, | 2577 | static int hidpp_input_configured(struct hid_device *hdev, |
@@ -2886,27 +2690,6 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
2886 | return 0; | 2690 | return 0; |
2887 | } | 2691 | } |
2888 | 2692 | ||
2889 | static int hidpp_event(struct hid_device *hdev, struct hid_field *field, | ||
2890 | struct hid_usage *usage, __s32 value) | ||
2891 | { | ||
2892 | /* This function will only be called for scroll events, due to the | ||
2893 | * restriction imposed in hidpp_usages. | ||
2894 | */ | ||
2895 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
2896 | struct hid_scroll_counter *counter = &hidpp->vertical_wheel_counter; | ||
2897 | /* A scroll event may occur before the multiplier has been retrieved or | ||
2898 | * the input device set, or high-res scroll enabling may fail. In such | ||
2899 | * cases we must return early (falling back to default behaviour) to | ||
2900 | * avoid a crash in hid_scroll_counter_handle_scroll. | ||
2901 | */ | ||
2902 | if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0 | ||
2903 | || counter->dev == NULL || counter->resolution_multiplier == 0) | ||
2904 | return 0; | ||
2905 | |||
2906 | hid_scroll_counter_handle_scroll(counter, value); | ||
2907 | return 1; | ||
2908 | } | ||
2909 | |||
2910 | static int hidpp_initialize_battery(struct hidpp_device *hidpp) | 2693 | static int hidpp_initialize_battery(struct hidpp_device *hidpp) |
2911 | { | 2694 | { |
2912 | static atomic_t battery_no = ATOMIC_INIT(0); | 2695 | static atomic_t battery_no = ATOMIC_INIT(0); |
@@ -3118,9 +2901,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
3118 | if (hidpp->battery.ps) | 2901 | if (hidpp->battery.ps) |
3119 | power_supply_changed(hidpp->battery.ps); | 2902 | power_supply_changed(hidpp->battery.ps); |
3120 | 2903 | ||
3121 | if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) | ||
3122 | hi_res_scroll_enable(hidpp); | ||
3123 | |||
3124 | if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) | 2904 | if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) |
3125 | /* if the input nodes are already created, we can stop now */ | 2905 | /* if the input nodes are already created, we can stop now */ |
3126 | return; | 2906 | return; |
@@ -3306,63 +3086,35 @@ static void hidpp_remove(struct hid_device *hdev) | |||
3306 | mutex_destroy(&hidpp->send_mutex); | 3086 | mutex_destroy(&hidpp->send_mutex); |
3307 | } | 3087 | } |
3308 | 3088 | ||
3309 | #define LDJ_DEVICE(product) \ | ||
3310 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \ | ||
3311 | USB_VENDOR_ID_LOGITECH, (product)) | ||
3312 | |||
3313 | static const struct hid_device_id hidpp_devices[] = { | 3089 | static const struct hid_device_id hidpp_devices[] = { |
3314 | { /* wireless touchpad */ | 3090 | { /* wireless touchpad */ |
3315 | LDJ_DEVICE(0x4011), | 3091 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
3092 | USB_VENDOR_ID_LOGITECH, 0x4011), | ||
3316 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | | 3093 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | |
3317 | HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, | 3094 | HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, |
3318 | { /* wireless touchpad T650 */ | 3095 | { /* wireless touchpad T650 */ |
3319 | LDJ_DEVICE(0x4101), | 3096 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
3097 | USB_VENDOR_ID_LOGITECH, 0x4101), | ||
3320 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, | 3098 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, |
3321 | { /* wireless touchpad T651 */ | 3099 | { /* wireless touchpad T651 */ |
3322 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, | 3100 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, |
3323 | USB_DEVICE_ID_LOGITECH_T651), | 3101 | USB_DEVICE_ID_LOGITECH_T651), |
3324 | .driver_data = HIDPP_QUIRK_CLASS_WTP }, | 3102 | .driver_data = HIDPP_QUIRK_CLASS_WTP }, |
3325 | { /* Mouse Logitech Anywhere MX */ | ||
3326 | LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, | ||
3327 | { /* Mouse Logitech Cube */ | ||
3328 | LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, | ||
3329 | { /* Mouse Logitech M335 */ | ||
3330 | LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3331 | { /* Mouse Logitech M515 */ | ||
3332 | LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, | ||
3333 | { /* Mouse logitech M560 */ | 3103 | { /* Mouse logitech M560 */ |
3334 | LDJ_DEVICE(0x402d), | 3104 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
3335 | .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 | 3105 | USB_VENDOR_ID_LOGITECH, 0x402d), |
3336 | | HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, | 3106 | .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 }, |
3337 | { /* Mouse Logitech M705 (firmware RQM17) */ | ||
3338 | LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, | ||
3339 | { /* Mouse Logitech M705 (firmware RQM67) */ | ||
3340 | LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3341 | { /* Mouse Logitech M720 */ | ||
3342 | LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3343 | { /* Mouse Logitech MX Anywhere 2 */ | ||
3344 | LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3345 | { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3346 | { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3347 | { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3348 | { /* Mouse Logitech MX Anywhere 2S */ | ||
3349 | LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3350 | { /* Mouse Logitech MX Master */ | ||
3351 | LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3352 | { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3353 | { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3354 | { /* Mouse Logitech MX Master 2S */ | ||
3355 | LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
3356 | { /* Mouse Logitech Performance MX */ | ||
3357 | LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, | ||
3358 | { /* Keyboard logitech K400 */ | 3107 | { /* Keyboard logitech K400 */ |
3359 | LDJ_DEVICE(0x4024), | 3108 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
3109 | USB_VENDOR_ID_LOGITECH, 0x4024), | ||
3360 | .driver_data = HIDPP_QUIRK_CLASS_K400 }, | 3110 | .driver_data = HIDPP_QUIRK_CLASS_K400 }, |
3361 | { /* Solar Keyboard Logitech K750 */ | 3111 | { /* Solar Keyboard Logitech K750 */ |
3362 | LDJ_DEVICE(0x4002), | 3112 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
3113 | USB_VENDOR_ID_LOGITECH, 0x4002), | ||
3363 | .driver_data = HIDPP_QUIRK_CLASS_K750 }, | 3114 | .driver_data = HIDPP_QUIRK_CLASS_K750 }, |
3364 | 3115 | ||
3365 | { LDJ_DEVICE(HID_ANY_ID) }, | 3116 | { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
3117 | USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, | ||
3366 | 3118 | ||
3367 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), | 3119 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), |
3368 | .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, | 3120 | .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, |
@@ -3371,19 +3123,12 @@ static const struct hid_device_id hidpp_devices[] = { | |||
3371 | 3123 | ||
3372 | MODULE_DEVICE_TABLE(hid, hidpp_devices); | 3124 | MODULE_DEVICE_TABLE(hid, hidpp_devices); |
3373 | 3125 | ||
3374 | static const struct hid_usage_id hidpp_usages[] = { | ||
3375 | { HID_GD_WHEEL, EV_REL, REL_WHEEL }, | ||
3376 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
3377 | }; | ||
3378 | |||
3379 | static struct hid_driver hidpp_driver = { | 3126 | static struct hid_driver hidpp_driver = { |
3380 | .name = "logitech-hidpp-device", | 3127 | .name = "logitech-hidpp-device", |
3381 | .id_table = hidpp_devices, | 3128 | .id_table = hidpp_devices, |
3382 | .probe = hidpp_probe, | 3129 | .probe = hidpp_probe, |
3383 | .remove = hidpp_remove, | 3130 | .remove = hidpp_remove, |
3384 | .raw_event = hidpp_raw_event, | 3131 | .raw_event = hidpp_raw_event, |
3385 | .usage_table = hidpp_usages, | ||
3386 | .event = hidpp_event, | ||
3387 | .input_configured = hidpp_input_configured, | 3132 | .input_configured = hidpp_input_configured, |
3388 | .input_mapping = hidpp_input_mapping, | 3133 | .input_mapping = hidpp_input_mapping, |
3389 | .input_mapped = hidpp_input_mapped, | 3134 | .input_mapped = hidpp_input_mapped, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index f7c6de2b6730..dca0a3a90fb8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1814,6 +1814,12 @@ static const struct hid_device_id mt_devices[] = { | |||
1814 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | 1814 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, |
1815 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | 1815 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, |
1816 | 1816 | ||
1817 | /* Cirque devices */ | ||
1818 | { .driver_data = MT_CLS_WIN_8_DUAL, | ||
1819 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | ||
1820 | I2C_VENDOR_ID_CIRQUE, | ||
1821 | I2C_PRODUCT_ID_CIRQUE_121F) }, | ||
1822 | |||
1817 | /* CJTouch panels */ | 1823 | /* CJTouch panels */ |
1818 | { .driver_data = MT_CLS_NSMU, | 1824 | { .driver_data = MT_CLS_NSMU, |
1819 | MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, | 1825 | MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, |
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 8237dd86fb17..c85a79986b6a 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c | |||
@@ -107,6 +107,7 @@ static const struct hid_device_id hid_quirks[] = { | |||
107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, | 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, |
108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, | 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, |
109 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, | 109 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, |
110 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL }, | ||
110 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, | 111 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, |
111 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, | 112 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, |
112 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, | 113 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, |
@@ -129,6 +130,8 @@ static const struct hid_device_id hid_quirks[] = { | |||
129 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS }, | 130 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS }, |
130 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, | 131 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, |
131 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL }, | 132 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL }, |
133 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL }, | ||
134 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL }, | ||
132 | { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET }, | 135 | { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET }, |
133 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET }, | 136 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET }, |
134 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET }, | 137 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET }, |
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c index 0422ec2b13d2..dc4128bfe2ca 100644 --- a/drivers/hid/hid-steam.c +++ b/drivers/hid/hid-steam.c | |||
@@ -23,8 +23,9 @@ | |||
23 | * In order to avoid breaking them this driver creates a layered hidraw device, | 23 | * In order to avoid breaking them this driver creates a layered hidraw device, |
24 | * so it can detect when the client is running and then: | 24 | * so it can detect when the client is running and then: |
25 | * - it will not send any command to the controller. | 25 | * - it will not send any command to the controller. |
26 | * - this input device will be disabled, to avoid double input of the same | 26 | * - this input device will be removed, to avoid double input of the same |
27 | * user action. | 27 | * user action. |
28 | * When the client is closed, this input device will be created again. | ||
28 | * | 29 | * |
29 | * For additional functions, such as changing the right-pad margin or switching | 30 | * For additional functions, such as changing the right-pad margin or switching |
30 | * the led, you can use the user-space tool at: | 31 | * the led, you can use the user-space tool at: |
@@ -113,7 +114,7 @@ struct steam_device { | |||
113 | spinlock_t lock; | 114 | spinlock_t lock; |
114 | struct hid_device *hdev, *client_hdev; | 115 | struct hid_device *hdev, *client_hdev; |
115 | struct mutex mutex; | 116 | struct mutex mutex; |
116 | bool client_opened, input_opened; | 117 | bool client_opened; |
117 | struct input_dev __rcu *input; | 118 | struct input_dev __rcu *input; |
118 | unsigned long quirks; | 119 | unsigned long quirks; |
119 | struct work_struct work_connect; | 120 | struct work_struct work_connect; |
@@ -279,18 +280,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) | |||
279 | } | 280 | } |
280 | } | 281 | } |
281 | 282 | ||
282 | static void steam_update_lizard_mode(struct steam_device *steam) | ||
283 | { | ||
284 | mutex_lock(&steam->mutex); | ||
285 | if (!steam->client_opened) { | ||
286 | if (steam->input_opened) | ||
287 | steam_set_lizard_mode(steam, false); | ||
288 | else | ||
289 | steam_set_lizard_mode(steam, lizard_mode); | ||
290 | } | ||
291 | mutex_unlock(&steam->mutex); | ||
292 | } | ||
293 | |||
294 | static int steam_input_open(struct input_dev *dev) | 283 | static int steam_input_open(struct input_dev *dev) |
295 | { | 284 | { |
296 | struct steam_device *steam = input_get_drvdata(dev); | 285 | struct steam_device *steam = input_get_drvdata(dev); |
@@ -301,7 +290,6 @@ static int steam_input_open(struct input_dev *dev) | |||
301 | return ret; | 290 | return ret; |
302 | 291 | ||
303 | mutex_lock(&steam->mutex); | 292 | mutex_lock(&steam->mutex); |
304 | steam->input_opened = true; | ||
305 | if (!steam->client_opened && lizard_mode) | 293 | if (!steam->client_opened && lizard_mode) |
306 | steam_set_lizard_mode(steam, false); | 294 | steam_set_lizard_mode(steam, false); |
307 | mutex_unlock(&steam->mutex); | 295 | mutex_unlock(&steam->mutex); |
@@ -313,7 +301,6 @@ static void steam_input_close(struct input_dev *dev) | |||
313 | struct steam_device *steam = input_get_drvdata(dev); | 301 | struct steam_device *steam = input_get_drvdata(dev); |
314 | 302 | ||
315 | mutex_lock(&steam->mutex); | 303 | mutex_lock(&steam->mutex); |
316 | steam->input_opened = false; | ||
317 | if (!steam->client_opened && lizard_mode) | 304 | if (!steam->client_opened && lizard_mode) |
318 | steam_set_lizard_mode(steam, true); | 305 | steam_set_lizard_mode(steam, true); |
319 | mutex_unlock(&steam->mutex); | 306 | mutex_unlock(&steam->mutex); |
@@ -400,7 +387,7 @@ static int steam_battery_register(struct steam_device *steam) | |||
400 | return 0; | 387 | return 0; |
401 | } | 388 | } |
402 | 389 | ||
403 | static int steam_register(struct steam_device *steam) | 390 | static int steam_input_register(struct steam_device *steam) |
404 | { | 391 | { |
405 | struct hid_device *hdev = steam->hdev; | 392 | struct hid_device *hdev = steam->hdev; |
406 | struct input_dev *input; | 393 | struct input_dev *input; |
@@ -414,17 +401,6 @@ static int steam_register(struct steam_device *steam) | |||
414 | return 0; | 401 | return 0; |
415 | } | 402 | } |
416 | 403 | ||
417 | /* | ||
418 | * Unlikely, but getting the serial could fail, and it is not so | ||
419 | * important, so make up a serial number and go on. | ||
420 | */ | ||
421 | if (steam_get_serial(steam) < 0) | ||
422 | strlcpy(steam->serial_no, "XXXXXXXXXX", | ||
423 | sizeof(steam->serial_no)); | ||
424 | |||
425 | hid_info(hdev, "Steam Controller '%s' connected", | ||
426 | steam->serial_no); | ||
427 | |||
428 | input = input_allocate_device(); | 404 | input = input_allocate_device(); |
429 | if (!input) | 405 | if (!input) |
430 | return -ENOMEM; | 406 | return -ENOMEM; |
@@ -492,11 +468,6 @@ static int steam_register(struct steam_device *steam) | |||
492 | goto input_register_fail; | 468 | goto input_register_fail; |
493 | 469 | ||
494 | rcu_assign_pointer(steam->input, input); | 470 | rcu_assign_pointer(steam->input, input); |
495 | |||
496 | /* ignore battery errors, we can live without it */ | ||
497 | if (steam->quirks & STEAM_QUIRK_WIRELESS) | ||
498 | steam_battery_register(steam); | ||
499 | |||
500 | return 0; | 471 | return 0; |
501 | 472 | ||
502 | input_register_fail: | 473 | input_register_fail: |
@@ -504,27 +475,88 @@ input_register_fail: | |||
504 | return ret; | 475 | return ret; |
505 | } | 476 | } |
506 | 477 | ||
507 | static void steam_unregister(struct steam_device *steam) | 478 | static void steam_input_unregister(struct steam_device *steam) |
508 | { | 479 | { |
509 | struct input_dev *input; | 480 | struct input_dev *input; |
481 | rcu_read_lock(); | ||
482 | input = rcu_dereference(steam->input); | ||
483 | rcu_read_unlock(); | ||
484 | if (!input) | ||
485 | return; | ||
486 | RCU_INIT_POINTER(steam->input, NULL); | ||
487 | synchronize_rcu(); | ||
488 | input_unregister_device(input); | ||
489 | } | ||
490 | |||
491 | static void steam_battery_unregister(struct steam_device *steam) | ||
492 | { | ||
510 | struct power_supply *battery; | 493 | struct power_supply *battery; |
511 | 494 | ||
512 | rcu_read_lock(); | 495 | rcu_read_lock(); |
513 | input = rcu_dereference(steam->input); | ||
514 | battery = rcu_dereference(steam->battery); | 496 | battery = rcu_dereference(steam->battery); |
515 | rcu_read_unlock(); | 497 | rcu_read_unlock(); |
516 | 498 | ||
517 | if (battery) { | 499 | if (!battery) |
518 | RCU_INIT_POINTER(steam->battery, NULL); | 500 | return; |
519 | synchronize_rcu(); | 501 | RCU_INIT_POINTER(steam->battery, NULL); |
520 | power_supply_unregister(battery); | 502 | synchronize_rcu(); |
503 | power_supply_unregister(battery); | ||
504 | } | ||
505 | |||
506 | static int steam_register(struct steam_device *steam) | ||
507 | { | ||
508 | int ret; | ||
509 | |||
510 | /* | ||
511 | * This function can be called several times in a row with the | ||
512 | * wireless adaptor, without steam_unregister() between them, because | ||
513 | * another client send a get_connection_status command, for example. | ||
514 | * The battery and serial number are set just once per device. | ||
515 | */ | ||
516 | if (!steam->serial_no[0]) { | ||
517 | /* | ||
518 | * Unlikely, but getting the serial could fail, and it is not so | ||
519 | * important, so make up a serial number and go on. | ||
520 | */ | ||
521 | if (steam_get_serial(steam) < 0) | ||
522 | strlcpy(steam->serial_no, "XXXXXXXXXX", | ||
523 | sizeof(steam->serial_no)); | ||
524 | |||
525 | hid_info(steam->hdev, "Steam Controller '%s' connected", | ||
526 | steam->serial_no); | ||
527 | |||
528 | /* ignore battery errors, we can live without it */ | ||
529 | if (steam->quirks & STEAM_QUIRK_WIRELESS) | ||
530 | steam_battery_register(steam); | ||
531 | |||
532 | mutex_lock(&steam_devices_lock); | ||
533 | list_add(&steam->list, &steam_devices); | ||
534 | mutex_unlock(&steam_devices_lock); | ||
521 | } | 535 | } |
522 | if (input) { | 536 | |
523 | RCU_INIT_POINTER(steam->input, NULL); | 537 | mutex_lock(&steam->mutex); |
524 | synchronize_rcu(); | 538 | if (!steam->client_opened) { |
539 | steam_set_lizard_mode(steam, lizard_mode); | ||
540 | ret = steam_input_register(steam); | ||
541 | } else { | ||
542 | ret = 0; | ||
543 | } | ||
544 | mutex_unlock(&steam->mutex); | ||
545 | |||
546 | return ret; | ||
547 | } | ||
548 | |||
549 | static void steam_unregister(struct steam_device *steam) | ||
550 | { | ||
551 | steam_battery_unregister(steam); | ||
552 | steam_input_unregister(steam); | ||
553 | if (steam->serial_no[0]) { | ||
525 | hid_info(steam->hdev, "Steam Controller '%s' disconnected", | 554 | hid_info(steam->hdev, "Steam Controller '%s' disconnected", |
526 | steam->serial_no); | 555 | steam->serial_no); |
527 | input_unregister_device(input); | 556 | mutex_lock(&steam_devices_lock); |
557 | list_del(&steam->list); | ||
558 | mutex_unlock(&steam_devices_lock); | ||
559 | steam->serial_no[0] = 0; | ||
528 | } | 560 | } |
529 | } | 561 | } |
530 | 562 | ||
@@ -600,6 +632,9 @@ static int steam_client_ll_open(struct hid_device *hdev) | |||
600 | mutex_lock(&steam->mutex); | 632 | mutex_lock(&steam->mutex); |
601 | steam->client_opened = true; | 633 | steam->client_opened = true; |
602 | mutex_unlock(&steam->mutex); | 634 | mutex_unlock(&steam->mutex); |
635 | |||
636 | steam_input_unregister(steam); | ||
637 | |||
603 | return ret; | 638 | return ret; |
604 | } | 639 | } |
605 | 640 | ||
@@ -609,13 +644,13 @@ static void steam_client_ll_close(struct hid_device *hdev) | |||
609 | 644 | ||
610 | mutex_lock(&steam->mutex); | 645 | mutex_lock(&steam->mutex); |
611 | steam->client_opened = false; | 646 | steam->client_opened = false; |
612 | if (steam->input_opened) | ||
613 | steam_set_lizard_mode(steam, false); | ||
614 | else | ||
615 | steam_set_lizard_mode(steam, lizard_mode); | ||
616 | mutex_unlock(&steam->mutex); | 647 | mutex_unlock(&steam->mutex); |
617 | 648 | ||
618 | hid_hw_close(steam->hdev); | 649 | hid_hw_close(steam->hdev); |
650 | if (steam->connected) { | ||
651 | steam_set_lizard_mode(steam, lizard_mode); | ||
652 | steam_input_register(steam); | ||
653 | } | ||
619 | } | 654 | } |
620 | 655 | ||
621 | static int steam_client_ll_raw_request(struct hid_device *hdev, | 656 | static int steam_client_ll_raw_request(struct hid_device *hdev, |
@@ -744,11 +779,6 @@ static int steam_probe(struct hid_device *hdev, | |||
744 | } | 779 | } |
745 | } | 780 | } |
746 | 781 | ||
747 | mutex_lock(&steam_devices_lock); | ||
748 | steam_update_lizard_mode(steam); | ||
749 | list_add(&steam->list, &steam_devices); | ||
750 | mutex_unlock(&steam_devices_lock); | ||
751 | |||
752 | return 0; | 782 | return 0; |
753 | 783 | ||
754 | hid_hw_open_fail: | 784 | hid_hw_open_fail: |
@@ -774,10 +804,6 @@ static void steam_remove(struct hid_device *hdev) | |||
774 | return; | 804 | return; |
775 | } | 805 | } |
776 | 806 | ||
777 | mutex_lock(&steam_devices_lock); | ||
778 | list_del(&steam->list); | ||
779 | mutex_unlock(&steam_devices_lock); | ||
780 | |||
781 | hid_destroy_device(steam->client_hdev); | 807 | hid_destroy_device(steam->client_hdev); |
782 | steam->client_opened = false; | 808 | steam->client_opened = false; |
783 | cancel_work_sync(&steam->work_connect); | 809 | cancel_work_sync(&steam->work_connect); |
@@ -792,12 +818,14 @@ static void steam_remove(struct hid_device *hdev) | |||
792 | static void steam_do_connect_event(struct steam_device *steam, bool connected) | 818 | static void steam_do_connect_event(struct steam_device *steam, bool connected) |
793 | { | 819 | { |
794 | unsigned long flags; | 820 | unsigned long flags; |
821 | bool changed; | ||
795 | 822 | ||
796 | spin_lock_irqsave(&steam->lock, flags); | 823 | spin_lock_irqsave(&steam->lock, flags); |
824 | changed = steam->connected != connected; | ||
797 | steam->connected = connected; | 825 | steam->connected = connected; |
798 | spin_unlock_irqrestore(&steam->lock, flags); | 826 | spin_unlock_irqrestore(&steam->lock, flags); |
799 | 827 | ||
800 | if (schedule_work(&steam->work_connect) == 0) | 828 | if (changed && schedule_work(&steam->work_connect) == 0) |
801 | dbg_hid("%s: connected=%d event already queued\n", | 829 | dbg_hid("%s: connected=%d event already queued\n", |
802 | __func__, connected); | 830 | __func__, connected); |
803 | } | 831 | } |
@@ -1019,13 +1047,8 @@ static int steam_raw_event(struct hid_device *hdev, | |||
1019 | return 0; | 1047 | return 0; |
1020 | rcu_read_lock(); | 1048 | rcu_read_lock(); |
1021 | input = rcu_dereference(steam->input); | 1049 | input = rcu_dereference(steam->input); |
1022 | if (likely(input)) { | 1050 | if (likely(input)) |
1023 | steam_do_input_event(steam, input, data); | 1051 | steam_do_input_event(steam, input, data); |
1024 | } else { | ||
1025 | dbg_hid("%s: input data without connect event\n", | ||
1026 | __func__); | ||
1027 | steam_do_connect_event(steam, true); | ||
1028 | } | ||
1029 | rcu_read_unlock(); | 1052 | rcu_read_unlock(); |
1030 | break; | 1053 | break; |
1031 | case STEAM_EV_CONNECT: | 1054 | case STEAM_EV_CONNECT: |
@@ -1074,7 +1097,10 @@ static int steam_param_set_lizard_mode(const char *val, | |||
1074 | 1097 | ||
1075 | mutex_lock(&steam_devices_lock); | 1098 | mutex_lock(&steam_devices_lock); |
1076 | list_for_each_entry(steam, &steam_devices, list) { | 1099 | list_for_each_entry(steam, &steam_devices, list) { |
1077 | steam_update_lizard_mode(steam); | 1100 | mutex_lock(&steam->mutex); |
1101 | if (!steam->client_opened) | ||
1102 | steam_set_lizard_mode(steam, lizard_mode); | ||
1103 | mutex_unlock(&steam->mutex); | ||
1078 | } | 1104 | } |
1079 | mutex_unlock(&steam_devices_lock); | 1105 | mutex_unlock(&steam_devices_lock); |
1080 | return 0; | 1106 | return 0; |
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 3cde7c1b9c33..8555ce7e737b 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c | |||
@@ -177,6 +177,8 @@ static const struct i2c_hid_quirks { | |||
177 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | 177 | I2C_HID_QUIRK_NO_RUNTIME_PM }, |
178 | { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, | 178 | { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, |
179 | I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, | 179 | I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, |
180 | { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001, | ||
181 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | ||
180 | { 0, 0 } | 182 | { 0, 0 } |
181 | }; | 183 | }; |
182 | 184 | ||
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 3c5507313606..840634e0f1e3 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
15 | #include <linux/cred.h> | ||
15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
16 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
17 | #include <linux/hid.h> | 18 | #include <linux/hid.h> |
@@ -496,12 +497,13 @@ static int uhid_dev_create2(struct uhid_device *uhid, | |||
496 | goto err_free; | 497 | goto err_free; |
497 | } | 498 | } |
498 | 499 | ||
499 | len = min(sizeof(hid->name), sizeof(ev->u.create2.name)); | 500 | /* @hid is zero-initialized, strncpy() is correct, strlcpy() not */ |
500 | strlcpy(hid->name, ev->u.create2.name, len); | 501 | len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1; |
501 | len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)); | 502 | strncpy(hid->name, ev->u.create2.name, len); |
502 | strlcpy(hid->phys, ev->u.create2.phys, len); | 503 | len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1; |
503 | len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)); | 504 | strncpy(hid->phys, ev->u.create2.phys, len); |
504 | strlcpy(hid->uniq, ev->u.create2.uniq, len); | 505 | len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1; |
506 | strncpy(hid->uniq, ev->u.create2.uniq, len); | ||
505 | 507 | ||
506 | hid->ll_driver = &uhid_hid_driver; | 508 | hid->ll_driver = &uhid_hid_driver; |
507 | hid->bus = ev->u.create2.bus; | 509 | hid->bus = ev->u.create2.bus; |
@@ -722,6 +724,17 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
722 | 724 | ||
723 | switch (uhid->input_buf.type) { | 725 | switch (uhid->input_buf.type) { |
724 | case UHID_CREATE: | 726 | case UHID_CREATE: |
727 | /* | ||
728 | * 'struct uhid_create_req' contains a __user pointer which is | ||
729 | * copied from, so it's unsafe to allow this with elevated | ||
730 | * privileges (e.g. from a setuid binary) or via kernel_write(). | ||
731 | */ | ||
732 | if (file->f_cred != current_cred() || uaccess_kernel()) { | ||
733 | pr_err_once("UHID_CREATE from different security context by process %d (%s), this is not allowed.\n", | ||
734 | task_tgid_vnr(current), current->comm); | ||
735 | ret = -EACCES; | ||
736 | goto unlock; | ||
737 | } | ||
725 | ret = uhid_dev_create(uhid, &uhid->input_buf); | 738 | ret = uhid_dev_create(uhid, &uhid->input_buf); |
726 | break; | 739 | break; |
727 | case UHID_CREATE2: | 740 | case UHID_CREATE2: |
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index a7513a8a8e37..d6106e1a0d4a 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c | |||
@@ -353,6 +353,9 @@ static void process_ib_ipinfo(void *in_msg, void *out_msg, int op) | |||
353 | 353 | ||
354 | out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled; | 354 | out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled; |
355 | 355 | ||
356 | /* fallthrough */ | ||
357 | |||
358 | case KVP_OP_GET_IP_INFO: | ||
356 | utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id, | 359 | utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id, |
357 | MAX_ADAPTER_ID_SIZE, | 360 | MAX_ADAPTER_ID_SIZE, |
358 | UTF16_LITTLE_ENDIAN, | 361 | UTF16_LITTLE_ENDIAN, |
@@ -405,7 +408,11 @@ kvp_send_key(struct work_struct *dummy) | |||
405 | process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO); | 408 | process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO); |
406 | break; | 409 | break; |
407 | case KVP_OP_GET_IP_INFO: | 410 | case KVP_OP_GET_IP_INFO: |
408 | /* We only need to pass on message->kvp_hdr.operation. */ | 411 | /* |
412 | * We only need to pass on the info of operation, adapter_id | ||
413 | * and addr_family to the userland kvp daemon. | ||
414 | */ | ||
415 | process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO); | ||
409 | break; | 416 | break; |
410 | case KVP_OP_SET: | 417 | case KVP_OP_SET: |
411 | switch (in_msg->body.kvp_set.data.value_type) { | 418 | switch (in_msg->body.kvp_set.data.value_type) { |
@@ -446,9 +453,9 @@ kvp_send_key(struct work_struct *dummy) | |||
446 | 453 | ||
447 | } | 454 | } |
448 | 455 | ||
449 | break; | 456 | /* |
450 | 457 | * The key is always a string - utf16 encoding. | |
451 | case KVP_OP_GET: | 458 | */ |
452 | message->body.kvp_set.data.key_size = | 459 | message->body.kvp_set.data.key_size = |
453 | utf16s_to_utf8s( | 460 | utf16s_to_utf8s( |
454 | (wchar_t *)in_msg->body.kvp_set.data.key, | 461 | (wchar_t *)in_msg->body.kvp_set.data.key, |
@@ -456,6 +463,17 @@ kvp_send_key(struct work_struct *dummy) | |||
456 | UTF16_LITTLE_ENDIAN, | 463 | UTF16_LITTLE_ENDIAN, |
457 | message->body.kvp_set.data.key, | 464 | message->body.kvp_set.data.key, |
458 | HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1; | 465 | HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1; |
466 | |||
467 | break; | ||
468 | |||
469 | case KVP_OP_GET: | ||
470 | message->body.kvp_get.data.key_size = | ||
471 | utf16s_to_utf8s( | ||
472 | (wchar_t *)in_msg->body.kvp_get.data.key, | ||
473 | in_msg->body.kvp_get.data.key_size, | ||
474 | UTF16_LITTLE_ENDIAN, | ||
475 | message->body.kvp_get.data.key, | ||
476 | HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1; | ||
459 | break; | 477 | break; |
460 | 478 | ||
461 | case KVP_OP_DELETE: | 479 | case KVP_OP_DELETE: |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index bb2cd29e1658..d8f7000a466a 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -797,7 +797,8 @@ static int iommu_init_ga_log(struct amd_iommu *iommu) | |||
797 | entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; | 797 | entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; |
798 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, | 798 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, |
799 | &entry, sizeof(entry)); | 799 | &entry, sizeof(entry)); |
800 | entry = (iommu_virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL; | 800 | entry = (iommu_virt_to_phys(iommu->ga_log_tail) & |
801 | (BIT_ULL(52)-1)) & ~7ULL; | ||
801 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, | 802 | memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, |
802 | &entry, sizeof(entry)); | 803 | &entry, sizeof(entry)); |
803 | writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); | 804 | writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index f3ccf025108b..41a4b8808802 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -3075,7 +3075,7 @@ static int copy_context_table(struct intel_iommu *iommu, | |||
3075 | } | 3075 | } |
3076 | 3076 | ||
3077 | if (old_ce) | 3077 | if (old_ce) |
3078 | iounmap(old_ce); | 3078 | memunmap(old_ce); |
3079 | 3079 | ||
3080 | ret = 0; | 3080 | ret = 0; |
3081 | if (devfn < 0x80) | 3081 | if (devfn < 0x80) |
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index db301efe126d..887150907526 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c | |||
@@ -595,7 +595,7 @@ static irqreturn_t prq_event_thread(int irq, void *d) | |||
595 | pr_err("%s: Page request without PASID: %08llx %08llx\n", | 595 | pr_err("%s: Page request without PASID: %08llx %08llx\n", |
596 | iommu->name, ((unsigned long long *)req)[0], | 596 | iommu->name, ((unsigned long long *)req)[0], |
597 | ((unsigned long long *)req)[1]); | 597 | ((unsigned long long *)req)[1]); |
598 | goto bad_req; | 598 | goto no_pasid; |
599 | } | 599 | } |
600 | 600 | ||
601 | if (!svm || svm->pasid != req->pasid) { | 601 | if (!svm || svm->pasid != req->pasid) { |
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index b98a03189580..ddf3a492e1d5 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c | |||
@@ -498,6 +498,9 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) | |||
498 | 498 | ||
499 | static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain) | 499 | static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain) |
500 | { | 500 | { |
501 | if (!domain->mmu) | ||
502 | return; | ||
503 | |||
501 | /* | 504 | /* |
502 | * Disable the context. Flush the TLB as required when modifying the | 505 | * Disable the context. Flush the TLB as required when modifying the |
503 | * context registers. | 506 | * context registers. |
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 31d1f4ab915e..65a933a21e68 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c | |||
@@ -807,7 +807,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, | |||
807 | } | 807 | } |
808 | 808 | ||
809 | if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) { | 809 | if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) { |
810 | dprintk(1, "%s: transmit queue full\n", __func__); | 810 | dprintk(2, "%s: transmit queue full\n", __func__); |
811 | return -EBUSY; | 811 | return -EBUSY; |
812 | } | 812 | } |
813 | 813 | ||
@@ -1180,6 +1180,8 @@ static int cec_config_log_addr(struct cec_adapter *adap, | |||
1180 | { | 1180 | { |
1181 | struct cec_log_addrs *las = &adap->log_addrs; | 1181 | struct cec_log_addrs *las = &adap->log_addrs; |
1182 | struct cec_msg msg = { }; | 1182 | struct cec_msg msg = { }; |
1183 | const unsigned int max_retries = 2; | ||
1184 | unsigned int i; | ||
1183 | int err; | 1185 | int err; |
1184 | 1186 | ||
1185 | if (cec_has_log_addr(adap, log_addr)) | 1187 | if (cec_has_log_addr(adap, log_addr)) |
@@ -1188,19 +1190,44 @@ static int cec_config_log_addr(struct cec_adapter *adap, | |||
1188 | /* Send poll message */ | 1190 | /* Send poll message */ |
1189 | msg.len = 1; | 1191 | msg.len = 1; |
1190 | msg.msg[0] = (log_addr << 4) | log_addr; | 1192 | msg.msg[0] = (log_addr << 4) | log_addr; |
1191 | err = cec_transmit_msg_fh(adap, &msg, NULL, true); | ||
1192 | 1193 | ||
1193 | /* | 1194 | for (i = 0; i < max_retries; i++) { |
1194 | * While trying to poll the physical address was reset | 1195 | err = cec_transmit_msg_fh(adap, &msg, NULL, true); |
1195 | * and the adapter was unconfigured, so bail out. | ||
1196 | */ | ||
1197 | if (!adap->is_configuring) | ||
1198 | return -EINTR; | ||
1199 | 1196 | ||
1200 | if (err) | 1197 | /* |
1201 | return err; | 1198 | * While trying to poll the physical address was reset |
1199 | * and the adapter was unconfigured, so bail out. | ||
1200 | */ | ||
1201 | if (!adap->is_configuring) | ||
1202 | return -EINTR; | ||
1203 | |||
1204 | if (err) | ||
1205 | return err; | ||
1202 | 1206 | ||
1203 | if (msg.tx_status & CEC_TX_STATUS_OK) | 1207 | /* |
1208 | * The message was aborted due to a disconnect or | ||
1209 | * unconfigure, just bail out. | ||
1210 | */ | ||
1211 | if (msg.tx_status & CEC_TX_STATUS_ABORTED) | ||
1212 | return -EINTR; | ||
1213 | if (msg.tx_status & CEC_TX_STATUS_OK) | ||
1214 | return 0; | ||
1215 | if (msg.tx_status & CEC_TX_STATUS_NACK) | ||
1216 | break; | ||
1217 | /* | ||
1218 | * Retry up to max_retries times if the message was neither | ||
1219 | * OKed or NACKed. This can happen due to e.g. a Lost | ||
1220 | * Arbitration condition. | ||
1221 | */ | ||
1222 | } | ||
1223 | |||
1224 | /* | ||
1225 | * If we are unable to get an OK or a NACK after max_retries attempts | ||
1226 | * (and note that each attempt already consists of four polls), then | ||
1227 | * then we assume that something is really weird and that it is not a | ||
1228 | * good idea to try and claim this logical address. | ||
1229 | */ | ||
1230 | if (i == max_retries) | ||
1204 | return 0; | 1231 | return 0; |
1205 | 1232 | ||
1206 | /* | 1233 | /* |
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index a38e54b8f687..22cafc07de25 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c | |||
@@ -1918,7 +1918,6 @@ static int tc358743_probe_of(struct tc358743_state *state) | |||
1918 | ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint); | 1918 | ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint); |
1919 | if (ret) { | 1919 | if (ret) { |
1920 | dev_err(dev, "failed to parse endpoint\n"); | 1920 | dev_err(dev, "failed to parse endpoint\n"); |
1921 | ret = ret; | ||
1922 | goto put_node; | 1921 | goto put_node; |
1923 | } | 1922 | } |
1924 | 1923 | ||
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 452eb9b42140..447baaebca44 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c | |||
@@ -1844,14 +1844,12 @@ fail_mutex_destroy: | |||
1844 | static void cio2_pci_remove(struct pci_dev *pci_dev) | 1844 | static void cio2_pci_remove(struct pci_dev *pci_dev) |
1845 | { | 1845 | { |
1846 | struct cio2_device *cio2 = pci_get_drvdata(pci_dev); | 1846 | struct cio2_device *cio2 = pci_get_drvdata(pci_dev); |
1847 | unsigned int i; | ||
1848 | 1847 | ||
1848 | media_device_unregister(&cio2->media_dev); | ||
1849 | cio2_notifier_exit(cio2); | 1849 | cio2_notifier_exit(cio2); |
1850 | cio2_queues_exit(cio2); | ||
1850 | cio2_fbpt_exit_dummy(cio2); | 1851 | cio2_fbpt_exit_dummy(cio2); |
1851 | for (i = 0; i < CIO2_QUEUES; i++) | ||
1852 | cio2_queue_exit(cio2, &cio2->queue[i]); | ||
1853 | v4l2_device_unregister(&cio2->v4l2_dev); | 1852 | v4l2_device_unregister(&cio2->v4l2_dev); |
1854 | media_device_unregister(&cio2->media_dev); | ||
1855 | media_device_cleanup(&cio2->media_dev); | 1853 | media_device_cleanup(&cio2->media_dev); |
1856 | mutex_destroy(&cio2->lock); | 1854 | mutex_destroy(&cio2->lock); |
1857 | } | 1855 | } |
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 77fb7987b42f..13f2828d880d 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c | |||
@@ -1587,6 +1587,8 @@ static void isp_pm_complete(struct device *dev) | |||
1587 | 1587 | ||
1588 | static void isp_unregister_entities(struct isp_device *isp) | 1588 | static void isp_unregister_entities(struct isp_device *isp) |
1589 | { | 1589 | { |
1590 | media_device_unregister(&isp->media_dev); | ||
1591 | |||
1590 | omap3isp_csi2_unregister_entities(&isp->isp_csi2a); | 1592 | omap3isp_csi2_unregister_entities(&isp->isp_csi2a); |
1591 | omap3isp_ccp2_unregister_entities(&isp->isp_ccp2); | 1593 | omap3isp_ccp2_unregister_entities(&isp->isp_ccp2); |
1592 | omap3isp_ccdc_unregister_entities(&isp->isp_ccdc); | 1594 | omap3isp_ccdc_unregister_entities(&isp->isp_ccdc); |
@@ -1597,7 +1599,6 @@ static void isp_unregister_entities(struct isp_device *isp) | |||
1597 | omap3isp_stat_unregister_entities(&isp->isp_hist); | 1599 | omap3isp_stat_unregister_entities(&isp->isp_hist); |
1598 | 1600 | ||
1599 | v4l2_device_unregister(&isp->v4l2_dev); | 1601 | v4l2_device_unregister(&isp->v4l2_dev); |
1600 | media_device_unregister(&isp->media_dev); | ||
1601 | media_device_cleanup(&isp->media_dev); | 1602 | media_device_cleanup(&isp->media_dev); |
1602 | } | 1603 | } |
1603 | 1604 | ||
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c index 1eb9132bfc85..b292cff26c86 100644 --- a/drivers/media/platform/vicodec/vicodec-core.c +++ b/drivers/media/platform/vicodec/vicodec-core.c | |||
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(debug, " activates debug info"); | |||
42 | #define MAX_WIDTH 4096U | 42 | #define MAX_WIDTH 4096U |
43 | #define MIN_WIDTH 640U | 43 | #define MIN_WIDTH 640U |
44 | #define MAX_HEIGHT 2160U | 44 | #define MAX_HEIGHT 2160U |
45 | #define MIN_HEIGHT 480U | 45 | #define MIN_HEIGHT 360U |
46 | 46 | ||
47 | #define dprintk(dev, fmt, arg...) \ | 47 | #define dprintk(dev, fmt, arg...) \ |
48 | v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) | 48 | v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) |
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index af150a0395df..d82db738f174 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c | |||
@@ -1009,7 +1009,7 @@ static const struct v4l2_m2m_ops m2m_ops = { | |||
1009 | 1009 | ||
1010 | static const struct media_device_ops m2m_media_ops = { | 1010 | static const struct media_device_ops m2m_media_ops = { |
1011 | .req_validate = vb2_request_validate, | 1011 | .req_validate = vb2_request_validate, |
1012 | .req_queue = vb2_m2m_request_queue, | 1012 | .req_queue = v4l2_m2m_request_queue, |
1013 | }; | 1013 | }; |
1014 | 1014 | ||
1015 | static int vim2m_probe(struct platform_device *pdev) | 1015 | static int vim2m_probe(struct platform_device *pdev) |
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 6e37950292cd..5f2b033a7a42 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | |||
@@ -1664,6 +1664,11 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, | |||
1664 | p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME) | 1664 | p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME) |
1665 | return -EINVAL; | 1665 | return -EINVAL; |
1666 | 1666 | ||
1667 | if (p_mpeg2_slice_params->pad || | ||
1668 | p_mpeg2_slice_params->picture.pad || | ||
1669 | p_mpeg2_slice_params->sequence.pad) | ||
1670 | return -EINVAL; | ||
1671 | |||
1667 | return 0; | 1672 | return 0; |
1668 | 1673 | ||
1669 | case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: | 1674 | case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: |
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index a3ef1f50a4b3..481e3c65cf97 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c | |||
@@ -193,6 +193,22 @@ int v4l2_event_pending(struct v4l2_fh *fh) | |||
193 | } | 193 | } |
194 | EXPORT_SYMBOL_GPL(v4l2_event_pending); | 194 | EXPORT_SYMBOL_GPL(v4l2_event_pending); |
195 | 195 | ||
196 | static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev) | ||
197 | { | ||
198 | struct v4l2_fh *fh = sev->fh; | ||
199 | unsigned int i; | ||
200 | |||
201 | lockdep_assert_held(&fh->subscribe_lock); | ||
202 | assert_spin_locked(&fh->vdev->fh_lock); | ||
203 | |||
204 | /* Remove any pending events for this subscription */ | ||
205 | for (i = 0; i < sev->in_use; i++) { | ||
206 | list_del(&sev->events[sev_pos(sev, i)].list); | ||
207 | fh->navailable--; | ||
208 | } | ||
209 | list_del(&sev->list); | ||
210 | } | ||
211 | |||
196 | int v4l2_event_subscribe(struct v4l2_fh *fh, | 212 | int v4l2_event_subscribe(struct v4l2_fh *fh, |
197 | const struct v4l2_event_subscription *sub, unsigned elems, | 213 | const struct v4l2_event_subscription *sub, unsigned elems, |
198 | const struct v4l2_subscribed_event_ops *ops) | 214 | const struct v4l2_subscribed_event_ops *ops) |
@@ -224,27 +240,23 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
224 | 240 | ||
225 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | 241 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
226 | found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); | 242 | found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); |
243 | if (!found_ev) | ||
244 | list_add(&sev->list, &fh->subscribed); | ||
227 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | 245 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); |
228 | 246 | ||
229 | if (found_ev) { | 247 | if (found_ev) { |
230 | /* Already listening */ | 248 | /* Already listening */ |
231 | kvfree(sev); | 249 | kvfree(sev); |
232 | goto out_unlock; | 250 | } else if (sev->ops && sev->ops->add) { |
233 | } | ||
234 | |||
235 | if (sev->ops && sev->ops->add) { | ||
236 | ret = sev->ops->add(sev, elems); | 251 | ret = sev->ops->add(sev, elems); |
237 | if (ret) { | 252 | if (ret) { |
253 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | ||
254 | __v4l2_event_unsubscribe(sev); | ||
255 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | ||
238 | kvfree(sev); | 256 | kvfree(sev); |
239 | goto out_unlock; | ||
240 | } | 257 | } |
241 | } | 258 | } |
242 | 259 | ||
243 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | ||
244 | list_add(&sev->list, &fh->subscribed); | ||
245 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | ||
246 | |||
247 | out_unlock: | ||
248 | mutex_unlock(&fh->subscribe_lock); | 260 | mutex_unlock(&fh->subscribe_lock); |
249 | 261 | ||
250 | return ret; | 262 | return ret; |
@@ -279,7 +291,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
279 | { | 291 | { |
280 | struct v4l2_subscribed_event *sev; | 292 | struct v4l2_subscribed_event *sev; |
281 | unsigned long flags; | 293 | unsigned long flags; |
282 | int i; | ||
283 | 294 | ||
284 | if (sub->type == V4L2_EVENT_ALL) { | 295 | if (sub->type == V4L2_EVENT_ALL) { |
285 | v4l2_event_unsubscribe_all(fh); | 296 | v4l2_event_unsubscribe_all(fh); |
@@ -291,14 +302,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
291 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | 302 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
292 | 303 | ||
293 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); | 304 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); |
294 | if (sev != NULL) { | 305 | if (sev != NULL) |
295 | /* Remove any pending events for this subscription */ | 306 | __v4l2_event_unsubscribe(sev); |
296 | for (i = 0; i < sev->in_use; i++) { | ||
297 | list_del(&sev->events[sev_pos(sev, i)].list); | ||
298 | fh->navailable--; | ||
299 | } | ||
300 | list_del(&sev->list); | ||
301 | } | ||
302 | 307 | ||
303 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | 308 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); |
304 | 309 | ||
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index d7806db222d8..1ed2465972ac 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | |||
@@ -953,7 +953,7 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, | |||
953 | } | 953 | } |
954 | EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue); | 954 | EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue); |
955 | 955 | ||
956 | void vb2_m2m_request_queue(struct media_request *req) | 956 | void v4l2_m2m_request_queue(struct media_request *req) |
957 | { | 957 | { |
958 | struct media_request_object *obj, *obj_safe; | 958 | struct media_request_object *obj, *obj_safe; |
959 | struct v4l2_m2m_ctx *m2m_ctx = NULL; | 959 | struct v4l2_m2m_ctx *m2m_ctx = NULL; |
@@ -997,7 +997,7 @@ void vb2_m2m_request_queue(struct media_request *req) | |||
997 | if (m2m_ctx) | 997 | if (m2m_ctx) |
998 | v4l2_m2m_try_schedule(m2m_ctx); | 998 | v4l2_m2m_try_schedule(m2m_ctx); |
999 | } | 999 | } |
1000 | EXPORT_SYMBOL_GPL(vb2_m2m_request_queue); | 1000 | EXPORT_SYMBOL_GPL(v4l2_m2m_request_queue); |
1001 | 1001 | ||
1002 | /* Videobuf2 ioctl helpers */ | 1002 | /* Videobuf2 ioctl helpers */ |
1003 | 1003 | ||
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index b2a0340f277e..d8e3cc2dc747 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c | |||
@@ -132,7 +132,7 @@ static const struct of_device_id atmel_ssc_dt_ids[] = { | |||
132 | MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids); | 132 | MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids); |
133 | #endif | 133 | #endif |
134 | 134 | ||
135 | static inline const struct atmel_ssc_platform_data * __init | 135 | static inline const struct atmel_ssc_platform_data * |
136 | atmel_ssc_get_driver_data(struct platform_device *pdev) | 136 | atmel_ssc_get_driver_data(struct platform_device *pdev) |
137 | { | 137 | { |
138 | if (pdev->dev.of_node) { | 138 | if (pdev->dev.of_node) { |
diff --git a/drivers/misc/sgi-gru/grukdump.c b/drivers/misc/sgi-gru/grukdump.c index 313da3150262..1540a7785e14 100644 --- a/drivers/misc/sgi-gru/grukdump.c +++ b/drivers/misc/sgi-gru/grukdump.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | #include <asm/uv/uv_hub.h> | 29 | #include <asm/uv/uv_hub.h> |
30 | |||
31 | #include <linux/nospec.h> | ||
32 | |||
30 | #include "gru.h" | 33 | #include "gru.h" |
31 | #include "grutables.h" | 34 | #include "grutables.h" |
32 | #include "gruhandles.h" | 35 | #include "gruhandles.h" |
@@ -196,6 +199,7 @@ int gru_dump_chiplet_request(unsigned long arg) | |||
196 | /* Currently, only dump by gid is implemented */ | 199 | /* Currently, only dump by gid is implemented */ |
197 | if (req.gid >= gru_max_gids) | 200 | if (req.gid >= gru_max_gids) |
198 | return -EINVAL; | 201 | return -EINVAL; |
202 | req.gid = array_index_nospec(req.gid, gru_max_gids); | ||
199 | 203 | ||
200 | gru = GID_TO_GRU(req.gid); | 204 | gru = GID_TO_GRU(req.gid); |
201 | ubuf = req.buf; | 205 | ubuf = req.buf; |
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 7bfd366d970d..c4115bae5db1 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
@@ -12,6 +12,7 @@ | |||
12 | * - JMicron (hardware and technical support) | 12 | * - JMicron (hardware and technical support) |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/bitfield.h> | ||
15 | #include <linux/string.h> | 16 | #include <linux/string.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
17 | #include <linux/highmem.h> | 18 | #include <linux/highmem.h> |
@@ -462,6 +463,9 @@ struct intel_host { | |||
462 | u32 dsm_fns; | 463 | u32 dsm_fns; |
463 | int drv_strength; | 464 | int drv_strength; |
464 | bool d3_retune; | 465 | bool d3_retune; |
466 | bool rpm_retune_ok; | ||
467 | u32 glk_rx_ctrl1; | ||
468 | u32 glk_tun_val; | ||
465 | }; | 469 | }; |
466 | 470 | ||
467 | static const guid_t intel_dsm_guid = | 471 | static const guid_t intel_dsm_guid = |
@@ -791,6 +795,77 @@ cleanup: | |||
791 | return ret; | 795 | return ret; |
792 | } | 796 | } |
793 | 797 | ||
798 | #ifdef CONFIG_PM | ||
799 | #define GLK_RX_CTRL1 0x834 | ||
800 | #define GLK_TUN_VAL 0x840 | ||
801 | #define GLK_PATH_PLL GENMASK(13, 8) | ||
802 | #define GLK_DLY GENMASK(6, 0) | ||
803 | /* Workaround firmware failing to restore the tuning value */ | ||
804 | static void glk_rpm_retune_wa(struct sdhci_pci_chip *chip, bool susp) | ||
805 | { | ||
806 | struct sdhci_pci_slot *slot = chip->slots[0]; | ||
807 | struct intel_host *intel_host = sdhci_pci_priv(slot); | ||
808 | struct sdhci_host *host = slot->host; | ||
809 | u32 glk_rx_ctrl1; | ||
810 | u32 glk_tun_val; | ||
811 | u32 dly; | ||
812 | |||
813 | if (intel_host->rpm_retune_ok || !mmc_can_retune(host->mmc)) | ||
814 | return; | ||
815 | |||
816 | glk_rx_ctrl1 = sdhci_readl(host, GLK_RX_CTRL1); | ||
817 | glk_tun_val = sdhci_readl(host, GLK_TUN_VAL); | ||
818 | |||
819 | if (susp) { | ||
820 | intel_host->glk_rx_ctrl1 = glk_rx_ctrl1; | ||
821 | intel_host->glk_tun_val = glk_tun_val; | ||
822 | return; | ||
823 | } | ||
824 | |||
825 | if (!intel_host->glk_tun_val) | ||
826 | return; | ||
827 | |||
828 | if (glk_rx_ctrl1 != intel_host->glk_rx_ctrl1) { | ||
829 | intel_host->rpm_retune_ok = true; | ||
830 | return; | ||
831 | } | ||
832 | |||
833 | dly = FIELD_PREP(GLK_DLY, FIELD_GET(GLK_PATH_PLL, glk_rx_ctrl1) + | ||
834 | (intel_host->glk_tun_val << 1)); | ||
835 | if (dly == FIELD_GET(GLK_DLY, glk_rx_ctrl1)) | ||
836 | return; | ||
837 | |||
838 | glk_rx_ctrl1 = (glk_rx_ctrl1 & ~GLK_DLY) | dly; | ||
839 | sdhci_writel(host, glk_rx_ctrl1, GLK_RX_CTRL1); | ||
840 | |||
841 | intel_host->rpm_retune_ok = true; | ||
842 | chip->rpm_retune = true; | ||
843 | mmc_retune_needed(host->mmc); | ||
844 | pr_info("%s: Requiring re-tune after rpm resume", mmc_hostname(host->mmc)); | ||
845 | } | ||
846 | |||
847 | static void glk_rpm_retune_chk(struct sdhci_pci_chip *chip, bool susp) | ||
848 | { | ||
849 | if (chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_EMMC && | ||
850 | !chip->rpm_retune) | ||
851 | glk_rpm_retune_wa(chip, susp); | ||
852 | } | ||
853 | |||
854 | static int glk_runtime_suspend(struct sdhci_pci_chip *chip) | ||
855 | { | ||
856 | glk_rpm_retune_chk(chip, true); | ||
857 | |||
858 | return sdhci_cqhci_runtime_suspend(chip); | ||
859 | } | ||
860 | |||
861 | static int glk_runtime_resume(struct sdhci_pci_chip *chip) | ||
862 | { | ||
863 | glk_rpm_retune_chk(chip, false); | ||
864 | |||
865 | return sdhci_cqhci_runtime_resume(chip); | ||
866 | } | ||
867 | #endif | ||
868 | |||
794 | #ifdef CONFIG_ACPI | 869 | #ifdef CONFIG_ACPI |
795 | static int ni_set_max_freq(struct sdhci_pci_slot *slot) | 870 | static int ni_set_max_freq(struct sdhci_pci_slot *slot) |
796 | { | 871 | { |
@@ -879,8 +954,8 @@ static const struct sdhci_pci_fixes sdhci_intel_glk_emmc = { | |||
879 | .resume = sdhci_cqhci_resume, | 954 | .resume = sdhci_cqhci_resume, |
880 | #endif | 955 | #endif |
881 | #ifdef CONFIG_PM | 956 | #ifdef CONFIG_PM |
882 | .runtime_suspend = sdhci_cqhci_runtime_suspend, | 957 | .runtime_suspend = glk_runtime_suspend, |
883 | .runtime_resume = sdhci_cqhci_runtime_resume, | 958 | .runtime_resume = glk_runtime_resume, |
884 | #endif | 959 | #endif |
885 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 960 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
886 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 961 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
@@ -1762,8 +1837,13 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( | |||
1762 | device_init_wakeup(&pdev->dev, true); | 1837 | device_init_wakeup(&pdev->dev, true); |
1763 | 1838 | ||
1764 | if (slot->cd_idx >= 0) { | 1839 | if (slot->cd_idx >= 0) { |
1765 | ret = mmc_gpiod_request_cd(host->mmc, NULL, slot->cd_idx, | 1840 | ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx, |
1766 | slot->cd_override_level, 0, NULL); | 1841 | slot->cd_override_level, 0, NULL); |
1842 | if (ret && ret != -EPROBE_DEFER) | ||
1843 | ret = mmc_gpiod_request_cd(host->mmc, NULL, | ||
1844 | slot->cd_idx, | ||
1845 | slot->cd_override_level, | ||
1846 | 0, NULL); | ||
1767 | if (ret == -EPROBE_DEFER) | 1847 | if (ret == -EPROBE_DEFER) |
1768 | goto remove; | 1848 | goto remove; |
1769 | 1849 | ||
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index fb33f6be7c4f..ad720494e8f7 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c | |||
@@ -2032,8 +2032,7 @@ atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller *nc) | |||
2032 | int ret; | 2032 | int ret; |
2033 | 2033 | ||
2034 | nand_np = dev->of_node; | 2034 | nand_np = dev->of_node; |
2035 | nfc_np = of_find_compatible_node(dev->of_node, NULL, | 2035 | nfc_np = of_get_compatible_child(dev->of_node, "atmel,sama5d3-nfc"); |
2036 | "atmel,sama5d3-nfc"); | ||
2037 | if (!nfc_np) { | 2036 | if (!nfc_np) { |
2038 | dev_err(dev, "Could not find device node for sama5d3-nfc\n"); | 2037 | dev_err(dev, "Could not find device node for sama5d3-nfc\n"); |
2039 | return -ENODEV; | 2038 | return -ENODEV; |
@@ -2447,15 +2446,19 @@ static int atmel_nand_controller_probe(struct platform_device *pdev) | |||
2447 | } | 2446 | } |
2448 | 2447 | ||
2449 | if (caps->legacy_of_bindings) { | 2448 | if (caps->legacy_of_bindings) { |
2449 | struct device_node *nfc_node; | ||
2450 | u32 ale_offs = 21; | 2450 | u32 ale_offs = 21; |
2451 | 2451 | ||
2452 | /* | 2452 | /* |
2453 | * If we are parsing legacy DT props and the DT contains a | 2453 | * If we are parsing legacy DT props and the DT contains a |
2454 | * valid NFC node, forward the request to the sama5 logic. | 2454 | * valid NFC node, forward the request to the sama5 logic. |
2455 | */ | 2455 | */ |
2456 | if (of_find_compatible_node(pdev->dev.of_node, NULL, | 2456 | nfc_node = of_get_compatible_child(pdev->dev.of_node, |
2457 | "atmel,sama5d3-nfc")) | 2457 | "atmel,sama5d3-nfc"); |
2458 | if (nfc_node) { | ||
2458 | caps = &atmel_sama5_nand_caps; | 2459 | caps = &atmel_sama5_nand_caps; |
2460 | of_node_put(nfc_node); | ||
2461 | } | ||
2459 | 2462 | ||
2460 | /* | 2463 | /* |
2461 | * Even if the compatible says we are dealing with an | 2464 | * Even if the compatible says we are dealing with an |
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index ef75dfa62a4f..699d3cf49c6d 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c | |||
@@ -150,15 +150,15 @@ | |||
150 | #define NAND_VERSION_MINOR_SHIFT 16 | 150 | #define NAND_VERSION_MINOR_SHIFT 16 |
151 | 151 | ||
152 | /* NAND OP_CMDs */ | 152 | /* NAND OP_CMDs */ |
153 | #define PAGE_READ 0x2 | 153 | #define OP_PAGE_READ 0x2 |
154 | #define PAGE_READ_WITH_ECC 0x3 | 154 | #define OP_PAGE_READ_WITH_ECC 0x3 |
155 | #define PAGE_READ_WITH_ECC_SPARE 0x4 | 155 | #define OP_PAGE_READ_WITH_ECC_SPARE 0x4 |
156 | #define PROGRAM_PAGE 0x6 | 156 | #define OP_PROGRAM_PAGE 0x6 |
157 | #define PAGE_PROGRAM_WITH_ECC 0x7 | 157 | #define OP_PAGE_PROGRAM_WITH_ECC 0x7 |
158 | #define PROGRAM_PAGE_SPARE 0x9 | 158 | #define OP_PROGRAM_PAGE_SPARE 0x9 |
159 | #define BLOCK_ERASE 0xa | 159 | #define OP_BLOCK_ERASE 0xa |
160 | #define FETCH_ID 0xb | 160 | #define OP_FETCH_ID 0xb |
161 | #define RESET_DEVICE 0xd | 161 | #define OP_RESET_DEVICE 0xd |
162 | 162 | ||
163 | /* Default Value for NAND_DEV_CMD_VLD */ | 163 | /* Default Value for NAND_DEV_CMD_VLD */ |
164 | #define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \ | 164 | #define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \ |
@@ -692,11 +692,11 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) | |||
692 | 692 | ||
693 | if (read) { | 693 | if (read) { |
694 | if (host->use_ecc) | 694 | if (host->use_ecc) |
695 | cmd = PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE; | 695 | cmd = OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE; |
696 | else | 696 | else |
697 | cmd = PAGE_READ | PAGE_ACC | LAST_PAGE; | 697 | cmd = OP_PAGE_READ | PAGE_ACC | LAST_PAGE; |
698 | } else { | 698 | } else { |
699 | cmd = PROGRAM_PAGE | PAGE_ACC | LAST_PAGE; | 699 | cmd = OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE; |
700 | } | 700 | } |
701 | 701 | ||
702 | if (host->use_ecc) { | 702 | if (host->use_ecc) { |
@@ -1170,7 +1170,7 @@ static int nandc_param(struct qcom_nand_host *host) | |||
1170 | * in use. we configure the controller to perform a raw read of 512 | 1170 | * in use. we configure the controller to perform a raw read of 512 |
1171 | * bytes to read onfi params | 1171 | * bytes to read onfi params |
1172 | */ | 1172 | */ |
1173 | nandc_set_reg(nandc, NAND_FLASH_CMD, PAGE_READ | PAGE_ACC | LAST_PAGE); | 1173 | nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ | PAGE_ACC | LAST_PAGE); |
1174 | nandc_set_reg(nandc, NAND_ADDR0, 0); | 1174 | nandc_set_reg(nandc, NAND_ADDR0, 0); |
1175 | nandc_set_reg(nandc, NAND_ADDR1, 0); | 1175 | nandc_set_reg(nandc, NAND_ADDR1, 0); |
1176 | nandc_set_reg(nandc, NAND_DEV0_CFG0, 0 << CW_PER_PAGE | 1176 | nandc_set_reg(nandc, NAND_DEV0_CFG0, 0 << CW_PER_PAGE |
@@ -1224,7 +1224,7 @@ static int erase_block(struct qcom_nand_host *host, int page_addr) | |||
1224 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); | 1224 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
1225 | 1225 | ||
1226 | nandc_set_reg(nandc, NAND_FLASH_CMD, | 1226 | nandc_set_reg(nandc, NAND_FLASH_CMD, |
1227 | BLOCK_ERASE | PAGE_ACC | LAST_PAGE); | 1227 | OP_BLOCK_ERASE | PAGE_ACC | LAST_PAGE); |
1228 | nandc_set_reg(nandc, NAND_ADDR0, page_addr); | 1228 | nandc_set_reg(nandc, NAND_ADDR0, page_addr); |
1229 | nandc_set_reg(nandc, NAND_ADDR1, 0); | 1229 | nandc_set_reg(nandc, NAND_ADDR1, 0); |
1230 | nandc_set_reg(nandc, NAND_DEV0_CFG0, | 1230 | nandc_set_reg(nandc, NAND_DEV0_CFG0, |
@@ -1255,7 +1255,7 @@ static int read_id(struct qcom_nand_host *host, int column) | |||
1255 | if (column == -1) | 1255 | if (column == -1) |
1256 | return 0; | 1256 | return 0; |
1257 | 1257 | ||
1258 | nandc_set_reg(nandc, NAND_FLASH_CMD, FETCH_ID); | 1258 | nandc_set_reg(nandc, NAND_FLASH_CMD, OP_FETCH_ID); |
1259 | nandc_set_reg(nandc, NAND_ADDR0, column); | 1259 | nandc_set_reg(nandc, NAND_ADDR0, column); |
1260 | nandc_set_reg(nandc, NAND_ADDR1, 0); | 1260 | nandc_set_reg(nandc, NAND_ADDR1, 0); |
1261 | nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, | 1261 | nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, |
@@ -1276,7 +1276,7 @@ static int reset(struct qcom_nand_host *host) | |||
1276 | struct nand_chip *chip = &host->chip; | 1276 | struct nand_chip *chip = &host->chip; |
1277 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); | 1277 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
1278 | 1278 | ||
1279 | nandc_set_reg(nandc, NAND_FLASH_CMD, RESET_DEVICE); | 1279 | nandc_set_reg(nandc, NAND_FLASH_CMD, OP_RESET_DEVICE); |
1280 | nandc_set_reg(nandc, NAND_EXEC_CMD, 1); | 1280 | nandc_set_reg(nandc, NAND_EXEC_CMD, 1); |
1281 | 1281 | ||
1282 | write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); | 1282 | write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); |
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index d846428ef038..04cedd3a2bf6 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c | |||
@@ -644,9 +644,23 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr, | |||
644 | ndelay(cqspi->wr_delay); | 644 | ndelay(cqspi->wr_delay); |
645 | 645 | ||
646 | while (remaining > 0) { | 646 | while (remaining > 0) { |
647 | size_t write_words, mod_bytes; | ||
648 | |||
647 | write_bytes = remaining > page_size ? page_size : remaining; | 649 | write_bytes = remaining > page_size ? page_size : remaining; |
648 | iowrite32_rep(cqspi->ahb_base, txbuf, | 650 | write_words = write_bytes / 4; |
649 | DIV_ROUND_UP(write_bytes, 4)); | 651 | mod_bytes = write_bytes % 4; |
652 | /* Write 4 bytes at a time then single bytes. */ | ||
653 | if (write_words) { | ||
654 | iowrite32_rep(cqspi->ahb_base, txbuf, write_words); | ||
655 | txbuf += (write_words * 4); | ||
656 | } | ||
657 | if (mod_bytes) { | ||
658 | unsigned int temp = 0xFFFFFFFF; | ||
659 | |||
660 | memcpy(&temp, txbuf, mod_bytes); | ||
661 | iowrite32(temp, cqspi->ahb_base); | ||
662 | txbuf += mod_bytes; | ||
663 | } | ||
650 | 664 | ||
651 | if (!wait_for_completion_timeout(&cqspi->transfer_complete, | 665 | if (!wait_for_completion_timeout(&cqspi->transfer_complete, |
652 | msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { | 666 | msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { |
@@ -655,7 +669,6 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr, | |||
655 | goto failwr; | 669 | goto failwr; |
656 | } | 670 | } |
657 | 671 | ||
658 | txbuf += write_bytes; | ||
659 | remaining -= write_bytes; | 672 | remaining -= write_bytes; |
660 | 673 | ||
661 | if (remaining > 0) | 674 | if (remaining > 0) |
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 3e54e31889c7..93c9bc8931fc 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
@@ -2156,7 +2156,7 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, | |||
2156 | * @nor: pointer to a 'struct spi_nor' | 2156 | * @nor: pointer to a 'struct spi_nor' |
2157 | * @addr: offset in the serial flash memory | 2157 | * @addr: offset in the serial flash memory |
2158 | * @len: number of bytes to read | 2158 | * @len: number of bytes to read |
2159 | * @buf: buffer where the data is copied into | 2159 | * @buf: buffer where the data is copied into (dma-safe memory) |
2160 | * | 2160 | * |
2161 | * Return: 0 on success, -errno otherwise. | 2161 | * Return: 0 on success, -errno otherwise. |
2162 | */ | 2162 | */ |
@@ -2522,6 +2522,34 @@ static int spi_nor_map_cmp_erase_type(const void *l, const void *r) | |||
2522 | } | 2522 | } |
2523 | 2523 | ||
2524 | /** | 2524 | /** |
2525 | * spi_nor_sort_erase_mask() - sort erase mask | ||
2526 | * @map: the erase map of the SPI NOR | ||
2527 | * @erase_mask: the erase type mask to be sorted | ||
2528 | * | ||
2529 | * Replicate the sort done for the map's erase types in BFPT: sort the erase | ||
2530 | * mask in ascending order with the smallest erase type size starting from | ||
2531 | * BIT(0) in the sorted erase mask. | ||
2532 | * | ||
2533 | * Return: sorted erase mask. | ||
2534 | */ | ||
2535 | static u8 spi_nor_sort_erase_mask(struct spi_nor_erase_map *map, u8 erase_mask) | ||
2536 | { | ||
2537 | struct spi_nor_erase_type *erase_type = map->erase_type; | ||
2538 | int i; | ||
2539 | u8 sorted_erase_mask = 0; | ||
2540 | |||
2541 | if (!erase_mask) | ||
2542 | return 0; | ||
2543 | |||
2544 | /* Replicate the sort done for the map's erase types. */ | ||
2545 | for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) | ||
2546 | if (erase_type[i].size && erase_mask & BIT(erase_type[i].idx)) | ||
2547 | sorted_erase_mask |= BIT(i); | ||
2548 | |||
2549 | return sorted_erase_mask; | ||
2550 | } | ||
2551 | |||
2552 | /** | ||
2525 | * spi_nor_regions_sort_erase_types() - sort erase types in each region | 2553 | * spi_nor_regions_sort_erase_types() - sort erase types in each region |
2526 | * @map: the erase map of the SPI NOR | 2554 | * @map: the erase map of the SPI NOR |
2527 | * | 2555 | * |
@@ -2536,19 +2564,13 @@ static int spi_nor_map_cmp_erase_type(const void *l, const void *r) | |||
2536 | static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) | 2564 | static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) |
2537 | { | 2565 | { |
2538 | struct spi_nor_erase_region *region = map->regions; | 2566 | struct spi_nor_erase_region *region = map->regions; |
2539 | struct spi_nor_erase_type *erase_type = map->erase_type; | ||
2540 | int i; | ||
2541 | u8 region_erase_mask, sorted_erase_mask; | 2567 | u8 region_erase_mask, sorted_erase_mask; |
2542 | 2568 | ||
2543 | while (region) { | 2569 | while (region) { |
2544 | region_erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; | 2570 | region_erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; |
2545 | 2571 | ||
2546 | /* Replicate the sort done for the map's erase types. */ | 2572 | sorted_erase_mask = spi_nor_sort_erase_mask(map, |
2547 | sorted_erase_mask = 0; | 2573 | region_erase_mask); |
2548 | for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) | ||
2549 | if (erase_type[i].size && | ||
2550 | region_erase_mask & BIT(erase_type[i].idx)) | ||
2551 | sorted_erase_mask |= BIT(i); | ||
2552 | 2574 | ||
2553 | /* Overwrite erase mask. */ | 2575 | /* Overwrite erase mask. */ |
2554 | region->offset = (region->offset & ~SNOR_ERASE_TYPE_MASK) | | 2576 | region->offset = (region->offset & ~SNOR_ERASE_TYPE_MASK) | |
@@ -2855,52 +2877,84 @@ static u8 spi_nor_smpt_read_dummy(const struct spi_nor *nor, const u32 settings) | |||
2855 | * spi_nor_get_map_in_use() - get the configuration map in use | 2877 | * spi_nor_get_map_in_use() - get the configuration map in use |
2856 | * @nor: pointer to a 'struct spi_nor' | 2878 | * @nor: pointer to a 'struct spi_nor' |
2857 | * @smpt: pointer to the sector map parameter table | 2879 | * @smpt: pointer to the sector map parameter table |
2880 | * @smpt_len: sector map parameter table length | ||
2881 | * | ||
2882 | * Return: pointer to the map in use, ERR_PTR(-errno) otherwise. | ||
2858 | */ | 2883 | */ |
2859 | static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt) | 2884 | static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt, |
2885 | u8 smpt_len) | ||
2860 | { | 2886 | { |
2861 | const u32 *ret = NULL; | 2887 | const u32 *ret; |
2862 | u32 i, addr; | 2888 | u8 *buf; |
2889 | u32 addr; | ||
2863 | int err; | 2890 | int err; |
2891 | u8 i; | ||
2864 | u8 addr_width, read_opcode, read_dummy; | 2892 | u8 addr_width, read_opcode, read_dummy; |
2865 | u8 read_data_mask, data_byte, map_id; | 2893 | u8 read_data_mask, map_id; |
2894 | |||
2895 | /* Use a kmalloc'ed bounce buffer to guarantee it is DMA-able. */ | ||
2896 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); | ||
2897 | if (!buf) | ||
2898 | return ERR_PTR(-ENOMEM); | ||
2866 | 2899 | ||
2867 | addr_width = nor->addr_width; | 2900 | addr_width = nor->addr_width; |
2868 | read_dummy = nor->read_dummy; | 2901 | read_dummy = nor->read_dummy; |
2869 | read_opcode = nor->read_opcode; | 2902 | read_opcode = nor->read_opcode; |
2870 | 2903 | ||
2871 | map_id = 0; | 2904 | map_id = 0; |
2872 | i = 0; | ||
2873 | /* Determine if there are any optional Detection Command Descriptors */ | 2905 | /* Determine if there are any optional Detection Command Descriptors */ |
2874 | while (!(smpt[i] & SMPT_DESC_TYPE_MAP)) { | 2906 | for (i = 0; i < smpt_len; i += 2) { |
2907 | if (smpt[i] & SMPT_DESC_TYPE_MAP) | ||
2908 | break; | ||
2909 | |||
2875 | read_data_mask = SMPT_CMD_READ_DATA(smpt[i]); | 2910 | read_data_mask = SMPT_CMD_READ_DATA(smpt[i]); |
2876 | nor->addr_width = spi_nor_smpt_addr_width(nor, smpt[i]); | 2911 | nor->addr_width = spi_nor_smpt_addr_width(nor, smpt[i]); |
2877 | nor->read_dummy = spi_nor_smpt_read_dummy(nor, smpt[i]); | 2912 | nor->read_dummy = spi_nor_smpt_read_dummy(nor, smpt[i]); |
2878 | nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); | 2913 | nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); |
2879 | addr = smpt[i + 1]; | 2914 | addr = smpt[i + 1]; |
2880 | 2915 | ||
2881 | err = spi_nor_read_raw(nor, addr, 1, &data_byte); | 2916 | err = spi_nor_read_raw(nor, addr, 1, buf); |
2882 | if (err) | 2917 | if (err) { |
2918 | ret = ERR_PTR(err); | ||
2883 | goto out; | 2919 | goto out; |
2920 | } | ||
2884 | 2921 | ||
2885 | /* | 2922 | /* |
2886 | * Build an index value that is used to select the Sector Map | 2923 | * Build an index value that is used to select the Sector Map |
2887 | * Configuration that is currently in use. | 2924 | * Configuration that is currently in use. |
2888 | */ | 2925 | */ |
2889 | map_id = map_id << 1 | !!(data_byte & read_data_mask); | 2926 | map_id = map_id << 1 | !!(*buf & read_data_mask); |
2890 | i = i + 2; | ||
2891 | } | 2927 | } |
2892 | 2928 | ||
2893 | /* Find the matching configuration map */ | 2929 | /* |
2894 | while (SMPT_MAP_ID(smpt[i]) != map_id) { | 2930 | * If command descriptors are provided, they always precede map |
2931 | * descriptors in the table. There is no need to start the iteration | ||
2932 | * over smpt array all over again. | ||
2933 | * | ||
2934 | * Find the matching configuration map. | ||
2935 | */ | ||
2936 | ret = ERR_PTR(-EINVAL); | ||
2937 | while (i < smpt_len) { | ||
2938 | if (SMPT_MAP_ID(smpt[i]) == map_id) { | ||
2939 | ret = smpt + i; | ||
2940 | break; | ||
2941 | } | ||
2942 | |||
2943 | /* | ||
2944 | * If there are no more configuration map descriptors and no | ||
2945 | * configuration ID matched the configuration identifier, the | ||
2946 | * sector address map is unknown. | ||
2947 | */ | ||
2895 | if (smpt[i] & SMPT_DESC_END) | 2948 | if (smpt[i] & SMPT_DESC_END) |
2896 | goto out; | 2949 | break; |
2950 | |||
2897 | /* increment the table index to the next map */ | 2951 | /* increment the table index to the next map */ |
2898 | i += SMPT_MAP_REGION_COUNT(smpt[i]) + 1; | 2952 | i += SMPT_MAP_REGION_COUNT(smpt[i]) + 1; |
2899 | } | 2953 | } |
2900 | 2954 | ||
2901 | ret = smpt + i; | ||
2902 | /* fall through */ | 2955 | /* fall through */ |
2903 | out: | 2956 | out: |
2957 | kfree(buf); | ||
2904 | nor->addr_width = addr_width; | 2958 | nor->addr_width = addr_width; |
2905 | nor->read_dummy = read_dummy; | 2959 | nor->read_dummy = read_dummy; |
2906 | nor->read_opcode = read_opcode; | 2960 | nor->read_opcode = read_opcode; |
@@ -2946,7 +3000,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, | |||
2946 | u64 offset; | 3000 | u64 offset; |
2947 | u32 region_count; | 3001 | u32 region_count; |
2948 | int i, j; | 3002 | int i, j; |
2949 | u8 erase_type; | 3003 | u8 erase_type, uniform_erase_type; |
2950 | 3004 | ||
2951 | region_count = SMPT_MAP_REGION_COUNT(*smpt); | 3005 | region_count = SMPT_MAP_REGION_COUNT(*smpt); |
2952 | /* | 3006 | /* |
@@ -2959,7 +3013,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, | |||
2959 | return -ENOMEM; | 3013 | return -ENOMEM; |
2960 | map->regions = region; | 3014 | map->regions = region; |
2961 | 3015 | ||
2962 | map->uniform_erase_type = 0xff; | 3016 | uniform_erase_type = 0xff; |
2963 | offset = 0; | 3017 | offset = 0; |
2964 | /* Populate regions. */ | 3018 | /* Populate regions. */ |
2965 | for (i = 0; i < region_count; i++) { | 3019 | for (i = 0; i < region_count; i++) { |
@@ -2974,12 +3028,15 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, | |||
2974 | * Save the erase types that are supported in all regions and | 3028 | * Save the erase types that are supported in all regions and |
2975 | * can erase the entire flash memory. | 3029 | * can erase the entire flash memory. |
2976 | */ | 3030 | */ |
2977 | map->uniform_erase_type &= erase_type; | 3031 | uniform_erase_type &= erase_type; |
2978 | 3032 | ||
2979 | offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) + | 3033 | offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) + |
2980 | region[i].size; | 3034 | region[i].size; |
2981 | } | 3035 | } |
2982 | 3036 | ||
3037 | map->uniform_erase_type = spi_nor_sort_erase_mask(map, | ||
3038 | uniform_erase_type); | ||
3039 | |||
2983 | spi_nor_region_mark_end(®ion[i - 1]); | 3040 | spi_nor_region_mark_end(®ion[i - 1]); |
2984 | 3041 | ||
2985 | return 0; | 3042 | return 0; |
@@ -3020,9 +3077,9 @@ static int spi_nor_parse_smpt(struct spi_nor *nor, | |||
3020 | for (i = 0; i < smpt_header->length; i++) | 3077 | for (i = 0; i < smpt_header->length; i++) |
3021 | smpt[i] = le32_to_cpu(smpt[i]); | 3078 | smpt[i] = le32_to_cpu(smpt[i]); |
3022 | 3079 | ||
3023 | sector_map = spi_nor_get_map_in_use(nor, smpt); | 3080 | sector_map = spi_nor_get_map_in_use(nor, smpt, smpt_header->length); |
3024 | if (!sector_map) { | 3081 | if (IS_ERR(sector_map)) { |
3025 | ret = -EINVAL; | 3082 | ret = PTR_ERR(sector_map); |
3026 | goto out; | 3083 | goto out; |
3027 | } | 3084 | } |
3028 | 3085 | ||
@@ -3125,7 +3182,7 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, | |||
3125 | if (err) | 3182 | if (err) |
3126 | goto exit; | 3183 | goto exit; |
3127 | 3184 | ||
3128 | /* Parse other parameter headers. */ | 3185 | /* Parse optional parameter tables. */ |
3129 | for (i = 0; i < header.nph; i++) { | 3186 | for (i = 0; i < header.nph; i++) { |
3130 | param_header = ¶m_headers[i]; | 3187 | param_header = ¶m_headers[i]; |
3131 | 3188 | ||
@@ -3138,8 +3195,17 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, | |||
3138 | break; | 3195 | break; |
3139 | } | 3196 | } |
3140 | 3197 | ||
3141 | if (err) | 3198 | if (err) { |
3142 | goto exit; | 3199 | dev_warn(dev, "Failed to parse optional parameter table: %04x\n", |
3200 | SFDP_PARAM_HEADER_ID(param_header)); | ||
3201 | /* | ||
3202 | * Let's not drop all information we extracted so far | ||
3203 | * if optional table parsers fail. In case of failing, | ||
3204 | * each optional parser is responsible to roll back to | ||
3205 | * the previously known spi_nor data. | ||
3206 | */ | ||
3207 | err = 0; | ||
3208 | } | ||
3143 | } | 3209 | } |
3144 | 3210 | ||
3145 | exit: | 3211 | exit: |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 49163570a63a..3b3f88ffab53 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -477,6 +477,34 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | |||
477 | } | 477 | } |
478 | EXPORT_SYMBOL_GPL(can_put_echo_skb); | 478 | EXPORT_SYMBOL_GPL(can_put_echo_skb); |
479 | 479 | ||
480 | struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr) | ||
481 | { | ||
482 | struct can_priv *priv = netdev_priv(dev); | ||
483 | struct sk_buff *skb = priv->echo_skb[idx]; | ||
484 | struct canfd_frame *cf; | ||
485 | |||
486 | if (idx >= priv->echo_skb_max) { | ||
487 | netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", | ||
488 | __func__, idx, priv->echo_skb_max); | ||
489 | return NULL; | ||
490 | } | ||
491 | |||
492 | if (!skb) { | ||
493 | netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n", | ||
494 | __func__, idx); | ||
495 | return NULL; | ||
496 | } | ||
497 | |||
498 | /* Using "struct canfd_frame::len" for the frame | ||
499 | * length is supported on both CAN and CANFD frames. | ||
500 | */ | ||
501 | cf = (struct canfd_frame *)skb->data; | ||
502 | *len_ptr = cf->len; | ||
503 | priv->echo_skb[idx] = NULL; | ||
504 | |||
505 | return skb; | ||
506 | } | ||
507 | |||
480 | /* | 508 | /* |
481 | * Get the skb from the stack and loop it back locally | 509 | * Get the skb from the stack and loop it back locally |
482 | * | 510 | * |
@@ -486,22 +514,16 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); | |||
486 | */ | 514 | */ |
487 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) | 515 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) |
488 | { | 516 | { |
489 | struct can_priv *priv = netdev_priv(dev); | 517 | struct sk_buff *skb; |
490 | 518 | u8 len; | |
491 | BUG_ON(idx >= priv->echo_skb_max); | ||
492 | |||
493 | if (priv->echo_skb[idx]) { | ||
494 | struct sk_buff *skb = priv->echo_skb[idx]; | ||
495 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
496 | u8 dlc = cf->can_dlc; | ||
497 | 519 | ||
498 | netif_rx(priv->echo_skb[idx]); | 520 | skb = __can_get_echo_skb(dev, idx, &len); |
499 | priv->echo_skb[idx] = NULL; | 521 | if (!skb) |
522 | return 0; | ||
500 | 523 | ||
501 | return dlc; | 524 | netif_rx(skb); |
502 | } | ||
503 | 525 | ||
504 | return 0; | 526 | return len; |
505 | } | 527 | } |
506 | EXPORT_SYMBOL_GPL(can_get_echo_skb); | 528 | EXPORT_SYMBOL_GPL(can_get_echo_skb); |
507 | 529 | ||
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 8e972ef08637..75ce11395ee8 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -135,13 +135,12 @@ | |||
135 | 135 | ||
136 | /* FLEXCAN interrupt flag register (IFLAG) bits */ | 136 | /* FLEXCAN interrupt flag register (IFLAG) bits */ |
137 | /* Errata ERR005829 step7: Reserve first valid MB */ | 137 | /* Errata ERR005829 step7: Reserve first valid MB */ |
138 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 | 138 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 |
139 | #define FLEXCAN_TX_MB_OFF_FIFO 9 | ||
140 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 | 139 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
141 | #define FLEXCAN_TX_MB_OFF_TIMESTAMP 1 | 140 | #define FLEXCAN_TX_MB 63 |
142 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1) | 141 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) |
143 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63 | 142 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1) |
144 | #define FLEXCAN_IFLAG_MB(x) BIT(x) | 143 | #define FLEXCAN_IFLAG_MB(x) BIT(x & 0x1f) |
145 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) | 144 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
146 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) | 145 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
147 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) | 146 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
@@ -259,9 +258,7 @@ struct flexcan_priv { | |||
259 | struct can_rx_offload offload; | 258 | struct can_rx_offload offload; |
260 | 259 | ||
261 | struct flexcan_regs __iomem *regs; | 260 | struct flexcan_regs __iomem *regs; |
262 | struct flexcan_mb __iomem *tx_mb; | ||
263 | struct flexcan_mb __iomem *tx_mb_reserved; | 261 | struct flexcan_mb __iomem *tx_mb_reserved; |
264 | u8 tx_mb_idx; | ||
265 | u32 reg_ctrl_default; | 262 | u32 reg_ctrl_default; |
266 | u32 reg_imask1_default; | 263 | u32 reg_imask1_default; |
267 | u32 reg_imask2_default; | 264 | u32 reg_imask2_default; |
@@ -515,6 +512,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev, | |||
515 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) | 512 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
516 | { | 513 | { |
517 | const struct flexcan_priv *priv = netdev_priv(dev); | 514 | const struct flexcan_priv *priv = netdev_priv(dev); |
515 | struct flexcan_regs __iomem *regs = priv->regs; | ||
518 | struct can_frame *cf = (struct can_frame *)skb->data; | 516 | struct can_frame *cf = (struct can_frame *)skb->data; |
519 | u32 can_id; | 517 | u32 can_id; |
520 | u32 data; | 518 | u32 data; |
@@ -537,17 +535,17 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de | |||
537 | 535 | ||
538 | if (cf->can_dlc > 0) { | 536 | if (cf->can_dlc > 0) { |
539 | data = be32_to_cpup((__be32 *)&cf->data[0]); | 537 | data = be32_to_cpup((__be32 *)&cf->data[0]); |
540 | priv->write(data, &priv->tx_mb->data[0]); | 538 | priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[0]); |
541 | } | 539 | } |
542 | if (cf->can_dlc > 4) { | 540 | if (cf->can_dlc > 4) { |
543 | data = be32_to_cpup((__be32 *)&cf->data[4]); | 541 | data = be32_to_cpup((__be32 *)&cf->data[4]); |
544 | priv->write(data, &priv->tx_mb->data[1]); | 542 | priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[1]); |
545 | } | 543 | } |
546 | 544 | ||
547 | can_put_echo_skb(skb, dev, 0); | 545 | can_put_echo_skb(skb, dev, 0); |
548 | 546 | ||
549 | priv->write(can_id, &priv->tx_mb->can_id); | 547 | priv->write(can_id, ®s->mb[FLEXCAN_TX_MB].can_id); |
550 | priv->write(ctrl, &priv->tx_mb->can_ctrl); | 548 | priv->write(ctrl, ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
551 | 549 | ||
552 | /* Errata ERR005829 step8: | 550 | /* Errata ERR005829 step8: |
553 | * Write twice INACTIVE(0x8) code to first MB. | 551 | * Write twice INACTIVE(0x8) code to first MB. |
@@ -563,9 +561,13 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de | |||
563 | static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) | 561 | static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) |
564 | { | 562 | { |
565 | struct flexcan_priv *priv = netdev_priv(dev); | 563 | struct flexcan_priv *priv = netdev_priv(dev); |
564 | struct flexcan_regs __iomem *regs = priv->regs; | ||
566 | struct sk_buff *skb; | 565 | struct sk_buff *skb; |
567 | struct can_frame *cf; | 566 | struct can_frame *cf; |
568 | bool rx_errors = false, tx_errors = false; | 567 | bool rx_errors = false, tx_errors = false; |
568 | u32 timestamp; | ||
569 | |||
570 | timestamp = priv->read(®s->timer) << 16; | ||
569 | 571 | ||
570 | skb = alloc_can_err_skb(dev, &cf); | 572 | skb = alloc_can_err_skb(dev, &cf); |
571 | if (unlikely(!skb)) | 573 | if (unlikely(!skb)) |
@@ -612,17 +614,21 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) | |||
612 | if (tx_errors) | 614 | if (tx_errors) |
613 | dev->stats.tx_errors++; | 615 | dev->stats.tx_errors++; |
614 | 616 | ||
615 | can_rx_offload_irq_queue_err_skb(&priv->offload, skb); | 617 | can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); |
616 | } | 618 | } |
617 | 619 | ||
618 | static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) | 620 | static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) |
619 | { | 621 | { |
620 | struct flexcan_priv *priv = netdev_priv(dev); | 622 | struct flexcan_priv *priv = netdev_priv(dev); |
623 | struct flexcan_regs __iomem *regs = priv->regs; | ||
621 | struct sk_buff *skb; | 624 | struct sk_buff *skb; |
622 | struct can_frame *cf; | 625 | struct can_frame *cf; |
623 | enum can_state new_state, rx_state, tx_state; | 626 | enum can_state new_state, rx_state, tx_state; |
624 | int flt; | 627 | int flt; |
625 | struct can_berr_counter bec; | 628 | struct can_berr_counter bec; |
629 | u32 timestamp; | ||
630 | |||
631 | timestamp = priv->read(®s->timer) << 16; | ||
626 | 632 | ||
627 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; | 633 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; |
628 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { | 634 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { |
@@ -652,7 +658,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) | |||
652 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) | 658 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) |
653 | can_bus_off(dev); | 659 | can_bus_off(dev); |
654 | 660 | ||
655 | can_rx_offload_irq_queue_err_skb(&priv->offload, skb); | 661 | can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); |
656 | } | 662 | } |
657 | 663 | ||
658 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) | 664 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) |
@@ -720,9 +726,14 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, | |||
720 | priv->write(BIT(n - 32), ®s->iflag2); | 726 | priv->write(BIT(n - 32), ®s->iflag2); |
721 | } else { | 727 | } else { |
722 | priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); | 728 | priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
723 | priv->read(®s->timer); | ||
724 | } | 729 | } |
725 | 730 | ||
731 | /* Read the Free Running Timer. It is optional but recommended | ||
732 | * to unlock Mailbox as soon as possible and make it available | ||
733 | * for reception. | ||
734 | */ | ||
735 | priv->read(®s->timer); | ||
736 | |||
726 | return 1; | 737 | return 1; |
727 | } | 738 | } |
728 | 739 | ||
@@ -732,9 +743,9 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) | |||
732 | struct flexcan_regs __iomem *regs = priv->regs; | 743 | struct flexcan_regs __iomem *regs = priv->regs; |
733 | u32 iflag1, iflag2; | 744 | u32 iflag1, iflag2; |
734 | 745 | ||
735 | iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default; | 746 | iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & |
736 | iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default & | 747 | ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); |
737 | ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | 748 | iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; |
738 | 749 | ||
739 | return (u64)iflag2 << 32 | iflag1; | 750 | return (u64)iflag2 << 32 | iflag1; |
740 | } | 751 | } |
@@ -746,11 +757,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
746 | struct flexcan_priv *priv = netdev_priv(dev); | 757 | struct flexcan_priv *priv = netdev_priv(dev); |
747 | struct flexcan_regs __iomem *regs = priv->regs; | 758 | struct flexcan_regs __iomem *regs = priv->regs; |
748 | irqreturn_t handled = IRQ_NONE; | 759 | irqreturn_t handled = IRQ_NONE; |
749 | u32 reg_iflag1, reg_esr; | 760 | u32 reg_iflag2, reg_esr; |
750 | enum can_state last_state = priv->can.state; | 761 | enum can_state last_state = priv->can.state; |
751 | 762 | ||
752 | reg_iflag1 = priv->read(®s->iflag1); | ||
753 | |||
754 | /* reception interrupt */ | 763 | /* reception interrupt */ |
755 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 764 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
756 | u64 reg_iflag; | 765 | u64 reg_iflag; |
@@ -764,6 +773,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
764 | break; | 773 | break; |
765 | } | 774 | } |
766 | } else { | 775 | } else { |
776 | u32 reg_iflag1; | ||
777 | |||
778 | reg_iflag1 = priv->read(®s->iflag1); | ||
767 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { | 779 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { |
768 | handled = IRQ_HANDLED; | 780 | handled = IRQ_HANDLED; |
769 | can_rx_offload_irq_offload_fifo(&priv->offload); | 781 | can_rx_offload_irq_offload_fifo(&priv->offload); |
@@ -779,17 +791,22 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
779 | } | 791 | } |
780 | } | 792 | } |
781 | 793 | ||
794 | reg_iflag2 = priv->read(®s->iflag2); | ||
795 | |||
782 | /* transmission complete interrupt */ | 796 | /* transmission complete interrupt */ |
783 | if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { | 797 | if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) { |
798 | u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl); | ||
799 | |||
784 | handled = IRQ_HANDLED; | 800 | handled = IRQ_HANDLED; |
785 | stats->tx_bytes += can_get_echo_skb(dev, 0); | 801 | stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, |
802 | 0, reg_ctrl << 16); | ||
786 | stats->tx_packets++; | 803 | stats->tx_packets++; |
787 | can_led_event(dev, CAN_LED_EVENT_TX); | 804 | can_led_event(dev, CAN_LED_EVENT_TX); |
788 | 805 | ||
789 | /* after sending a RTR frame MB is in RX mode */ | 806 | /* after sending a RTR frame MB is in RX mode */ |
790 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 807 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
791 | &priv->tx_mb->can_ctrl); | 808 | ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
792 | priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1); | 809 | priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), ®s->iflag2); |
793 | netif_wake_queue(dev); | 810 | netif_wake_queue(dev); |
794 | } | 811 | } |
795 | 812 | ||
@@ -931,15 +948,13 @@ static int flexcan_chip_start(struct net_device *dev) | |||
931 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); | 948 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
932 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | | 949 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | |
933 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | | 950 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | |
934 | FLEXCAN_MCR_IDAM_C; | 951 | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB); |
935 | 952 | ||
936 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 953 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
937 | reg_mcr &= ~FLEXCAN_MCR_FEN; | 954 | reg_mcr &= ~FLEXCAN_MCR_FEN; |
938 | reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last); | 955 | else |
939 | } else { | 956 | reg_mcr |= FLEXCAN_MCR_FEN; |
940 | reg_mcr |= FLEXCAN_MCR_FEN | | 957 | |
941 | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); | ||
942 | } | ||
943 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); | 958 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
944 | priv->write(reg_mcr, ®s->mcr); | 959 | priv->write(reg_mcr, ®s->mcr); |
945 | 960 | ||
@@ -982,16 +997,17 @@ static int flexcan_chip_start(struct net_device *dev) | |||
982 | priv->write(reg_ctrl2, ®s->ctrl2); | 997 | priv->write(reg_ctrl2, ®s->ctrl2); |
983 | } | 998 | } |
984 | 999 | ||
985 | /* clear and invalidate all mailboxes first */ | ||
986 | for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) { | ||
987 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, | ||
988 | ®s->mb[i].can_ctrl); | ||
989 | } | ||
990 | |||
991 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1000 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
992 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) | 1001 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { |
993 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, | 1002 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, |
994 | ®s->mb[i].can_ctrl); | 1003 | ®s->mb[i].can_ctrl); |
1004 | } | ||
1005 | } else { | ||
1006 | /* clear and invalidate unused mailboxes first */ | ||
1007 | for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) { | ||
1008 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, | ||
1009 | ®s->mb[i].can_ctrl); | ||
1010 | } | ||
995 | } | 1011 | } |
996 | 1012 | ||
997 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ | 1013 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ |
@@ -1000,7 +1016,7 @@ static int flexcan_chip_start(struct net_device *dev) | |||
1000 | 1016 | ||
1001 | /* mark TX mailbox as INACTIVE */ | 1017 | /* mark TX mailbox as INACTIVE */ |
1002 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 1018 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
1003 | &priv->tx_mb->can_ctrl); | 1019 | ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
1004 | 1020 | ||
1005 | /* acceptance mask/acceptance code (accept everything) */ | 1021 | /* acceptance mask/acceptance code (accept everything) */ |
1006 | priv->write(0x0, ®s->rxgmask); | 1022 | priv->write(0x0, ®s->rxgmask); |
@@ -1355,17 +1371,13 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1355 | priv->devtype_data = devtype_data; | 1371 | priv->devtype_data = devtype_data; |
1356 | priv->reg_xceiver = reg_xceiver; | 1372 | priv->reg_xceiver = reg_xceiver; |
1357 | 1373 | ||
1358 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1374 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
1359 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP; | ||
1360 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; | 1375 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; |
1361 | } else { | 1376 | else |
1362 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO; | ||
1363 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; | 1377 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; |
1364 | } | ||
1365 | priv->tx_mb = ®s->mb[priv->tx_mb_idx]; | ||
1366 | 1378 | ||
1367 | priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | 1379 | priv->reg_imask1_default = 0; |
1368 | priv->reg_imask2_default = 0; | 1380 | priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); |
1369 | 1381 | ||
1370 | priv->offload.mailbox_read = flexcan_mailbox_read; | 1382 | priv->offload.mailbox_read = flexcan_mailbox_read; |
1371 | 1383 | ||
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c index 11662f479e76..771a46083739 100644 --- a/drivers/net/can/rcar/rcar_can.c +++ b/drivers/net/can/rcar/rcar_can.c | |||
@@ -24,6 +24,9 @@ | |||
24 | 24 | ||
25 | #define RCAR_CAN_DRV_NAME "rcar_can" | 25 | #define RCAR_CAN_DRV_NAME "rcar_can" |
26 | 26 | ||
27 | #define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \ | ||
28 | BIT(CLKR_CLKEXT)) | ||
29 | |||
27 | /* Mailbox configuration: | 30 | /* Mailbox configuration: |
28 | * mailbox 60 - 63 - Rx FIFO mailboxes | 31 | * mailbox 60 - 63 - Rx FIFO mailboxes |
29 | * mailbox 56 - 59 - Tx FIFO mailboxes | 32 | * mailbox 56 - 59 - Tx FIFO mailboxes |
@@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev) | |||
789 | goto fail_clk; | 792 | goto fail_clk; |
790 | } | 793 | } |
791 | 794 | ||
792 | if (clock_select >= ARRAY_SIZE(clock_names)) { | 795 | if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) { |
793 | err = -EINVAL; | 796 | err = -EINVAL; |
794 | dev_err(&pdev->dev, "invalid CAN clock selected\n"); | 797 | dev_err(&pdev->dev, "invalid CAN clock selected\n"); |
795 | goto fail_clk; | 798 | goto fail_clk; |
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index c7d05027a7a0..2ce4fa8698c7 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c | |||
@@ -211,7 +211,54 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) | |||
211 | } | 211 | } |
212 | EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); | 212 | EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); |
213 | 213 | ||
214 | int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb) | 214 | int can_rx_offload_queue_sorted(struct can_rx_offload *offload, |
215 | struct sk_buff *skb, u32 timestamp) | ||
216 | { | ||
217 | struct can_rx_offload_cb *cb; | ||
218 | unsigned long flags; | ||
219 | |||
220 | if (skb_queue_len(&offload->skb_queue) > | ||
221 | offload->skb_queue_len_max) | ||
222 | return -ENOMEM; | ||
223 | |||
224 | cb = can_rx_offload_get_cb(skb); | ||
225 | cb->timestamp = timestamp; | ||
226 | |||
227 | spin_lock_irqsave(&offload->skb_queue.lock, flags); | ||
228 | __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare); | ||
229 | spin_unlock_irqrestore(&offload->skb_queue.lock, flags); | ||
230 | |||
231 | can_rx_offload_schedule(offload); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted); | ||
236 | |||
237 | unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, | ||
238 | unsigned int idx, u32 timestamp) | ||
239 | { | ||
240 | struct net_device *dev = offload->dev; | ||
241 | struct net_device_stats *stats = &dev->stats; | ||
242 | struct sk_buff *skb; | ||
243 | u8 len; | ||
244 | int err; | ||
245 | |||
246 | skb = __can_get_echo_skb(dev, idx, &len); | ||
247 | if (!skb) | ||
248 | return 0; | ||
249 | |||
250 | err = can_rx_offload_queue_sorted(offload, skb, timestamp); | ||
251 | if (err) { | ||
252 | stats->rx_errors++; | ||
253 | stats->tx_fifo_errors++; | ||
254 | } | ||
255 | |||
256 | return len; | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb); | ||
259 | |||
260 | int can_rx_offload_queue_tail(struct can_rx_offload *offload, | ||
261 | struct sk_buff *skb) | ||
215 | { | 262 | { |
216 | if (skb_queue_len(&offload->skb_queue) > | 263 | if (skb_queue_len(&offload->skb_queue) > |
217 | offload->skb_queue_len_max) | 264 | offload->skb_queue_len_max) |
@@ -222,7 +269,7 @@ int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_b | |||
222 | 269 | ||
223 | return 0; | 270 | return 0; |
224 | } | 271 | } |
225 | EXPORT_SYMBOL_GPL(can_rx_offload_irq_queue_err_skb); | 272 | EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail); |
226 | 273 | ||
227 | static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) | 274 | static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) |
228 | { | 275 | { |
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index 53e320c92a8b..ddaf46239e39 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c | |||
@@ -760,7 +760,7 @@ static int hi3110_open(struct net_device *net) | |||
760 | { | 760 | { |
761 | struct hi3110_priv *priv = netdev_priv(net); | 761 | struct hi3110_priv *priv = netdev_priv(net); |
762 | struct spi_device *spi = priv->spi; | 762 | struct spi_device *spi = priv->spi; |
763 | unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_RISING; | 763 | unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH; |
764 | int ret; | 764 | int ret; |
765 | 765 | ||
766 | ret = open_candev(net); | 766 | ret = open_candev(net); |
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index b939a4c10b84..c89c7d4900d7 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | |||
@@ -528,7 +528,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
528 | context = &priv->tx_contexts[i]; | 528 | context = &priv->tx_contexts[i]; |
529 | 529 | ||
530 | context->echo_index = i; | 530 | context->echo_index = i; |
531 | can_put_echo_skb(skb, netdev, context->echo_index); | ||
532 | ++priv->active_tx_contexts; | 531 | ++priv->active_tx_contexts; |
533 | if (priv->active_tx_contexts >= (int)dev->max_tx_urbs) | 532 | if (priv->active_tx_contexts >= (int)dev->max_tx_urbs) |
534 | netif_stop_queue(netdev); | 533 | netif_stop_queue(netdev); |
@@ -553,7 +552,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
553 | dev_kfree_skb(skb); | 552 | dev_kfree_skb(skb); |
554 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); | 553 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); |
555 | 554 | ||
556 | can_free_echo_skb(netdev, context->echo_index); | ||
557 | context->echo_index = dev->max_tx_urbs; | 555 | context->echo_index = dev->max_tx_urbs; |
558 | --priv->active_tx_contexts; | 556 | --priv->active_tx_contexts; |
559 | netif_wake_queue(netdev); | 557 | netif_wake_queue(netdev); |
@@ -564,6 +562,8 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
564 | 562 | ||
565 | context->priv = priv; | 563 | context->priv = priv; |
566 | 564 | ||
565 | can_put_echo_skb(skb, netdev, context->echo_index); | ||
566 | |||
567 | usb_fill_bulk_urb(urb, dev->udev, | 567 | usb_fill_bulk_urb(urb, dev->udev, |
568 | usb_sndbulkpipe(dev->udev, | 568 | usb_sndbulkpipe(dev->udev, |
569 | dev->bulk_out->bEndpointAddress), | 569 | dev->bulk_out->bEndpointAddress), |
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index c084bae5ec0a..5fc0be564274 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | |||
@@ -1019,6 +1019,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, | |||
1019 | new_state : CAN_STATE_ERROR_ACTIVE; | 1019 | new_state : CAN_STATE_ERROR_ACTIVE; |
1020 | 1020 | ||
1021 | can_change_state(netdev, cf, tx_state, rx_state); | 1021 | can_change_state(netdev, cf, tx_state, rx_state); |
1022 | |||
1023 | if (priv->can.restart_ms && | ||
1024 | old_state >= CAN_STATE_BUS_OFF && | ||
1025 | new_state < CAN_STATE_BUS_OFF) | ||
1026 | cf->can_id |= CAN_ERR_RESTARTED; | ||
1022 | } | 1027 | } |
1023 | 1028 | ||
1024 | if (new_state == CAN_STATE_BUS_OFF) { | 1029 | if (new_state == CAN_STATE_BUS_OFF) { |
@@ -1028,11 +1033,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, | |||
1028 | 1033 | ||
1029 | can_bus_off(netdev); | 1034 | can_bus_off(netdev); |
1030 | } | 1035 | } |
1031 | |||
1032 | if (priv->can.restart_ms && | ||
1033 | old_state >= CAN_STATE_BUS_OFF && | ||
1034 | new_state < CAN_STATE_BUS_OFF) | ||
1035 | cf->can_id |= CAN_ERR_RESTARTED; | ||
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | if (!skb) { | 1038 | if (!skb) { |
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c index 0678a38b1af4..f3d5bda012a1 100644 --- a/drivers/net/can/usb/ucan.c +++ b/drivers/net/can/usb/ucan.c | |||
@@ -35,10 +35,6 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
37 | 37 | ||
38 | #include <linux/can.h> | ||
39 | #include <linux/can/dev.h> | ||
40 | #include <linux/can/error.h> | ||
41 | |||
42 | #define UCAN_DRIVER_NAME "ucan" | 38 | #define UCAN_DRIVER_NAME "ucan" |
43 | #define UCAN_MAX_RX_URBS 8 | 39 | #define UCAN_MAX_RX_URBS 8 |
44 | /* the CAN controller needs a while to enable/disable the bus */ | 40 | /* the CAN controller needs a while to enable/disable the bus */ |
@@ -1575,11 +1571,8 @@ err_firmware_needs_update: | |||
1575 | /* disconnect the device */ | 1571 | /* disconnect the device */ |
1576 | static void ucan_disconnect(struct usb_interface *intf) | 1572 | static void ucan_disconnect(struct usb_interface *intf) |
1577 | { | 1573 | { |
1578 | struct usb_device *udev; | ||
1579 | struct ucan_priv *up = usb_get_intfdata(intf); | 1574 | struct ucan_priv *up = usb_get_intfdata(intf); |
1580 | 1575 | ||
1581 | udev = interface_to_usbdev(intf); | ||
1582 | |||
1583 | usb_set_intfdata(intf, NULL); | 1576 | usb_set_intfdata(intf, NULL); |
1584 | 1577 | ||
1585 | if (up) { | 1578 | if (up) { |
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 18956e7604a3..a70bb1bb90e7 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c | |||
@@ -1848,6 +1848,8 @@ static void ena_down(struct ena_adapter *adapter) | |||
1848 | rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); | 1848 | rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); |
1849 | if (rc) | 1849 | if (rc) |
1850 | dev_err(&adapter->pdev->dev, "Device reset failed\n"); | 1850 | dev_err(&adapter->pdev->dev, "Device reset failed\n"); |
1851 | /* stop submitting admin commands on a device that was reset */ | ||
1852 | ena_com_set_admin_running_state(adapter->ena_dev, false); | ||
1851 | } | 1853 | } |
1852 | 1854 | ||
1853 | ena_destroy_all_io_queues(adapter); | 1855 | ena_destroy_all_io_queues(adapter); |
@@ -1914,6 +1916,9 @@ static int ena_close(struct net_device *netdev) | |||
1914 | 1916 | ||
1915 | netif_dbg(adapter, ifdown, netdev, "%s\n", __func__); | 1917 | netif_dbg(adapter, ifdown, netdev, "%s\n", __func__); |
1916 | 1918 | ||
1919 | if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) | ||
1920 | return 0; | ||
1921 | |||
1917 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) | 1922 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) |
1918 | ena_down(adapter); | 1923 | ena_down(adapter); |
1919 | 1924 | ||
@@ -2613,9 +2618,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful) | |||
2613 | ena_down(adapter); | 2618 | ena_down(adapter); |
2614 | 2619 | ||
2615 | /* Stop the device from sending AENQ events (in case reset flag is set | 2620 | /* Stop the device from sending AENQ events (in case reset flag is set |
2616 | * and device is up, ena_close already reset the device | 2621 | * and device is up, ena_down() already reset the device. |
2617 | * In case the reset flag is set and the device is up, ena_down() | ||
2618 | * already perform the reset, so it can be skipped. | ||
2619 | */ | 2622 | */ |
2620 | if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) | 2623 | if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) |
2621 | ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); | 2624 | ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); |
@@ -2694,8 +2697,8 @@ err_device_destroy: | |||
2694 | ena_com_abort_admin_commands(ena_dev); | 2697 | ena_com_abort_admin_commands(ena_dev); |
2695 | ena_com_wait_for_abort_completion(ena_dev); | 2698 | ena_com_wait_for_abort_completion(ena_dev); |
2696 | ena_com_admin_destroy(ena_dev); | 2699 | ena_com_admin_destroy(ena_dev); |
2697 | ena_com_mmio_reg_read_request_destroy(ena_dev); | ||
2698 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_DRIVER_INVALID_STATE); | 2700 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_DRIVER_INVALID_STATE); |
2701 | ena_com_mmio_reg_read_request_destroy(ena_dev); | ||
2699 | err: | 2702 | err: |
2700 | clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); | 2703 | clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); |
2701 | clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags); | 2704 | clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags); |
@@ -3452,6 +3455,8 @@ err_rss: | |||
3452 | ena_com_rss_destroy(ena_dev); | 3455 | ena_com_rss_destroy(ena_dev); |
3453 | err_free_msix: | 3456 | err_free_msix: |
3454 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR); | 3457 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR); |
3458 | /* stop submitting admin commands on a device that was reset */ | ||
3459 | ena_com_set_admin_running_state(ena_dev, false); | ||
3455 | ena_free_mgmnt_irq(adapter); | 3460 | ena_free_mgmnt_irq(adapter); |
3456 | ena_disable_msix(adapter); | 3461 | ena_disable_msix(adapter); |
3457 | err_worker_destroy: | 3462 | err_worker_destroy: |
@@ -3498,18 +3503,12 @@ static void ena_remove(struct pci_dev *pdev) | |||
3498 | 3503 | ||
3499 | cancel_work_sync(&adapter->reset_task); | 3504 | cancel_work_sync(&adapter->reset_task); |
3500 | 3505 | ||
3501 | unregister_netdev(netdev); | ||
3502 | |||
3503 | /* If the device is running then we want to make sure the device will be | ||
3504 | * reset to make sure no more events will be issued by the device. | ||
3505 | */ | ||
3506 | if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) | ||
3507 | set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); | ||
3508 | |||
3509 | rtnl_lock(); | 3506 | rtnl_lock(); |
3510 | ena_destroy_device(adapter, true); | 3507 | ena_destroy_device(adapter, true); |
3511 | rtnl_unlock(); | 3508 | rtnl_unlock(); |
3512 | 3509 | ||
3510 | unregister_netdev(netdev); | ||
3511 | |||
3513 | free_netdev(netdev); | 3512 | free_netdev(netdev); |
3514 | 3513 | ||
3515 | ena_com_rss_destroy(ena_dev); | 3514 | ena_com_rss_destroy(ena_dev); |
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h index 521873642339..dc8b6173d8d8 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.h +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | #define DRV_MODULE_VER_MAJOR 2 | 46 | #define DRV_MODULE_VER_MAJOR 2 |
47 | #define DRV_MODULE_VER_MINOR 0 | 47 | #define DRV_MODULE_VER_MINOR 0 |
48 | #define DRV_MODULE_VER_SUBMINOR 1 | 48 | #define DRV_MODULE_VER_SUBMINOR 2 |
49 | 49 | ||
50 | #define DRV_MODULE_NAME "ena" | 50 | #define DRV_MODULE_NAME "ena" |
51 | #ifndef DRV_MODULE_VERSION | 51 | #ifndef DRV_MODULE_VERSION |
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index b4fc0ed5bce8..9d4899826823 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c | |||
@@ -1419,7 +1419,7 @@ static int sparc_lance_probe_one(struct platform_device *op, | |||
1419 | 1419 | ||
1420 | prop = of_get_property(nd, "tpe-link-test?", NULL); | 1420 | prop = of_get_property(nd, "tpe-link-test?", NULL); |
1421 | if (!prop) | 1421 | if (!prop) |
1422 | goto no_link_test; | 1422 | goto node_put; |
1423 | 1423 | ||
1424 | if (strcmp(prop, "true")) { | 1424 | if (strcmp(prop, "true")) { |
1425 | printk(KERN_NOTICE "SunLance: warning: overriding option " | 1425 | printk(KERN_NOTICE "SunLance: warning: overriding option " |
@@ -1428,6 +1428,8 @@ static int sparc_lance_probe_one(struct platform_device *op, | |||
1428 | "to ecd@skynet.be\n"); | 1428 | "to ecd@skynet.be\n"); |
1429 | auxio_set_lte(AUXIO_LTE_ON); | 1429 | auxio_set_lte(AUXIO_LTE_ON); |
1430 | } | 1430 | } |
1431 | node_put: | ||
1432 | of_node_put(nd); | ||
1431 | no_link_test: | 1433 | no_link_test: |
1432 | lp->auto_select = 1; | 1434 | lp->auto_select = 1; |
1433 | lp->tpe = 0; | 1435 | lp->tpe = 0; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index be1506169076..0de487a8f0eb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -2191,6 +2191,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, | |||
2191 | #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ | 2191 | #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ |
2192 | E1HVN_MAX) | 2192 | E1HVN_MAX) |
2193 | 2193 | ||
2194 | /* Following is the DMAE channel number allocation for the clients. | ||
2195 | * MFW: OCBB/OCSD implementations use DMAE channels 14/15 respectively. | ||
2196 | * Driver: 0-3 and 8-11 (for PF dmae operations) | ||
2197 | * 4 and 12 (for stats requests) | ||
2198 | */ | ||
2199 | #define BNX2X_FW_DMAE_C 13 /* Channel for FW DMAE operations */ | ||
2200 | |||
2194 | /* PCIE link and speed */ | 2201 | /* PCIE link and speed */ |
2195 | #define PCICFG_LINK_WIDTH 0x1f00000 | 2202 | #define PCICFG_LINK_WIDTH 0x1f00000 |
2196 | #define PCICFG_LINK_WIDTH_SHIFT 20 | 2203 | #define PCICFG_LINK_WIDTH_SHIFT 20 |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 3f4d2c8da21a..a9eaaf3e73a4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -6149,6 +6149,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, | |||
6149 | rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); | 6149 | rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); |
6150 | rdata->path_id = BP_PATH(bp); | 6150 | rdata->path_id = BP_PATH(bp); |
6151 | rdata->network_cos_mode = start_params->network_cos_mode; | 6151 | rdata->network_cos_mode = start_params->network_cos_mode; |
6152 | rdata->dmae_cmd_id = BNX2X_FW_DMAE_C; | ||
6152 | 6153 | ||
6153 | rdata->vxlan_dst_port = cpu_to_le16(start_params->vxlan_dst_port); | 6154 | rdata->vxlan_dst_port = cpu_to_le16(start_params->vxlan_dst_port); |
6154 | rdata->geneve_dst_port = cpu_to_le16(start_params->geneve_dst_port); | 6155 | rdata->geneve_dst_port = cpu_to_le16(start_params->geneve_dst_port); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index dd85d790f638..d4c300117529 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -1675,7 +1675,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, | |||
1675 | } else { | 1675 | } else { |
1676 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { | 1676 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { |
1677 | if (dev->features & NETIF_F_RXCSUM) | 1677 | if (dev->features & NETIF_F_RXCSUM) |
1678 | cpr->rx_l4_csum_errors++; | 1678 | bnapi->cp_ring.rx_l4_csum_errors++; |
1679 | } | 1679 | } |
1680 | } | 1680 | } |
1681 | 1681 | ||
@@ -8714,6 +8714,26 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features) | |||
8714 | return rc; | 8714 | return rc; |
8715 | } | 8715 | } |
8716 | 8716 | ||
8717 | static int bnxt_dbg_hwrm_ring_info_get(struct bnxt *bp, u8 ring_type, | ||
8718 | u32 ring_id, u32 *prod, u32 *cons) | ||
8719 | { | ||
8720 | struct hwrm_dbg_ring_info_get_output *resp = bp->hwrm_cmd_resp_addr; | ||
8721 | struct hwrm_dbg_ring_info_get_input req = {0}; | ||
8722 | int rc; | ||
8723 | |||
8724 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_DBG_RING_INFO_GET, -1, -1); | ||
8725 | req.ring_type = ring_type; | ||
8726 | req.fw_ring_id = cpu_to_le32(ring_id); | ||
8727 | mutex_lock(&bp->hwrm_cmd_lock); | ||
8728 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | ||
8729 | if (!rc) { | ||
8730 | *prod = le32_to_cpu(resp->producer_index); | ||
8731 | *cons = le32_to_cpu(resp->consumer_index); | ||
8732 | } | ||
8733 | mutex_unlock(&bp->hwrm_cmd_lock); | ||
8734 | return rc; | ||
8735 | } | ||
8736 | |||
8717 | static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi) | 8737 | static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi) |
8718 | { | 8738 | { |
8719 | struct bnxt_tx_ring_info *txr = bnapi->tx_ring; | 8739 | struct bnxt_tx_ring_info *txr = bnapi->tx_ring; |
@@ -8821,6 +8841,11 @@ static void bnxt_timer(struct timer_list *t) | |||
8821 | bnxt_queue_sp_work(bp); | 8841 | bnxt_queue_sp_work(bp); |
8822 | } | 8842 | } |
8823 | } | 8843 | } |
8844 | |||
8845 | if ((bp->flags & BNXT_FLAG_CHIP_P5) && netif_carrier_ok(dev)) { | ||
8846 | set_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event); | ||
8847 | bnxt_queue_sp_work(bp); | ||
8848 | } | ||
8824 | bnxt_restart_timer: | 8849 | bnxt_restart_timer: |
8825 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 8850 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
8826 | } | 8851 | } |
@@ -8851,6 +8876,44 @@ static void bnxt_reset(struct bnxt *bp, bool silent) | |||
8851 | bnxt_rtnl_unlock_sp(bp); | 8876 | bnxt_rtnl_unlock_sp(bp); |
8852 | } | 8877 | } |
8853 | 8878 | ||
8879 | static void bnxt_chk_missed_irq(struct bnxt *bp) | ||
8880 | { | ||
8881 | int i; | ||
8882 | |||
8883 | if (!(bp->flags & BNXT_FLAG_CHIP_P5)) | ||
8884 | return; | ||
8885 | |||
8886 | for (i = 0; i < bp->cp_nr_rings; i++) { | ||
8887 | struct bnxt_napi *bnapi = bp->bnapi[i]; | ||
8888 | struct bnxt_cp_ring_info *cpr; | ||
8889 | u32 fw_ring_id; | ||
8890 | int j; | ||
8891 | |||
8892 | if (!bnapi) | ||
8893 | continue; | ||
8894 | |||
8895 | cpr = &bnapi->cp_ring; | ||
8896 | for (j = 0; j < 2; j++) { | ||
8897 | struct bnxt_cp_ring_info *cpr2 = cpr->cp_ring_arr[j]; | ||
8898 | u32 val[2]; | ||
8899 | |||
8900 | if (!cpr2 || cpr2->has_more_work || | ||
8901 | !bnxt_has_work(bp, cpr2)) | ||
8902 | continue; | ||
8903 | |||
8904 | if (cpr2->cp_raw_cons != cpr2->last_cp_raw_cons) { | ||
8905 | cpr2->last_cp_raw_cons = cpr2->cp_raw_cons; | ||
8906 | continue; | ||
8907 | } | ||
8908 | fw_ring_id = cpr2->cp_ring_struct.fw_ring_id; | ||
8909 | bnxt_dbg_hwrm_ring_info_get(bp, | ||
8910 | DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL, | ||
8911 | fw_ring_id, &val[0], &val[1]); | ||
8912 | cpr->missed_irqs++; | ||
8913 | } | ||
8914 | } | ||
8915 | } | ||
8916 | |||
8854 | static void bnxt_cfg_ntp_filters(struct bnxt *); | 8917 | static void bnxt_cfg_ntp_filters(struct bnxt *); |
8855 | 8918 | ||
8856 | static void bnxt_sp_task(struct work_struct *work) | 8919 | static void bnxt_sp_task(struct work_struct *work) |
@@ -8930,6 +8993,9 @@ static void bnxt_sp_task(struct work_struct *work) | |||
8930 | if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event)) | 8993 | if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event)) |
8931 | bnxt_tc_flow_stats_work(bp); | 8994 | bnxt_tc_flow_stats_work(bp); |
8932 | 8995 | ||
8996 | if (test_and_clear_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event)) | ||
8997 | bnxt_chk_missed_irq(bp); | ||
8998 | |||
8933 | /* These functions below will clear BNXT_STATE_IN_SP_TASK. They | 8999 | /* These functions below will clear BNXT_STATE_IN_SP_TASK. They |
8934 | * must be the last functions to be called before exiting. | 9000 | * must be the last functions to be called before exiting. |
8935 | */ | 9001 | */ |
@@ -10087,6 +10153,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10087 | } | 10153 | } |
10088 | 10154 | ||
10089 | bnxt_hwrm_func_qcfg(bp); | 10155 | bnxt_hwrm_func_qcfg(bp); |
10156 | bnxt_hwrm_vnic_qcaps(bp); | ||
10090 | bnxt_hwrm_port_led_qcaps(bp); | 10157 | bnxt_hwrm_port_led_qcaps(bp); |
10091 | bnxt_ethtool_init(bp); | 10158 | bnxt_ethtool_init(bp); |
10092 | bnxt_dcb_init(bp); | 10159 | bnxt_dcb_init(bp); |
@@ -10120,7 +10187,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10120 | VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6; | 10187 | VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6; |
10121 | } | 10188 | } |
10122 | 10189 | ||
10123 | bnxt_hwrm_vnic_qcaps(bp); | ||
10124 | if (bnxt_rfs_supported(bp)) { | 10190 | if (bnxt_rfs_supported(bp)) { |
10125 | dev->hw_features |= NETIF_F_NTUPLE; | 10191 | dev->hw_features |= NETIF_F_NTUPLE; |
10126 | if (bnxt_rfs_capable(bp)) { | 10192 | if (bnxt_rfs_capable(bp)) { |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 498b373c992d..9e99d4ab3e06 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
@@ -798,6 +798,8 @@ struct bnxt_cp_ring_info { | |||
798 | u8 had_work_done:1; | 798 | u8 had_work_done:1; |
799 | u8 has_more_work:1; | 799 | u8 has_more_work:1; |
800 | 800 | ||
801 | u32 last_cp_raw_cons; | ||
802 | |||
801 | struct bnxt_coal rx_ring_coal; | 803 | struct bnxt_coal rx_ring_coal; |
802 | u64 rx_packets; | 804 | u64 rx_packets; |
803 | u64 rx_bytes; | 805 | u64 rx_bytes; |
@@ -816,6 +818,7 @@ struct bnxt_cp_ring_info { | |||
816 | dma_addr_t hw_stats_map; | 818 | dma_addr_t hw_stats_map; |
817 | u32 hw_stats_ctx_id; | 819 | u32 hw_stats_ctx_id; |
818 | u64 rx_l4_csum_errors; | 820 | u64 rx_l4_csum_errors; |
821 | u64 missed_irqs; | ||
819 | 822 | ||
820 | struct bnxt_ring_struct cp_ring_struct; | 823 | struct bnxt_ring_struct cp_ring_struct; |
821 | 824 | ||
@@ -1527,6 +1530,7 @@ struct bnxt { | |||
1527 | #define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 | 1530 | #define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 |
1528 | #define BNXT_FLOW_STATS_SP_EVENT 15 | 1531 | #define BNXT_FLOW_STATS_SP_EVENT 15 |
1529 | #define BNXT_UPDATE_PHY_SP_EVENT 16 | 1532 | #define BNXT_UPDATE_PHY_SP_EVENT 16 |
1533 | #define BNXT_RING_COAL_NOW_SP_EVENT 17 | ||
1530 | 1534 | ||
1531 | struct bnxt_hw_resc hw_resc; | 1535 | struct bnxt_hw_resc hw_resc; |
1532 | struct bnxt_pf_info pf; | 1536 | struct bnxt_pf_info pf; |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 48078564f025..6cc69a58478a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | |||
@@ -137,7 +137,7 @@ reset_coalesce: | |||
137 | return rc; | 137 | return rc; |
138 | } | 138 | } |
139 | 139 | ||
140 | #define BNXT_NUM_STATS 21 | 140 | #define BNXT_NUM_STATS 22 |
141 | 141 | ||
142 | #define BNXT_RX_STATS_ENTRY(counter) \ | 142 | #define BNXT_RX_STATS_ENTRY(counter) \ |
143 | { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) } | 143 | { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) } |
@@ -384,6 +384,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev, | |||
384 | for (k = 0; k < stat_fields; j++, k++) | 384 | for (k = 0; k < stat_fields; j++, k++) |
385 | buf[j] = le64_to_cpu(hw_stats[k]); | 385 | buf[j] = le64_to_cpu(hw_stats[k]); |
386 | buf[j++] = cpr->rx_l4_csum_errors; | 386 | buf[j++] = cpr->rx_l4_csum_errors; |
387 | buf[j++] = cpr->missed_irqs; | ||
387 | 388 | ||
388 | bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter += | 389 | bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter += |
389 | le64_to_cpu(cpr->hw_stats->rx_discard_pkts); | 390 | le64_to_cpu(cpr->hw_stats->rx_discard_pkts); |
@@ -468,6 +469,8 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf) | |||
468 | buf += ETH_GSTRING_LEN; | 469 | buf += ETH_GSTRING_LEN; |
469 | sprintf(buf, "[%d]: rx_l4_csum_errors", i); | 470 | sprintf(buf, "[%d]: rx_l4_csum_errors", i); |
470 | buf += ETH_GSTRING_LEN; | 471 | buf += ETH_GSTRING_LEN; |
472 | sprintf(buf, "[%d]: missed_irqs", i); | ||
473 | buf += ETH_GSTRING_LEN; | ||
471 | } | 474 | } |
472 | for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) { | 475 | for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) { |
473 | strcpy(buf, bnxt_sw_func_stats[i].string); | 476 | strcpy(buf, bnxt_sw_func_stats[i].string); |
@@ -2942,8 +2945,8 @@ bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record, | |||
2942 | record->asic_state = 0; | 2945 | record->asic_state = 0; |
2943 | strlcpy(record->system_name, utsname()->nodename, | 2946 | strlcpy(record->system_name, utsname()->nodename, |
2944 | sizeof(record->system_name)); | 2947 | sizeof(record->system_name)); |
2945 | record->year = cpu_to_le16(tm.tm_year); | 2948 | record->year = cpu_to_le16(tm.tm_year + 1900); |
2946 | record->month = cpu_to_le16(tm.tm_mon); | 2949 | record->month = cpu_to_le16(tm.tm_mon + 1); |
2947 | record->day = cpu_to_le16(tm.tm_mday); | 2950 | record->day = cpu_to_le16(tm.tm_mday); |
2948 | record->hour = cpu_to_le16(tm.tm_hour); | 2951 | record->hour = cpu_to_le16(tm.tm_hour); |
2949 | record->minute = cpu_to_le16(tm.tm_min); | 2952 | record->minute = cpu_to_le16(tm.tm_min); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index beee61292d5e..b59b382d34f9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | |||
@@ -43,6 +43,9 @@ static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id, | |||
43 | if (ulp_id == BNXT_ROCE_ULP) { | 43 | if (ulp_id == BNXT_ROCE_ULP) { |
44 | unsigned int max_stat_ctxs; | 44 | unsigned int max_stat_ctxs; |
45 | 45 | ||
46 | if (bp->flags & BNXT_FLAG_CHIP_P5) | ||
47 | return -EOPNOTSUPP; | ||
48 | |||
46 | max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); | 49 | max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); |
47 | if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || | 50 | if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || |
48 | bp->num_stat_ctxs == max_stat_ctxs) | 51 | bp->num_stat_ctxs == max_stat_ctxs) |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 89295306f161..432c3b867084 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -12422,6 +12422,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
12422 | { | 12422 | { |
12423 | struct tg3 *tp = netdev_priv(dev); | 12423 | struct tg3 *tp = netdev_priv(dev); |
12424 | int i, irq_sync = 0, err = 0; | 12424 | int i, irq_sync = 0, err = 0; |
12425 | bool reset_phy = false; | ||
12425 | 12426 | ||
12426 | if ((ering->rx_pending > tp->rx_std_ring_mask) || | 12427 | if ((ering->rx_pending > tp->rx_std_ring_mask) || |
12427 | (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || | 12428 | (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || |
@@ -12453,7 +12454,13 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
12453 | 12454 | ||
12454 | if (netif_running(dev)) { | 12455 | if (netif_running(dev)) { |
12455 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 12456 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
12456 | err = tg3_restart_hw(tp, false); | 12457 | /* Reset PHY to avoid PHY lock up */ |
12458 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || | ||
12459 | tg3_asic_rev(tp) == ASIC_REV_5719 || | ||
12460 | tg3_asic_rev(tp) == ASIC_REV_5720) | ||
12461 | reset_phy = true; | ||
12462 | |||
12463 | err = tg3_restart_hw(tp, reset_phy); | ||
12457 | if (!err) | 12464 | if (!err) |
12458 | tg3_netif_start(tp); | 12465 | tg3_netif_start(tp); |
12459 | } | 12466 | } |
@@ -12487,6 +12494,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
12487 | { | 12494 | { |
12488 | struct tg3 *tp = netdev_priv(dev); | 12495 | struct tg3 *tp = netdev_priv(dev); |
12489 | int err = 0; | 12496 | int err = 0; |
12497 | bool reset_phy = false; | ||
12490 | 12498 | ||
12491 | if (tp->link_config.autoneg == AUTONEG_ENABLE) | 12499 | if (tp->link_config.autoneg == AUTONEG_ENABLE) |
12492 | tg3_warn_mgmt_link_flap(tp); | 12500 | tg3_warn_mgmt_link_flap(tp); |
@@ -12556,7 +12564,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
12556 | 12564 | ||
12557 | if (netif_running(dev)) { | 12565 | if (netif_running(dev)) { |
12558 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 12566 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
12559 | err = tg3_restart_hw(tp, false); | 12567 | /* Reset PHY to avoid PHY lock up */ |
12568 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || | ||
12569 | tg3_asic_rev(tp) == ASIC_REV_5719 || | ||
12570 | tg3_asic_rev(tp) == ASIC_REV_5720) | ||
12571 | reset_phy = true; | ||
12572 | |||
12573 | err = tg3_restart_hw(tp, reset_phy); | ||
12560 | if (!err) | 12574 | if (!err) |
12561 | tg3_netif_start(tp); | 12575 | tg3_netif_start(tp); |
12562 | } | 12576 | } |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 768f584f8392..88f8a8fa93cd 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
@@ -1784,6 +1784,7 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) | |||
1784 | bool if_up = netif_running(nic->netdev); | 1784 | bool if_up = netif_running(nic->netdev); |
1785 | struct bpf_prog *old_prog; | 1785 | struct bpf_prog *old_prog; |
1786 | bool bpf_attached = false; | 1786 | bool bpf_attached = false; |
1787 | int ret = 0; | ||
1787 | 1788 | ||
1788 | /* For now just support only the usual MTU sized frames */ | 1789 | /* For now just support only the usual MTU sized frames */ |
1789 | if (prog && (dev->mtu > 1500)) { | 1790 | if (prog && (dev->mtu > 1500)) { |
@@ -1817,8 +1818,12 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) | |||
1817 | if (nic->xdp_prog) { | 1818 | if (nic->xdp_prog) { |
1818 | /* Attach BPF program */ | 1819 | /* Attach BPF program */ |
1819 | nic->xdp_prog = bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1); | 1820 | nic->xdp_prog = bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1); |
1820 | if (!IS_ERR(nic->xdp_prog)) | 1821 | if (!IS_ERR(nic->xdp_prog)) { |
1821 | bpf_attached = true; | 1822 | bpf_attached = true; |
1823 | } else { | ||
1824 | ret = PTR_ERR(nic->xdp_prog); | ||
1825 | nic->xdp_prog = NULL; | ||
1826 | } | ||
1822 | } | 1827 | } |
1823 | 1828 | ||
1824 | /* Calculate Tx queues needed for XDP and network stack */ | 1829 | /* Calculate Tx queues needed for XDP and network stack */ |
@@ -1830,7 +1835,7 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) | |||
1830 | netif_trans_update(nic->netdev); | 1835 | netif_trans_update(nic->netdev); |
1831 | } | 1836 | } |
1832 | 1837 | ||
1833 | return 0; | 1838 | return ret; |
1834 | } | 1839 | } |
1835 | 1840 | ||
1836 | static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) | 1841 | static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index 187a249ff2d1..fcaf18fa3904 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c | |||
@@ -585,10 +585,12 @@ static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) | |||
585 | if (!sq->dmem.base) | 585 | if (!sq->dmem.base) |
586 | return; | 586 | return; |
587 | 587 | ||
588 | if (sq->tso_hdrs) | 588 | if (sq->tso_hdrs) { |
589 | dma_free_coherent(&nic->pdev->dev, | 589 | dma_free_coherent(&nic->pdev->dev, |
590 | sq->dmem.q_len * TSO_HEADER_SIZE, | 590 | sq->dmem.q_len * TSO_HEADER_SIZE, |
591 | sq->tso_hdrs, sq->tso_hdrs_phys); | 591 | sq->tso_hdrs, sq->tso_hdrs_phys); |
592 | sq->tso_hdrs = NULL; | ||
593 | } | ||
592 | 594 | ||
593 | /* Free pending skbs in the queue */ | 595 | /* Free pending skbs in the queue */ |
594 | smp_rmb(); | 596 | smp_rmb(); |
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig index 75c1c5ed2387..e2cdfa75673f 100644 --- a/drivers/net/ethernet/chelsio/Kconfig +++ b/drivers/net/ethernet/chelsio/Kconfig | |||
@@ -67,7 +67,6 @@ config CHELSIO_T3 | |||
67 | config CHELSIO_T4 | 67 | config CHELSIO_T4 |
68 | tristate "Chelsio Communications T4/T5/T6 Ethernet support" | 68 | tristate "Chelsio Communications T4/T5/T6 Ethernet support" |
69 | depends on PCI && (IPV6 || IPV6=n) | 69 | depends on PCI && (IPV6 || IPV6=n) |
70 | depends on THERMAL || !THERMAL | ||
71 | select FW_LOADER | 70 | select FW_LOADER |
72 | select MDIO | 71 | select MDIO |
73 | select ZLIB_DEFLATE | 72 | select ZLIB_DEFLATE |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile index 78e5d17a1d5f..91d8a885deba 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/Makefile +++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile | |||
@@ -12,6 +12,4 @@ cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o | |||
12 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o | 12 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o |
13 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o | 13 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o |
14 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o | 14 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o |
15 | ifdef CONFIG_THERMAL | 15 | cxgb4-$(CONFIG_THERMAL) += cxgb4_thermal.o |
16 | cxgb4-objs += cxgb4_thermal.o | ||
17 | endif | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 05a46926016a..d49db46254cd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -5863,7 +5863,7 @@ fw_attach_fail: | |||
5863 | if (!is_t4(adapter->params.chip)) | 5863 | if (!is_t4(adapter->params.chip)) |
5864 | cxgb4_ptp_init(adapter); | 5864 | cxgb4_ptp_init(adapter); |
5865 | 5865 | ||
5866 | if (IS_ENABLED(CONFIG_THERMAL) && | 5866 | if (IS_REACHABLE(CONFIG_THERMAL) && |
5867 | !is_t4(adapter->params.chip) && (adapter->flags & FW_OK)) | 5867 | !is_t4(adapter->params.chip) && (adapter->flags & FW_OK)) |
5868 | cxgb4_thermal_init(adapter); | 5868 | cxgb4_thermal_init(adapter); |
5869 | 5869 | ||
@@ -5932,7 +5932,7 @@ static void remove_one(struct pci_dev *pdev) | |||
5932 | 5932 | ||
5933 | if (!is_t4(adapter->params.chip)) | 5933 | if (!is_t4(adapter->params.chip)) |
5934 | cxgb4_ptp_stop(adapter); | 5934 | cxgb4_ptp_stop(adapter); |
5935 | if (IS_ENABLED(CONFIG_THERMAL)) | 5935 | if (IS_REACHABLE(CONFIG_THERMAL)) |
5936 | cxgb4_thermal_remove(adapter); | 5936 | cxgb4_thermal_remove(adapter); |
5937 | 5937 | ||
5938 | /* If we allocated filters, free up state associated with any | 5938 | /* If we allocated filters, free up state associated with any |
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index ceec467f590d..949103db8a8a 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c | |||
@@ -660,7 +660,7 @@ static void gmac_clean_txq(struct net_device *netdev, struct gmac_txq *txq, | |||
660 | 660 | ||
661 | u64_stats_update_begin(&port->tx_stats_syncp); | 661 | u64_stats_update_begin(&port->tx_stats_syncp); |
662 | port->tx_frag_stats[nfrags]++; | 662 | port->tx_frag_stats[nfrags]++; |
663 | u64_stats_update_end(&port->ir_stats_syncp); | 663 | u64_stats_update_end(&port->tx_stats_syncp); |
664 | } | 664 | } |
665 | } | 665 | } |
666 | 666 | ||
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c index 570caeb8ee9e..084f24daf2b5 100644 --- a/drivers/net/ethernet/faraday/ftmac100.c +++ b/drivers/net/ethernet/faraday/ftmac100.c | |||
@@ -872,11 +872,10 @@ static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) | |||
872 | struct net_device *netdev = dev_id; | 872 | struct net_device *netdev = dev_id; |
873 | struct ftmac100 *priv = netdev_priv(netdev); | 873 | struct ftmac100 *priv = netdev_priv(netdev); |
874 | 874 | ||
875 | if (likely(netif_running(netdev))) { | 875 | /* Disable interrupts for polling */ |
876 | /* Disable interrupts for polling */ | 876 | ftmac100_disable_all_int(priv); |
877 | ftmac100_disable_all_int(priv); | 877 | if (likely(netif_running(netdev))) |
878 | napi_schedule(&priv->napi); | 878 | napi_schedule(&priv->napi); |
879 | } | ||
880 | 879 | ||
881 | return IRQ_HANDLED; | 880 | return IRQ_HANDLED; |
882 | } | 881 | } |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index c9d5d0a7fbf1..c0203a0d5e3b 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c | |||
@@ -485,8 +485,8 @@ static void release_rx_pools(struct ibmvnic_adapter *adapter) | |||
485 | 485 | ||
486 | for (j = 0; j < rx_pool->size; j++) { | 486 | for (j = 0; j < rx_pool->size; j++) { |
487 | if (rx_pool->rx_buff[j].skb) { | 487 | if (rx_pool->rx_buff[j].skb) { |
488 | dev_kfree_skb_any(rx_pool->rx_buff[i].skb); | 488 | dev_kfree_skb_any(rx_pool->rx_buff[j].skb); |
489 | rx_pool->rx_buff[i].skb = NULL; | 489 | rx_pool->rx_buff[j].skb = NULL; |
490 | } | 490 | } |
491 | } | 491 | } |
492 | 492 | ||
@@ -1103,20 +1103,15 @@ static int ibmvnic_open(struct net_device *netdev) | |||
1103 | return 0; | 1103 | return 0; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | mutex_lock(&adapter->reset_lock); | ||
1107 | |||
1108 | if (adapter->state != VNIC_CLOSED) { | 1106 | if (adapter->state != VNIC_CLOSED) { |
1109 | rc = ibmvnic_login(netdev); | 1107 | rc = ibmvnic_login(netdev); |
1110 | if (rc) { | 1108 | if (rc) |
1111 | mutex_unlock(&adapter->reset_lock); | ||
1112 | return rc; | 1109 | return rc; |
1113 | } | ||
1114 | 1110 | ||
1115 | rc = init_resources(adapter); | 1111 | rc = init_resources(adapter); |
1116 | if (rc) { | 1112 | if (rc) { |
1117 | netdev_err(netdev, "failed to initialize resources\n"); | 1113 | netdev_err(netdev, "failed to initialize resources\n"); |
1118 | release_resources(adapter); | 1114 | release_resources(adapter); |
1119 | mutex_unlock(&adapter->reset_lock); | ||
1120 | return rc; | 1115 | return rc; |
1121 | } | 1116 | } |
1122 | } | 1117 | } |
@@ -1124,8 +1119,6 @@ static int ibmvnic_open(struct net_device *netdev) | |||
1124 | rc = __ibmvnic_open(netdev); | 1119 | rc = __ibmvnic_open(netdev); |
1125 | netif_carrier_on(netdev); | 1120 | netif_carrier_on(netdev); |
1126 | 1121 | ||
1127 | mutex_unlock(&adapter->reset_lock); | ||
1128 | |||
1129 | return rc; | 1122 | return rc; |
1130 | } | 1123 | } |
1131 | 1124 | ||
@@ -1269,10 +1262,8 @@ static int ibmvnic_close(struct net_device *netdev) | |||
1269 | return 0; | 1262 | return 0; |
1270 | } | 1263 | } |
1271 | 1264 | ||
1272 | mutex_lock(&adapter->reset_lock); | ||
1273 | rc = __ibmvnic_close(netdev); | 1265 | rc = __ibmvnic_close(netdev); |
1274 | ibmvnic_cleanup(netdev); | 1266 | ibmvnic_cleanup(netdev); |
1275 | mutex_unlock(&adapter->reset_lock); | ||
1276 | 1267 | ||
1277 | return rc; | 1268 | return rc; |
1278 | } | 1269 | } |
@@ -1746,6 +1737,7 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
1746 | struct ibmvnic_rwi *rwi, u32 reset_state) | 1737 | struct ibmvnic_rwi *rwi, u32 reset_state) |
1747 | { | 1738 | { |
1748 | u64 old_num_rx_queues, old_num_tx_queues; | 1739 | u64 old_num_rx_queues, old_num_tx_queues; |
1740 | u64 old_num_rx_slots, old_num_tx_slots; | ||
1749 | struct net_device *netdev = adapter->netdev; | 1741 | struct net_device *netdev = adapter->netdev; |
1750 | int i, rc; | 1742 | int i, rc; |
1751 | 1743 | ||
@@ -1757,6 +1749,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
1757 | 1749 | ||
1758 | old_num_rx_queues = adapter->req_rx_queues; | 1750 | old_num_rx_queues = adapter->req_rx_queues; |
1759 | old_num_tx_queues = adapter->req_tx_queues; | 1751 | old_num_tx_queues = adapter->req_tx_queues; |
1752 | old_num_rx_slots = adapter->req_rx_add_entries_per_subcrq; | ||
1753 | old_num_tx_slots = adapter->req_tx_entries_per_subcrq; | ||
1760 | 1754 | ||
1761 | ibmvnic_cleanup(netdev); | 1755 | ibmvnic_cleanup(netdev); |
1762 | 1756 | ||
@@ -1819,21 +1813,20 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
1819 | if (rc) | 1813 | if (rc) |
1820 | return rc; | 1814 | return rc; |
1821 | } else if (adapter->req_rx_queues != old_num_rx_queues || | 1815 | } else if (adapter->req_rx_queues != old_num_rx_queues || |
1822 | adapter->req_tx_queues != old_num_tx_queues) { | 1816 | adapter->req_tx_queues != old_num_tx_queues || |
1823 | adapter->map_id = 1; | 1817 | adapter->req_rx_add_entries_per_subcrq != |
1818 | old_num_rx_slots || | ||
1819 | adapter->req_tx_entries_per_subcrq != | ||
1820 | old_num_tx_slots) { | ||
1824 | release_rx_pools(adapter); | 1821 | release_rx_pools(adapter); |
1825 | release_tx_pools(adapter); | 1822 | release_tx_pools(adapter); |
1826 | rc = init_rx_pools(netdev); | ||
1827 | if (rc) | ||
1828 | return rc; | ||
1829 | rc = init_tx_pools(netdev); | ||
1830 | if (rc) | ||
1831 | return rc; | ||
1832 | |||
1833 | release_napi(adapter); | 1823 | release_napi(adapter); |
1834 | rc = init_napi(adapter); | 1824 | release_vpd_data(adapter); |
1825 | |||
1826 | rc = init_resources(adapter); | ||
1835 | if (rc) | 1827 | if (rc) |
1836 | return rc; | 1828 | return rc; |
1829 | |||
1837 | } else { | 1830 | } else { |
1838 | rc = reset_tx_pools(adapter); | 1831 | rc = reset_tx_pools(adapter); |
1839 | if (rc) | 1832 | if (rc) |
@@ -1917,17 +1910,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter, | |||
1917 | adapter->state = VNIC_PROBED; | 1910 | adapter->state = VNIC_PROBED; |
1918 | return 0; | 1911 | return 0; |
1919 | } | 1912 | } |
1920 | /* netif_set_real_num_xx_queues needs to take rtnl lock here | 1913 | |
1921 | * unless wait_for_reset is set, in which case the rtnl lock | 1914 | rc = init_resources(adapter); |
1922 | * has already been taken before initializing the reset | ||
1923 | */ | ||
1924 | if (!adapter->wait_for_reset) { | ||
1925 | rtnl_lock(); | ||
1926 | rc = init_resources(adapter); | ||
1927 | rtnl_unlock(); | ||
1928 | } else { | ||
1929 | rc = init_resources(adapter); | ||
1930 | } | ||
1931 | if (rc) | 1915 | if (rc) |
1932 | return rc; | 1916 | return rc; |
1933 | 1917 | ||
@@ -1986,13 +1970,21 @@ static void __ibmvnic_reset(struct work_struct *work) | |||
1986 | struct ibmvnic_rwi *rwi; | 1970 | struct ibmvnic_rwi *rwi; |
1987 | struct ibmvnic_adapter *adapter; | 1971 | struct ibmvnic_adapter *adapter; |
1988 | struct net_device *netdev; | 1972 | struct net_device *netdev; |
1973 | bool we_lock_rtnl = false; | ||
1989 | u32 reset_state; | 1974 | u32 reset_state; |
1990 | int rc = 0; | 1975 | int rc = 0; |
1991 | 1976 | ||
1992 | adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); | 1977 | adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); |
1993 | netdev = adapter->netdev; | 1978 | netdev = adapter->netdev; |
1994 | 1979 | ||
1995 | mutex_lock(&adapter->reset_lock); | 1980 | /* netif_set_real_num_xx_queues needs to take rtnl lock here |
1981 | * unless wait_for_reset is set, in which case the rtnl lock | ||
1982 | * has already been taken before initializing the reset | ||
1983 | */ | ||
1984 | if (!adapter->wait_for_reset) { | ||
1985 | rtnl_lock(); | ||
1986 | we_lock_rtnl = true; | ||
1987 | } | ||
1996 | reset_state = adapter->state; | 1988 | reset_state = adapter->state; |
1997 | 1989 | ||
1998 | rwi = get_next_rwi(adapter); | 1990 | rwi = get_next_rwi(adapter); |
@@ -2020,12 +2012,11 @@ static void __ibmvnic_reset(struct work_struct *work) | |||
2020 | if (rc) { | 2012 | if (rc) { |
2021 | netdev_dbg(adapter->netdev, "Reset failed\n"); | 2013 | netdev_dbg(adapter->netdev, "Reset failed\n"); |
2022 | free_all_rwi(adapter); | 2014 | free_all_rwi(adapter); |
2023 | mutex_unlock(&adapter->reset_lock); | ||
2024 | return; | ||
2025 | } | 2015 | } |
2026 | 2016 | ||
2027 | adapter->resetting = false; | 2017 | adapter->resetting = false; |
2028 | mutex_unlock(&adapter->reset_lock); | 2018 | if (we_lock_rtnl) |
2019 | rtnl_unlock(); | ||
2029 | } | 2020 | } |
2030 | 2021 | ||
2031 | static int ibmvnic_reset(struct ibmvnic_adapter *adapter, | 2022 | static int ibmvnic_reset(struct ibmvnic_adapter *adapter, |
@@ -4768,7 +4759,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
4768 | 4759 | ||
4769 | INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset); | 4760 | INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset); |
4770 | INIT_LIST_HEAD(&adapter->rwi_list); | 4761 | INIT_LIST_HEAD(&adapter->rwi_list); |
4771 | mutex_init(&adapter->reset_lock); | ||
4772 | mutex_init(&adapter->rwi_lock); | 4762 | mutex_init(&adapter->rwi_lock); |
4773 | adapter->resetting = false; | 4763 | adapter->resetting = false; |
4774 | 4764 | ||
@@ -4840,8 +4830,8 @@ static int ibmvnic_remove(struct vio_dev *dev) | |||
4840 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 4830 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
4841 | 4831 | ||
4842 | adapter->state = VNIC_REMOVING; | 4832 | adapter->state = VNIC_REMOVING; |
4843 | unregister_netdev(netdev); | 4833 | rtnl_lock(); |
4844 | mutex_lock(&adapter->reset_lock); | 4834 | unregister_netdevice(netdev); |
4845 | 4835 | ||
4846 | release_resources(adapter); | 4836 | release_resources(adapter); |
4847 | release_sub_crqs(adapter, 1); | 4837 | release_sub_crqs(adapter, 1); |
@@ -4852,7 +4842,7 @@ static int ibmvnic_remove(struct vio_dev *dev) | |||
4852 | 4842 | ||
4853 | adapter->state = VNIC_REMOVED; | 4843 | adapter->state = VNIC_REMOVED; |
4854 | 4844 | ||
4855 | mutex_unlock(&adapter->reset_lock); | 4845 | rtnl_unlock(); |
4856 | device_remove_file(&dev->dev, &dev_attr_failover); | 4846 | device_remove_file(&dev->dev, &dev_attr_failover); |
4857 | free_netdev(netdev); | 4847 | free_netdev(netdev); |
4858 | dev_set_drvdata(&dev->dev, NULL); | 4848 | dev_set_drvdata(&dev->dev, NULL); |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index 18103b811d4d..99c4f8d331ce 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h | |||
@@ -1075,7 +1075,7 @@ struct ibmvnic_adapter { | |||
1075 | struct tasklet_struct tasklet; | 1075 | struct tasklet_struct tasklet; |
1076 | enum vnic_state state; | 1076 | enum vnic_state state; |
1077 | enum ibmvnic_reset_reason reset_reason; | 1077 | enum ibmvnic_reset_reason reset_reason; |
1078 | struct mutex reset_lock, rwi_lock; | 1078 | struct mutex rwi_lock; |
1079 | struct list_head rwi_list; | 1079 | struct list_head rwi_list; |
1080 | struct work_struct ibmvnic_reset; | 1080 | struct work_struct ibmvnic_reset; |
1081 | bool resetting; | 1081 | bool resetting; |
diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c index 8c5ba4b81fb7..2d4d10a017e5 100644 --- a/drivers/net/ethernet/lantiq_xrx200.c +++ b/drivers/net/ethernet/lantiq_xrx200.c | |||
@@ -512,7 +512,8 @@ static int xrx200_probe(struct platform_device *pdev) | |||
512 | err = register_netdev(net_dev); | 512 | err = register_netdev(net_dev); |
513 | if (err) | 513 | if (err) |
514 | goto err_unprepare_clk; | 514 | goto err_unprepare_clk; |
515 | return err; | 515 | |
516 | return 0; | ||
516 | 517 | ||
517 | err_unprepare_clk: | 518 | err_unprepare_clk: |
518 | clk_disable_unprepare(priv->clk); | 519 | clk_disable_unprepare(priv->clk); |
@@ -520,7 +521,7 @@ err_unprepare_clk: | |||
520 | err_uninit_dma: | 521 | err_uninit_dma: |
521 | xrx200_hw_cleanup(priv); | 522 | xrx200_hw_cleanup(priv); |
522 | 523 | ||
523 | return 0; | 524 | return err; |
524 | } | 525 | } |
525 | 526 | ||
526 | static int xrx200_remove(struct platform_device *pdev) | 527 | static int xrx200_remove(struct platform_device *pdev) |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 3ba672e9e353..e5397c8197b9 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
@@ -3343,7 +3343,6 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported, | |||
3343 | if (state->interface != PHY_INTERFACE_MODE_NA && | 3343 | if (state->interface != PHY_INTERFACE_MODE_NA && |
3344 | state->interface != PHY_INTERFACE_MODE_QSGMII && | 3344 | state->interface != PHY_INTERFACE_MODE_QSGMII && |
3345 | state->interface != PHY_INTERFACE_MODE_SGMII && | 3345 | state->interface != PHY_INTERFACE_MODE_SGMII && |
3346 | state->interface != PHY_INTERFACE_MODE_2500BASEX && | ||
3347 | !phy_interface_mode_is_8023z(state->interface) && | 3346 | !phy_interface_mode_is_8023z(state->interface) && |
3348 | !phy_interface_mode_is_rgmii(state->interface)) { | 3347 | !phy_interface_mode_is_rgmii(state->interface)) { |
3349 | bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); | 3348 | bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); |
@@ -3357,14 +3356,9 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported, | |||
3357 | /* Asymmetric pause is unsupported */ | 3356 | /* Asymmetric pause is unsupported */ |
3358 | phylink_set(mask, Pause); | 3357 | phylink_set(mask, Pause); |
3359 | 3358 | ||
3360 | /* We cannot use 1Gbps when using the 2.5G interface. */ | 3359 | /* Half-duplex at speeds higher than 100Mbit is unsupported */ |
3361 | if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { | 3360 | phylink_set(mask, 1000baseT_Full); |
3362 | phylink_set(mask, 2500baseT_Full); | 3361 | phylink_set(mask, 1000baseX_Full); |
3363 | phylink_set(mask, 2500baseX_Full); | ||
3364 | } else { | ||
3365 | phylink_set(mask, 1000baseT_Full); | ||
3366 | phylink_set(mask, 1000baseX_Full); | ||
3367 | } | ||
3368 | 3362 | ||
3369 | if (!phy_interface_mode_is_8023z(state->interface)) { | 3363 | if (!phy_interface_mode_is_8023z(state->interface)) { |
3370 | /* 10M and 100M are only supported in non-802.3z mode */ | 3364 | /* 10M and 100M are only supported in non-802.3z mode */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c index deef5a998985..9af34e03892c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/alloc.c +++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c | |||
@@ -337,7 +337,7 @@ void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc) | |||
337 | static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count, | 337 | static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count, |
338 | int align, u32 skip_mask, u32 *puid) | 338 | int align, u32 skip_mask, u32 *puid) |
339 | { | 339 | { |
340 | u32 uid; | 340 | u32 uid = 0; |
341 | u32 res; | 341 | u32 res; |
342 | struct mlx4_zone_allocator *zone_alloc = zone->allocator; | 342 | struct mlx4_zone_allocator *zone_alloc = zone->allocator; |
343 | struct mlx4_zone_entry *curr_node; | 343 | struct mlx4_zone_entry *curr_node; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index ebcd2778eeb3..23f1b5b512c2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -540,8 +540,8 @@ struct slave_list { | |||
540 | struct resource_allocator { | 540 | struct resource_allocator { |
541 | spinlock_t alloc_lock; /* protect quotas */ | 541 | spinlock_t alloc_lock; /* protect quotas */ |
542 | union { | 542 | union { |
543 | int res_reserved; | 543 | unsigned int res_reserved; |
544 | int res_port_rsvd[MLX4_MAX_PORTS]; | 544 | unsigned int res_port_rsvd[MLX4_MAX_PORTS]; |
545 | }; | 545 | }; |
546 | union { | 546 | union { |
547 | int res_free; | 547 | int res_free; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 2e84f10f59ba..1a11bc0e1612 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -363,6 +363,7 @@ int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, | |||
363 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, | 363 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, |
364 | buf); | 364 | buf); |
365 | 365 | ||
366 | (*mpt_entry)->lkey = 0; | ||
366 | err = mlx4_SW2HW_MPT(dev, mailbox, key); | 367 | err = mlx4_SW2HW_MPT(dev, mailbox, key); |
367 | } | 368 | } |
368 | 369 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index d7fbd5b6ac95..118324802926 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
@@ -569,6 +569,7 @@ struct mlx5e_rq { | |||
569 | 569 | ||
570 | unsigned long state; | 570 | unsigned long state; |
571 | int ix; | 571 | int ix; |
572 | unsigned int hw_mtu; | ||
572 | 573 | ||
573 | struct net_dim dim; /* Dynamic Interrupt Moderation */ | 574 | struct net_dim dim; /* Dynamic Interrupt Moderation */ |
574 | 575 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c index 023dc4bccd28..4a37713023be 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c | |||
@@ -88,10 +88,8 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) | |||
88 | 88 | ||
89 | eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper); | 89 | eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper); |
90 | *speed = mlx5e_port_ptys2speed(eth_proto_oper); | 90 | *speed = mlx5e_port_ptys2speed(eth_proto_oper); |
91 | if (!(*speed)) { | 91 | if (!(*speed)) |
92 | mlx5_core_warn(mdev, "cannot get port speed\n"); | ||
93 | err = -EINVAL; | 92 | err = -EINVAL; |
94 | } | ||
95 | 93 | ||
96 | return err; | 94 | return err; |
97 | } | 95 | } |
@@ -258,7 +256,7 @@ static int mlx5e_fec_admin_field(u32 *pplm, | |||
258 | case 40000: | 256 | case 40000: |
259 | if (!write) | 257 | if (!write) |
260 | *fec_policy = MLX5_GET(pplm_reg, pplm, | 258 | *fec_policy = MLX5_GET(pplm_reg, pplm, |
261 | fec_override_cap_10g_40g); | 259 | fec_override_admin_10g_40g); |
262 | else | 260 | else |
263 | MLX5_SET(pplm_reg, pplm, | 261 | MLX5_SET(pplm_reg, pplm, |
264 | fec_override_admin_10g_40g, *fec_policy); | 262 | fec_override_admin_10g_40g, *fec_policy); |
@@ -310,7 +308,7 @@ static int mlx5e_get_fec_cap_field(u32 *pplm, | |||
310 | case 10000: | 308 | case 10000: |
311 | case 40000: | 309 | case 40000: |
312 | *fec_cap = MLX5_GET(pplm_reg, pplm, | 310 | *fec_cap = MLX5_GET(pplm_reg, pplm, |
313 | fec_override_admin_10g_40g); | 311 | fec_override_cap_10g_40g); |
314 | break; | 312 | break; |
315 | case 25000: | 313 | case 25000: |
316 | *fec_cap = MLX5_GET(pplm_reg, pplm, | 314 | *fec_cap = MLX5_GET(pplm_reg, pplm, |
@@ -394,12 +392,12 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active, | |||
394 | 392 | ||
395 | int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) | 393 | int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) |
396 | { | 394 | { |
395 | u8 fec_policy_nofec = BIT(MLX5E_FEC_NOFEC); | ||
397 | bool fec_mode_not_supp_in_speed = false; | 396 | bool fec_mode_not_supp_in_speed = false; |
398 | u8 no_fec_policy = BIT(MLX5E_FEC_NOFEC); | ||
399 | u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; | 397 | u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; |
400 | u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; | 398 | u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; |
401 | int sz = MLX5_ST_SZ_BYTES(pplm_reg); | 399 | int sz = MLX5_ST_SZ_BYTES(pplm_reg); |
402 | u32 current_fec_speed; | 400 | u8 fec_policy_auto = 0; |
403 | u8 fec_caps = 0; | 401 | u8 fec_caps = 0; |
404 | int err; | 402 | int err; |
405 | int i; | 403 | int i; |
@@ -415,23 +413,19 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) | |||
415 | if (err) | 413 | if (err) |
416 | return err; | 414 | return err; |
417 | 415 | ||
418 | err = mlx5e_port_linkspeed(dev, ¤t_fec_speed); | 416 | MLX5_SET(pplm_reg, out, local_port, 1); |
419 | if (err) | ||
420 | return err; | ||
421 | 417 | ||
422 | memset(in, 0, sz); | 418 | for (i = 0; i < MLX5E_FEC_SUPPORTED_SPEEDS; i++) { |
423 | MLX5_SET(pplm_reg, in, local_port, 1); | ||
424 | for (i = 0; i < MLX5E_FEC_SUPPORTED_SPEEDS && !!fec_policy; i++) { | ||
425 | mlx5e_get_fec_cap_field(out, &fec_caps, fec_supported_speeds[i]); | 419 | mlx5e_get_fec_cap_field(out, &fec_caps, fec_supported_speeds[i]); |
426 | /* policy supported for link speed */ | 420 | /* policy supported for link speed, or policy is auto */ |
427 | if (!!(fec_caps & fec_policy)) { | 421 | if (fec_caps & fec_policy || fec_policy == fec_policy_auto) { |
428 | mlx5e_fec_admin_field(in, &fec_policy, 1, | 422 | mlx5e_fec_admin_field(out, &fec_policy, 1, |
429 | fec_supported_speeds[i]); | 423 | fec_supported_speeds[i]); |
430 | } else { | 424 | } else { |
431 | if (fec_supported_speeds[i] == current_fec_speed) | 425 | /* turn off FEC if supported. Else, leave it the same */ |
432 | return -EOPNOTSUPP; | 426 | if (fec_caps & fec_policy_nofec) |
433 | mlx5e_fec_admin_field(in, &no_fec_policy, 1, | 427 | mlx5e_fec_admin_field(out, &fec_policy_nofec, 1, |
434 | fec_supported_speeds[i]); | 428 | fec_supported_speeds[i]); |
435 | fec_mode_not_supp_in_speed = true; | 429 | fec_mode_not_supp_in_speed = true; |
436 | } | 430 | } |
437 | } | 431 | } |
@@ -441,5 +435,5 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) | |||
441 | "FEC policy 0x%x is not supported for some speeds", | 435 | "FEC policy 0x%x is not supported for some speeds", |
442 | fec_policy); | 436 | fec_policy); |
443 | 437 | ||
444 | return mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1); | 438 | return mlx5_core_access_reg(dev, out, sz, out, sz, MLX5_REG_PPLM, 0, 1); |
445 | } | 439 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c index c047da8752da..eac245a93f91 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | |||
@@ -130,8 +130,10 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu) | |||
130 | int err; | 130 | int err; |
131 | 131 | ||
132 | err = mlx5e_port_linkspeed(priv->mdev, &speed); | 132 | err = mlx5e_port_linkspeed(priv->mdev, &speed); |
133 | if (err) | 133 | if (err) { |
134 | mlx5_core_warn(priv->mdev, "cannot get port speed\n"); | ||
134 | return 0; | 135 | return 0; |
136 | } | ||
135 | 137 | ||
136 | xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100; | 138 | xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100; |
137 | 139 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 3e770abfd802..25c1c4f96841 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
@@ -843,8 +843,7 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, | |||
843 | ethtool_link_ksettings_add_link_mode(link_ksettings, supported, | 843 | ethtool_link_ksettings_add_link_mode(link_ksettings, supported, |
844 | Autoneg); | 844 | Autoneg); |
845 | 845 | ||
846 | err = get_fec_supported_advertised(mdev, link_ksettings); | 846 | if (get_fec_supported_advertised(mdev, link_ksettings)) |
847 | if (err) | ||
848 | netdev_dbg(netdev, "%s: FEC caps query failed: %d\n", | 847 | netdev_dbg(netdev, "%s: FEC caps query failed: %d\n", |
849 | __func__, err); | 848 | __func__, err); |
850 | 849 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 1243edbedc9e..871313d6b34d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -502,6 +502,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, | |||
502 | rq->channel = c; | 502 | rq->channel = c; |
503 | rq->ix = c->ix; | 503 | rq->ix = c->ix; |
504 | rq->mdev = mdev; | 504 | rq->mdev = mdev; |
505 | rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); | ||
505 | rq->stats = &c->priv->channel_stats[c->ix].rq; | 506 | rq->stats = &c->priv->channel_stats[c->ix].rq; |
506 | 507 | ||
507 | rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL; | 508 | rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL; |
@@ -1623,13 +1624,15 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev, | |||
1623 | int err; | 1624 | int err; |
1624 | u32 i; | 1625 | u32 i; |
1625 | 1626 | ||
1627 | err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn); | ||
1628 | if (err) | ||
1629 | return err; | ||
1630 | |||
1626 | err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, | 1631 | err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, |
1627 | &cq->wq_ctrl); | 1632 | &cq->wq_ctrl); |
1628 | if (err) | 1633 | if (err) |
1629 | return err; | 1634 | return err; |
1630 | 1635 | ||
1631 | mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn); | ||
1632 | |||
1633 | mcq->cqe_sz = 64; | 1636 | mcq->cqe_sz = 64; |
1634 | mcq->set_ci_db = cq->wq_ctrl.db.db; | 1637 | mcq->set_ci_db = cq->wq_ctrl.db.db; |
1635 | mcq->arm_db = cq->wq_ctrl.db.db + 1; | 1638 | mcq->arm_db = cq->wq_ctrl.db.db + 1; |
@@ -1687,6 +1690,10 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param) | |||
1687 | int eqn; | 1690 | int eqn; |
1688 | int err; | 1691 | int err; |
1689 | 1692 | ||
1693 | err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used); | ||
1694 | if (err) | ||
1695 | return err; | ||
1696 | |||
1690 | inlen = MLX5_ST_SZ_BYTES(create_cq_in) + | 1697 | inlen = MLX5_ST_SZ_BYTES(create_cq_in) + |
1691 | sizeof(u64) * cq->wq_ctrl.buf.npages; | 1698 | sizeof(u64) * cq->wq_ctrl.buf.npages; |
1692 | in = kvzalloc(inlen, GFP_KERNEL); | 1699 | in = kvzalloc(inlen, GFP_KERNEL); |
@@ -1700,8 +1707,6 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param) | |||
1700 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, | 1707 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, |
1701 | (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); | 1708 | (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); |
1702 | 1709 | ||
1703 | mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used); | ||
1704 | |||
1705 | MLX5_SET(cqc, cqc, cq_period_mode, param->cq_period_mode); | 1710 | MLX5_SET(cqc, cqc, cq_period_mode, param->cq_period_mode); |
1706 | MLX5_SET(cqc, cqc, c_eqn, eqn); | 1711 | MLX5_SET(cqc, cqc, c_eqn, eqn); |
1707 | MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); | 1712 | MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); |
@@ -1921,6 +1926,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, | |||
1921 | int err; | 1926 | int err; |
1922 | int eqn; | 1927 | int eqn; |
1923 | 1928 | ||
1929 | err = mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq); | ||
1930 | if (err) | ||
1931 | return err; | ||
1932 | |||
1924 | c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); | 1933 | c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); |
1925 | if (!c) | 1934 | if (!c) |
1926 | return -ENOMEM; | 1935 | return -ENOMEM; |
@@ -1937,7 +1946,6 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, | |||
1937 | c->xdp = !!params->xdp_prog; | 1946 | c->xdp = !!params->xdp_prog; |
1938 | c->stats = &priv->channel_stats[ix].ch; | 1947 | c->stats = &priv->channel_stats[ix].ch; |
1939 | 1948 | ||
1940 | mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq); | ||
1941 | c->irq_desc = irq_to_desc(irq); | 1949 | c->irq_desc = irq_to_desc(irq); |
1942 | 1950 | ||
1943 | netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64); | 1951 | netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64); |
@@ -3574,6 +3582,7 @@ static int set_feature_cvlan_filter(struct net_device *netdev, bool enable) | |||
3574 | return 0; | 3582 | return 0; |
3575 | } | 3583 | } |
3576 | 3584 | ||
3585 | #ifdef CONFIG_MLX5_ESWITCH | ||
3577 | static int set_feature_tc_num_filters(struct net_device *netdev, bool enable) | 3586 | static int set_feature_tc_num_filters(struct net_device *netdev, bool enable) |
3578 | { | 3587 | { |
3579 | struct mlx5e_priv *priv = netdev_priv(netdev); | 3588 | struct mlx5e_priv *priv = netdev_priv(netdev); |
@@ -3586,6 +3595,7 @@ static int set_feature_tc_num_filters(struct net_device *netdev, bool enable) | |||
3586 | 3595 | ||
3587 | return 0; | 3596 | return 0; |
3588 | } | 3597 | } |
3598 | #endif | ||
3589 | 3599 | ||
3590 | static int set_feature_rx_all(struct net_device *netdev, bool enable) | 3600 | static int set_feature_rx_all(struct net_device *netdev, bool enable) |
3591 | { | 3601 | { |
@@ -3684,7 +3694,9 @@ static int mlx5e_set_features(struct net_device *netdev, | |||
3684 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro); | 3694 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro); |
3685 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER, | 3695 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER, |
3686 | set_feature_cvlan_filter); | 3696 | set_feature_cvlan_filter); |
3697 | #ifdef CONFIG_MLX5_ESWITCH | ||
3687 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters); | 3698 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters); |
3699 | #endif | ||
3688 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXALL, set_feature_rx_all); | 3700 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXALL, set_feature_rx_all); |
3689 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs); | 3701 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs); |
3690 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan); | 3702 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan); |
@@ -3755,10 +3767,11 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu, | |||
3755 | } | 3767 | } |
3756 | 3768 | ||
3757 | if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { | 3769 | if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { |
3770 | bool is_linear = mlx5e_rx_mpwqe_is_linear_skb(priv->mdev, &new_channels.params); | ||
3758 | u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params); | 3771 | u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params); |
3759 | u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params); | 3772 | u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params); |
3760 | 3773 | ||
3761 | reset = reset && (ppw_old != ppw_new); | 3774 | reset = reset && (is_linear || (ppw_old != ppw_new)); |
3762 | } | 3775 | } |
3763 | 3776 | ||
3764 | if (!reset) { | 3777 | if (!reset) { |
@@ -4678,7 +4691,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) | |||
4678 | FT_CAP(modify_root) && | 4691 | FT_CAP(modify_root) && |
4679 | FT_CAP(identified_miss_table_mode) && | 4692 | FT_CAP(identified_miss_table_mode) && |
4680 | FT_CAP(flow_table_modify)) { | 4693 | FT_CAP(flow_table_modify)) { |
4694 | #ifdef CONFIG_MLX5_ESWITCH | ||
4681 | netdev->hw_features |= NETIF_F_HW_TC; | 4695 | netdev->hw_features |= NETIF_F_HW_TC; |
4696 | #endif | ||
4682 | #ifdef CONFIG_MLX5_EN_ARFS | 4697 | #ifdef CONFIG_MLX5_EN_ARFS |
4683 | netdev->hw_features |= NETIF_F_NTUPLE; | 4698 | netdev->hw_features |= NETIF_F_NTUPLE; |
4684 | #endif | 4699 | #endif |
@@ -5004,11 +5019,21 @@ err_free_netdev: | |||
5004 | int mlx5e_attach_netdev(struct mlx5e_priv *priv) | 5019 | int mlx5e_attach_netdev(struct mlx5e_priv *priv) |
5005 | { | 5020 | { |
5006 | const struct mlx5e_profile *profile; | 5021 | const struct mlx5e_profile *profile; |
5022 | int max_nch; | ||
5007 | int err; | 5023 | int err; |
5008 | 5024 | ||
5009 | profile = priv->profile; | 5025 | profile = priv->profile; |
5010 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); | 5026 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); |
5011 | 5027 | ||
5028 | /* max number of channels may have changed */ | ||
5029 | max_nch = mlx5e_get_max_num_channels(priv->mdev); | ||
5030 | if (priv->channels.params.num_channels > max_nch) { | ||
5031 | mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); | ||
5032 | priv->channels.params.num_channels = max_nch; | ||
5033 | mlx5e_build_default_indir_rqt(priv->channels.params.indirection_rqt, | ||
5034 | MLX5E_INDIR_RQT_SIZE, max_nch); | ||
5035 | } | ||
5036 | |||
5012 | err = profile->init_tx(priv); | 5037 | err = profile->init_tx(priv); |
5013 | if (err) | 5038 | if (err) |
5014 | goto out; | 5039 | goto out; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 79638dcbae78..16985ca3248d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | |||
@@ -1104,6 +1104,12 @@ mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, | |||
1104 | u32 frag_size; | 1104 | u32 frag_size; |
1105 | bool consumed; | 1105 | bool consumed; |
1106 | 1106 | ||
1107 | /* Check packet size. Note LRO doesn't use linear SKB */ | ||
1108 | if (unlikely(cqe_bcnt > rq->hw_mtu)) { | ||
1109 | rq->stats->oversize_pkts_sw_drop++; | ||
1110 | return NULL; | ||
1111 | } | ||
1112 | |||
1107 | va = page_address(di->page) + head_offset; | 1113 | va = page_address(di->page) + head_offset; |
1108 | data = va + rx_headroom; | 1114 | data = va + rx_headroom; |
1109 | frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + cqe_bcnt32); | 1115 | frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + cqe_bcnt32); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c index 35ded91203f5..4382ef85488c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c | |||
@@ -98,18 +98,17 @@ static int mlx5e_test_link_speed(struct mlx5e_priv *priv) | |||
98 | return 1; | 98 | return 1; |
99 | } | 99 | } |
100 | 100 | ||
101 | #ifdef CONFIG_INET | ||
102 | /* loopback test */ | ||
103 | #define MLX5E_TEST_PKT_SIZE (MLX5E_RX_MAX_HEAD - NET_IP_ALIGN) | ||
104 | static const char mlx5e_test_text[ETH_GSTRING_LEN] = "MLX5E SELF TEST"; | ||
105 | #define MLX5E_TEST_MAGIC 0x5AEED15C001ULL | ||
106 | |||
107 | struct mlx5ehdr { | 101 | struct mlx5ehdr { |
108 | __be32 version; | 102 | __be32 version; |
109 | __be64 magic; | 103 | __be64 magic; |
110 | char text[ETH_GSTRING_LEN]; | ||
111 | }; | 104 | }; |
112 | 105 | ||
106 | #ifdef CONFIG_INET | ||
107 | /* loopback test */ | ||
108 | #define MLX5E_TEST_PKT_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) +\ | ||
109 | sizeof(struct udphdr) + sizeof(struct mlx5ehdr)) | ||
110 | #define MLX5E_TEST_MAGIC 0x5AEED15C001ULL | ||
111 | |||
113 | static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | 112 | static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) |
114 | { | 113 | { |
115 | struct sk_buff *skb = NULL; | 114 | struct sk_buff *skb = NULL; |
@@ -117,10 +116,7 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
117 | struct ethhdr *ethh; | 116 | struct ethhdr *ethh; |
118 | struct udphdr *udph; | 117 | struct udphdr *udph; |
119 | struct iphdr *iph; | 118 | struct iphdr *iph; |
120 | int datalen, iplen; | 119 | int iplen; |
121 | |||
122 | datalen = MLX5E_TEST_PKT_SIZE - | ||
123 | (sizeof(*ethh) + sizeof(*iph) + sizeof(*udph)); | ||
124 | 120 | ||
125 | skb = netdev_alloc_skb(priv->netdev, MLX5E_TEST_PKT_SIZE); | 121 | skb = netdev_alloc_skb(priv->netdev, MLX5E_TEST_PKT_SIZE); |
126 | if (!skb) { | 122 | if (!skb) { |
@@ -149,7 +145,7 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
149 | /* Fill UDP header */ | 145 | /* Fill UDP header */ |
150 | udph->source = htons(9); | 146 | udph->source = htons(9); |
151 | udph->dest = htons(9); /* Discard Protocol */ | 147 | udph->dest = htons(9); /* Discard Protocol */ |
152 | udph->len = htons(datalen + sizeof(struct udphdr)); | 148 | udph->len = htons(sizeof(struct mlx5ehdr) + sizeof(struct udphdr)); |
153 | udph->check = 0; | 149 | udph->check = 0; |
154 | 150 | ||
155 | /* Fill IP header */ | 151 | /* Fill IP header */ |
@@ -157,7 +153,8 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
157 | iph->ttl = 32; | 153 | iph->ttl = 32; |
158 | iph->version = 4; | 154 | iph->version = 4; |
159 | iph->protocol = IPPROTO_UDP; | 155 | iph->protocol = IPPROTO_UDP; |
160 | iplen = sizeof(struct iphdr) + sizeof(struct udphdr) + datalen; | 156 | iplen = sizeof(struct iphdr) + sizeof(struct udphdr) + |
157 | sizeof(struct mlx5ehdr); | ||
161 | iph->tot_len = htons(iplen); | 158 | iph->tot_len = htons(iplen); |
162 | iph->frag_off = 0; | 159 | iph->frag_off = 0; |
163 | iph->saddr = 0; | 160 | iph->saddr = 0; |
@@ -170,9 +167,6 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
170 | mlxh = skb_put(skb, sizeof(*mlxh)); | 167 | mlxh = skb_put(skb, sizeof(*mlxh)); |
171 | mlxh->version = 0; | 168 | mlxh->version = 0; |
172 | mlxh->magic = cpu_to_be64(MLX5E_TEST_MAGIC); | 169 | mlxh->magic = cpu_to_be64(MLX5E_TEST_MAGIC); |
173 | strlcpy(mlxh->text, mlx5e_test_text, sizeof(mlxh->text)); | ||
174 | datalen -= sizeof(*mlxh); | ||
175 | skb_put_zero(skb, datalen); | ||
176 | 170 | ||
177 | skb->csum = 0; | 171 | skb->csum = 0; |
178 | skb->ip_summed = CHECKSUM_PARTIAL; | 172 | skb->ip_summed = CHECKSUM_PARTIAL; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c index 1e55b9c27ffc..3e99d0728b2f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c | |||
@@ -83,6 +83,7 @@ static const struct counter_desc sw_stats_desc[] = { | |||
83 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, | 83 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, |
84 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_cqes) }, | 84 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_cqes) }, |
85 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_strides) }, | 85 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_strides) }, |
86 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_oversize_pkts_sw_drop) }, | ||
86 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) }, | 87 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) }, |
87 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_blks) }, | 88 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_blks) }, |
88 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_pkts) }, | 89 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_pkts) }, |
@@ -161,6 +162,7 @@ void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv) | |||
161 | s->rx_wqe_err += rq_stats->wqe_err; | 162 | s->rx_wqe_err += rq_stats->wqe_err; |
162 | s->rx_mpwqe_filler_cqes += rq_stats->mpwqe_filler_cqes; | 163 | s->rx_mpwqe_filler_cqes += rq_stats->mpwqe_filler_cqes; |
163 | s->rx_mpwqe_filler_strides += rq_stats->mpwqe_filler_strides; | 164 | s->rx_mpwqe_filler_strides += rq_stats->mpwqe_filler_strides; |
165 | s->rx_oversize_pkts_sw_drop += rq_stats->oversize_pkts_sw_drop; | ||
164 | s->rx_buff_alloc_err += rq_stats->buff_alloc_err; | 166 | s->rx_buff_alloc_err += rq_stats->buff_alloc_err; |
165 | s->rx_cqe_compress_blks += rq_stats->cqe_compress_blks; | 167 | s->rx_cqe_compress_blks += rq_stats->cqe_compress_blks; |
166 | s->rx_cqe_compress_pkts += rq_stats->cqe_compress_pkts; | 168 | s->rx_cqe_compress_pkts += rq_stats->cqe_compress_pkts; |
@@ -1189,6 +1191,7 @@ static const struct counter_desc rq_stats_desc[] = { | |||
1189 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, wqe_err) }, | 1191 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, wqe_err) }, |
1190 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) }, | 1192 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) }, |
1191 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) }, | 1193 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) }, |
1194 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, oversize_pkts_sw_drop) }, | ||
1192 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, buff_alloc_err) }, | 1195 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, buff_alloc_err) }, |
1193 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_blks) }, | 1196 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_blks) }, |
1194 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) }, | 1197 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) }, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index 77f74ce11280..3f8e870ef4c9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | |||
@@ -96,6 +96,7 @@ struct mlx5e_sw_stats { | |||
96 | u64 rx_wqe_err; | 96 | u64 rx_wqe_err; |
97 | u64 rx_mpwqe_filler_cqes; | 97 | u64 rx_mpwqe_filler_cqes; |
98 | u64 rx_mpwqe_filler_strides; | 98 | u64 rx_mpwqe_filler_strides; |
99 | u64 rx_oversize_pkts_sw_drop; | ||
99 | u64 rx_buff_alloc_err; | 100 | u64 rx_buff_alloc_err; |
100 | u64 rx_cqe_compress_blks; | 101 | u64 rx_cqe_compress_blks; |
101 | u64 rx_cqe_compress_pkts; | 102 | u64 rx_cqe_compress_pkts; |
@@ -193,6 +194,7 @@ struct mlx5e_rq_stats { | |||
193 | u64 wqe_err; | 194 | u64 wqe_err; |
194 | u64 mpwqe_filler_cqes; | 195 | u64 mpwqe_filler_cqes; |
195 | u64 mpwqe_filler_strides; | 196 | u64 mpwqe_filler_strides; |
197 | u64 oversize_pkts_sw_drop; | ||
196 | u64 buff_alloc_err; | 198 | u64 buff_alloc_err; |
197 | u64 cqe_compress_blks; | 199 | u64 cqe_compress_blks; |
198 | u64 cqe_compress_pkts; | 200 | u64 cqe_compress_pkts; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 608025ca5c04..fca6f4132c91 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -1447,31 +1447,21 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1447 | inner_headers); | 1447 | inner_headers); |
1448 | } | 1448 | } |
1449 | 1449 | ||
1450 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { | 1450 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) { |
1451 | struct flow_dissector_key_eth_addrs *key = | 1451 | struct flow_dissector_key_basic *key = |
1452 | skb_flow_dissector_target(f->dissector, | 1452 | skb_flow_dissector_target(f->dissector, |
1453 | FLOW_DISSECTOR_KEY_ETH_ADDRS, | 1453 | FLOW_DISSECTOR_KEY_BASIC, |
1454 | f->key); | 1454 | f->key); |
1455 | struct flow_dissector_key_eth_addrs *mask = | 1455 | struct flow_dissector_key_basic *mask = |
1456 | skb_flow_dissector_target(f->dissector, | 1456 | skb_flow_dissector_target(f->dissector, |
1457 | FLOW_DISSECTOR_KEY_ETH_ADDRS, | 1457 | FLOW_DISSECTOR_KEY_BASIC, |
1458 | f->mask); | 1458 | f->mask); |
1459 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype, | ||
1460 | ntohs(mask->n_proto)); | ||
1461 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, | ||
1462 | ntohs(key->n_proto)); | ||
1459 | 1463 | ||
1460 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, | 1464 | if (mask->n_proto) |
1461 | dmac_47_16), | ||
1462 | mask->dst); | ||
1463 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1464 | dmac_47_16), | ||
1465 | key->dst); | ||
1466 | |||
1467 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, | ||
1468 | smac_47_16), | ||
1469 | mask->src); | ||
1470 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1471 | smac_47_16), | ||
1472 | key->src); | ||
1473 | |||
1474 | if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst)) | ||
1475 | *match_level = MLX5_MATCH_L2; | 1465 | *match_level = MLX5_MATCH_L2; |
1476 | } | 1466 | } |
1477 | 1467 | ||
@@ -1505,9 +1495,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1505 | 1495 | ||
1506 | *match_level = MLX5_MATCH_L2; | 1496 | *match_level = MLX5_MATCH_L2; |
1507 | } | 1497 | } |
1508 | } else { | 1498 | } else if (*match_level != MLX5_MATCH_NONE) { |
1509 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, svlan_tag, 1); | 1499 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, svlan_tag, 1); |
1510 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); | 1500 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); |
1501 | *match_level = MLX5_MATCH_L2; | ||
1511 | } | 1502 | } |
1512 | 1503 | ||
1513 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { | 1504 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { |
@@ -1545,21 +1536,31 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1545 | } | 1536 | } |
1546 | } | 1537 | } |
1547 | 1538 | ||
1548 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) { | 1539 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { |
1549 | struct flow_dissector_key_basic *key = | 1540 | struct flow_dissector_key_eth_addrs *key = |
1550 | skb_flow_dissector_target(f->dissector, | 1541 | skb_flow_dissector_target(f->dissector, |
1551 | FLOW_DISSECTOR_KEY_BASIC, | 1542 | FLOW_DISSECTOR_KEY_ETH_ADDRS, |
1552 | f->key); | 1543 | f->key); |
1553 | struct flow_dissector_key_basic *mask = | 1544 | struct flow_dissector_key_eth_addrs *mask = |
1554 | skb_flow_dissector_target(f->dissector, | 1545 | skb_flow_dissector_target(f->dissector, |
1555 | FLOW_DISSECTOR_KEY_BASIC, | 1546 | FLOW_DISSECTOR_KEY_ETH_ADDRS, |
1556 | f->mask); | 1547 | f->mask); |
1557 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype, | ||
1558 | ntohs(mask->n_proto)); | ||
1559 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, | ||
1560 | ntohs(key->n_proto)); | ||
1561 | 1548 | ||
1562 | if (mask->n_proto) | 1549 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, |
1550 | dmac_47_16), | ||
1551 | mask->dst); | ||
1552 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1553 | dmac_47_16), | ||
1554 | key->dst); | ||
1555 | |||
1556 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, | ||
1557 | smac_47_16), | ||
1558 | mask->src); | ||
1559 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1560 | smac_47_16), | ||
1561 | key->src); | ||
1562 | |||
1563 | if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst)) | ||
1563 | *match_level = MLX5_MATCH_L2; | 1564 | *match_level = MLX5_MATCH_L2; |
1564 | } | 1565 | } |
1565 | 1566 | ||
@@ -1586,10 +1587,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1586 | 1587 | ||
1587 | /* the HW doesn't need L3 inline to match on frag=no */ | 1588 | /* the HW doesn't need L3 inline to match on frag=no */ |
1588 | if (!(key->flags & FLOW_DIS_IS_FRAGMENT)) | 1589 | if (!(key->flags & FLOW_DIS_IS_FRAGMENT)) |
1589 | *match_level = MLX5_INLINE_MODE_L2; | 1590 | *match_level = MLX5_MATCH_L2; |
1590 | /* *** L2 attributes parsing up to here *** */ | 1591 | /* *** L2 attributes parsing up to here *** */ |
1591 | else | 1592 | else |
1592 | *match_level = MLX5_INLINE_MODE_IP; | 1593 | *match_level = MLX5_MATCH_L3; |
1593 | } | 1594 | } |
1594 | } | 1595 | } |
1595 | 1596 | ||
@@ -2979,7 +2980,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, | |||
2979 | if (!actions_match_supported(priv, exts, parse_attr, flow, extack)) | 2980 | if (!actions_match_supported(priv, exts, parse_attr, flow, extack)) |
2980 | return -EOPNOTSUPP; | 2981 | return -EOPNOTSUPP; |
2981 | 2982 | ||
2982 | if (attr->out_count > 1 && !mlx5_esw_has_fwd_fdb(priv->mdev)) { | 2983 | if (attr->mirror_count > 0 && !mlx5_esw_has_fwd_fdb(priv->mdev)) { |
2983 | NL_SET_ERR_MSG_MOD(extack, | 2984 | NL_SET_ERR_MSG_MOD(extack, |
2984 | "current firmware doesn't support split rule for port mirroring"); | 2985 | "current firmware doesn't support split rule for port mirroring"); |
2985 | netdev_warn_once(priv->netdev, "current firmware doesn't support split rule for port mirroring\n"); | 2986 | netdev_warn_once(priv->netdev, "current firmware doesn't support split rule for port mirroring\n"); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c index 515e3d6de051..5a22c5874f3b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c | |||
@@ -83,8 +83,14 @@ struct mlx5_fpga_ipsec_rule { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | static const struct rhashtable_params rhash_sa = { | 85 | static const struct rhashtable_params rhash_sa = { |
86 | .key_len = FIELD_SIZEOF(struct mlx5_fpga_ipsec_sa_ctx, hw_sa), | 86 | /* Keep out "cmd" field from the key as it's |
87 | .key_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hw_sa), | 87 | * value is not constant during the lifetime |
88 | * of the key object. | ||
89 | */ | ||
90 | .key_len = FIELD_SIZEOF(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) - | ||
91 | FIELD_SIZEOF(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd), | ||
92 | .key_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) + | ||
93 | FIELD_SIZEOF(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd), | ||
88 | .head_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hash), | 94 | .head_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hash), |
89 | .automatic_shrinking = true, | 95 | .automatic_shrinking = true, |
90 | .min_size = 1, | 96 | .min_size = 1, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index b59953daf8b4..11dabd62e2c7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c | |||
@@ -560,9 +560,9 @@ static int mlx5i_close(struct net_device *netdev) | |||
560 | 560 | ||
561 | netif_carrier_off(epriv->netdev); | 561 | netif_carrier_off(epriv->netdev); |
562 | mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn); | 562 | mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn); |
563 | mlx5i_uninit_underlay_qp(epriv); | ||
564 | mlx5e_deactivate_priv_channels(epriv); | 563 | mlx5e_deactivate_priv_channels(epriv); |
565 | mlx5e_close_channels(&epriv->channels); | 564 | mlx5e_close_channels(&epriv->channels); |
565 | mlx5i_uninit_underlay_qp(epriv); | ||
566 | unlock: | 566 | unlock: |
567 | mutex_unlock(&epriv->state_lock); | 567 | mutex_unlock(&epriv->state_lock); |
568 | return 0; | 568 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 8e8fa823d611..69966dfc6e3d 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c | |||
@@ -191,7 +191,7 @@ qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data) | |||
191 | static void | 191 | static void |
192 | qed_dcbx_set_params(struct qed_dcbx_results *p_data, | 192 | qed_dcbx_set_params(struct qed_dcbx_results *p_data, |
193 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | 193 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
194 | bool enable, u8 prio, u8 tc, | 194 | bool app_tlv, bool enable, u8 prio, u8 tc, |
195 | enum dcbx_protocol_type type, | 195 | enum dcbx_protocol_type type, |
196 | enum qed_pci_personality personality) | 196 | enum qed_pci_personality personality) |
197 | { | 197 | { |
@@ -210,7 +210,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data, | |||
210 | p_data->arr[type].dont_add_vlan0 = true; | 210 | p_data->arr[type].dont_add_vlan0 = true; |
211 | 211 | ||
212 | /* QM reconf data */ | 212 | /* QM reconf data */ |
213 | if (p_hwfn->hw_info.personality == personality) | 213 | if (app_tlv && p_hwfn->hw_info.personality == personality) |
214 | qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc); | 214 | qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc); |
215 | 215 | ||
216 | /* Configure dcbx vlan priority in doorbell block for roce EDPM */ | 216 | /* Configure dcbx vlan priority in doorbell block for roce EDPM */ |
@@ -225,7 +225,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data, | |||
225 | static void | 225 | static void |
226 | qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, | 226 | qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, |
227 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | 227 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
228 | bool enable, u8 prio, u8 tc, | 228 | bool app_tlv, bool enable, u8 prio, u8 tc, |
229 | enum dcbx_protocol_type type) | 229 | enum dcbx_protocol_type type) |
230 | { | 230 | { |
231 | enum qed_pci_personality personality; | 231 | enum qed_pci_personality personality; |
@@ -240,7 +240,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, | |||
240 | 240 | ||
241 | personality = qed_dcbx_app_update[i].personality; | 241 | personality = qed_dcbx_app_update[i].personality; |
242 | 242 | ||
243 | qed_dcbx_set_params(p_data, p_hwfn, p_ptt, enable, | 243 | qed_dcbx_set_params(p_data, p_hwfn, p_ptt, app_tlv, enable, |
244 | prio, tc, type, personality); | 244 | prio, tc, type, personality); |
245 | } | 245 | } |
246 | } | 246 | } |
@@ -319,8 +319,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | |||
319 | enable = true; | 319 | enable = true; |
320 | } | 320 | } |
321 | 321 | ||
322 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable, | 322 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, true, |
323 | priority, tc, type); | 323 | enable, priority, tc, type); |
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
@@ -341,7 +341,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | |||
341 | continue; | 341 | continue; |
342 | 342 | ||
343 | enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version; | 343 | enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version; |
344 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable, | 344 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, false, enable, |
345 | priority, tc, type); | 345 | priority, tc, type); |
346 | } | 346 | } |
347 | 347 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 7ceb2b97538d..88a8576ca9ce 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c | |||
@@ -185,6 +185,10 @@ void qed_resc_free(struct qed_dev *cdev) | |||
185 | qed_iscsi_free(p_hwfn); | 185 | qed_iscsi_free(p_hwfn); |
186 | qed_ooo_free(p_hwfn); | 186 | qed_ooo_free(p_hwfn); |
187 | } | 187 | } |
188 | |||
189 | if (QED_IS_RDMA_PERSONALITY(p_hwfn)) | ||
190 | qed_rdma_info_free(p_hwfn); | ||
191 | |||
188 | qed_iov_free(p_hwfn); | 192 | qed_iov_free(p_hwfn); |
189 | qed_l2_free(p_hwfn); | 193 | qed_l2_free(p_hwfn); |
190 | qed_dmae_info_free(p_hwfn); | 194 | qed_dmae_info_free(p_hwfn); |
@@ -481,8 +485,16 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn, | |||
481 | struct qed_qm_info *qm_info = &p_hwfn->qm_info; | 485 | struct qed_qm_info *qm_info = &p_hwfn->qm_info; |
482 | 486 | ||
483 | /* Can't have multiple flags set here */ | 487 | /* Can't have multiple flags set here */ |
484 | if (bitmap_weight((unsigned long *)&pq_flags, sizeof(pq_flags)) > 1) | 488 | if (bitmap_weight((unsigned long *)&pq_flags, |
489 | sizeof(pq_flags) * BITS_PER_BYTE) > 1) { | ||
490 | DP_ERR(p_hwfn, "requested multiple pq flags 0x%x\n", pq_flags); | ||
491 | goto err; | ||
492 | } | ||
493 | |||
494 | if (!(qed_get_pq_flags(p_hwfn) & pq_flags)) { | ||
495 | DP_ERR(p_hwfn, "pq flag 0x%x is not set\n", pq_flags); | ||
485 | goto err; | 496 | goto err; |
497 | } | ||
486 | 498 | ||
487 | switch (pq_flags) { | 499 | switch (pq_flags) { |
488 | case PQ_FLAGS_RLS: | 500 | case PQ_FLAGS_RLS: |
@@ -506,8 +518,7 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn, | |||
506 | } | 518 | } |
507 | 519 | ||
508 | err: | 520 | err: |
509 | DP_ERR(p_hwfn, "BAD pq flags %d\n", pq_flags); | 521 | return &qm_info->start_pq; |
510 | return NULL; | ||
511 | } | 522 | } |
512 | 523 | ||
513 | /* save pq index in qm info */ | 524 | /* save pq index in qm info */ |
@@ -531,20 +542,32 @@ u16 qed_get_cm_pq_idx_mcos(struct qed_hwfn *p_hwfn, u8 tc) | |||
531 | { | 542 | { |
532 | u8 max_tc = qed_init_qm_get_num_tcs(p_hwfn); | 543 | u8 max_tc = qed_init_qm_get_num_tcs(p_hwfn); |
533 | 544 | ||
545 | if (max_tc == 0) { | ||
546 | DP_ERR(p_hwfn, "pq with flag 0x%lx do not exist\n", | ||
547 | PQ_FLAGS_MCOS); | ||
548 | return p_hwfn->qm_info.start_pq; | ||
549 | } | ||
550 | |||
534 | if (tc > max_tc) | 551 | if (tc > max_tc) |
535 | DP_ERR(p_hwfn, "tc %d must be smaller than %d\n", tc, max_tc); | 552 | DP_ERR(p_hwfn, "tc %d must be smaller than %d\n", tc, max_tc); |
536 | 553 | ||
537 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + tc; | 554 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + (tc % max_tc); |
538 | } | 555 | } |
539 | 556 | ||
540 | u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf) | 557 | u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf) |
541 | { | 558 | { |
542 | u16 max_vf = qed_init_qm_get_num_vfs(p_hwfn); | 559 | u16 max_vf = qed_init_qm_get_num_vfs(p_hwfn); |
543 | 560 | ||
561 | if (max_vf == 0) { | ||
562 | DP_ERR(p_hwfn, "pq with flag 0x%lx do not exist\n", | ||
563 | PQ_FLAGS_VFS); | ||
564 | return p_hwfn->qm_info.start_pq; | ||
565 | } | ||
566 | |||
544 | if (vf > max_vf) | 567 | if (vf > max_vf) |
545 | DP_ERR(p_hwfn, "vf %d must be smaller than %d\n", vf, max_vf); | 568 | DP_ERR(p_hwfn, "vf %d must be smaller than %d\n", vf, max_vf); |
546 | 569 | ||
547 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf; | 570 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + (vf % max_vf); |
548 | } | 571 | } |
549 | 572 | ||
550 | u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc) | 573 | u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc) |
@@ -1081,6 +1104,12 @@ int qed_resc_alloc(struct qed_dev *cdev) | |||
1081 | goto alloc_err; | 1104 | goto alloc_err; |
1082 | } | 1105 | } |
1083 | 1106 | ||
1107 | if (QED_IS_RDMA_PERSONALITY(p_hwfn)) { | ||
1108 | rc = qed_rdma_info_alloc(p_hwfn); | ||
1109 | if (rc) | ||
1110 | goto alloc_err; | ||
1111 | } | ||
1112 | |||
1084 | /* DMA info initialization */ | 1113 | /* DMA info initialization */ |
1085 | rc = qed_dmae_info_alloc(p_hwfn); | 1114 | rc = qed_dmae_info_alloc(p_hwfn); |
1086 | if (rc) | 1115 | if (rc) |
@@ -2102,11 +2131,8 @@ int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn) | |||
2102 | if (!p_ptt) | 2131 | if (!p_ptt) |
2103 | return -EAGAIN; | 2132 | return -EAGAIN; |
2104 | 2133 | ||
2105 | /* If roce info is allocated it means roce is initialized and should | ||
2106 | * be enabled in searcher. | ||
2107 | */ | ||
2108 | if (p_hwfn->p_rdma_info && | 2134 | if (p_hwfn->p_rdma_info && |
2109 | p_hwfn->b_rdma_enabled_in_prs) | 2135 | p_hwfn->p_rdma_info->active && p_hwfn->b_rdma_enabled_in_prs) |
2110 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0x1); | 2136 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0x1); |
2111 | 2137 | ||
2112 | /* Re-open incoming traffic */ | 2138 | /* Re-open incoming traffic */ |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index 0f0aba793352..b22f464ea3fa 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c | |||
@@ -992,6 +992,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn) | |||
992 | */ | 992 | */ |
993 | do { | 993 | do { |
994 | index = p_sb_attn->sb_index; | 994 | index = p_sb_attn->sb_index; |
995 | /* finish reading index before the loop condition */ | ||
996 | dma_rmb(); | ||
995 | attn_bits = le32_to_cpu(p_sb_attn->atten_bits); | 997 | attn_bits = le32_to_cpu(p_sb_attn->atten_bits); |
996 | attn_acks = le32_to_cpu(p_sb_attn->atten_ack); | 998 | attn_acks = le32_to_cpu(p_sb_attn->atten_ack); |
997 | } while (index != p_sb_attn->sb_index); | 999 | } while (index != p_sb_attn->sb_index); |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 35fd0db6a677..fff7f04d4525 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c | |||
@@ -1782,9 +1782,9 @@ static int qed_drain(struct qed_dev *cdev) | |||
1782 | return -EBUSY; | 1782 | return -EBUSY; |
1783 | } | 1783 | } |
1784 | rc = qed_mcp_drain(hwfn, ptt); | 1784 | rc = qed_mcp_drain(hwfn, ptt); |
1785 | qed_ptt_release(hwfn, ptt); | ||
1785 | if (rc) | 1786 | if (rc) |
1786 | return rc; | 1787 | return rc; |
1787 | qed_ptt_release(hwfn, ptt); | ||
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | return 0; | 1790 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c index 62113438c880..7873d6dfd91f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c | |||
@@ -140,22 +140,34 @@ static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id) | |||
140 | return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id; | 140 | return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int qed_rdma_alloc(struct qed_hwfn *p_hwfn, | 143 | int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) |
144 | struct qed_ptt *p_ptt, | ||
145 | struct qed_rdma_start_in_params *params) | ||
146 | { | 144 | { |
147 | struct qed_rdma_info *p_rdma_info; | 145 | struct qed_rdma_info *p_rdma_info; |
148 | u32 num_cons, num_tasks; | ||
149 | int rc = -ENOMEM; | ||
150 | 146 | ||
151 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n"); | ||
152 | |||
153 | /* Allocate a struct with current pf rdma info */ | ||
154 | p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL); | 147 | p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL); |
155 | if (!p_rdma_info) | 148 | if (!p_rdma_info) |
156 | return rc; | 149 | return -ENOMEM; |
150 | |||
151 | spin_lock_init(&p_rdma_info->lock); | ||
157 | 152 | ||
158 | p_hwfn->p_rdma_info = p_rdma_info; | 153 | p_hwfn->p_rdma_info = p_rdma_info; |
154 | return 0; | ||
155 | } | ||
156 | |||
157 | void qed_rdma_info_free(struct qed_hwfn *p_hwfn) | ||
158 | { | ||
159 | kfree(p_hwfn->p_rdma_info); | ||
160 | p_hwfn->p_rdma_info = NULL; | ||
161 | } | ||
162 | |||
163 | static int qed_rdma_alloc(struct qed_hwfn *p_hwfn) | ||
164 | { | ||
165 | struct qed_rdma_info *p_rdma_info = p_hwfn->p_rdma_info; | ||
166 | u32 num_cons, num_tasks; | ||
167 | int rc = -ENOMEM; | ||
168 | |||
169 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n"); | ||
170 | |||
159 | if (QED_IS_IWARP_PERSONALITY(p_hwfn)) | 171 | if (QED_IS_IWARP_PERSONALITY(p_hwfn)) |
160 | p_rdma_info->proto = PROTOCOLID_IWARP; | 172 | p_rdma_info->proto = PROTOCOLID_IWARP; |
161 | else | 173 | else |
@@ -183,7 +195,7 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn, | |||
183 | /* Allocate a struct with device params and fill it */ | 195 | /* Allocate a struct with device params and fill it */ |
184 | p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL); | 196 | p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL); |
185 | if (!p_rdma_info->dev) | 197 | if (!p_rdma_info->dev) |
186 | goto free_rdma_info; | 198 | return rc; |
187 | 199 | ||
188 | /* Allocate a struct with port params and fill it */ | 200 | /* Allocate a struct with port params and fill it */ |
189 | p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL); | 201 | p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL); |
@@ -298,8 +310,6 @@ free_rdma_port: | |||
298 | kfree(p_rdma_info->port); | 310 | kfree(p_rdma_info->port); |
299 | free_rdma_dev: | 311 | free_rdma_dev: |
300 | kfree(p_rdma_info->dev); | 312 | kfree(p_rdma_info->dev); |
301 | free_rdma_info: | ||
302 | kfree(p_rdma_info); | ||
303 | 313 | ||
304 | return rc; | 314 | return rc; |
305 | } | 315 | } |
@@ -370,8 +380,6 @@ static void qed_rdma_resc_free(struct qed_hwfn *p_hwfn) | |||
370 | 380 | ||
371 | kfree(p_rdma_info->port); | 381 | kfree(p_rdma_info->port); |
372 | kfree(p_rdma_info->dev); | 382 | kfree(p_rdma_info->dev); |
373 | |||
374 | kfree(p_rdma_info); | ||
375 | } | 383 | } |
376 | 384 | ||
377 | static void qed_rdma_free_tid(void *rdma_cxt, u32 itid) | 385 | static void qed_rdma_free_tid(void *rdma_cxt, u32 itid) |
@@ -679,8 +687,6 @@ static int qed_rdma_setup(struct qed_hwfn *p_hwfn, | |||
679 | 687 | ||
680 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n"); | 688 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n"); |
681 | 689 | ||
682 | spin_lock_init(&p_hwfn->p_rdma_info->lock); | ||
683 | |||
684 | qed_rdma_init_devinfo(p_hwfn, params); | 690 | qed_rdma_init_devinfo(p_hwfn, params); |
685 | qed_rdma_init_port(p_hwfn); | 691 | qed_rdma_init_port(p_hwfn); |
686 | qed_rdma_init_events(p_hwfn, params); | 692 | qed_rdma_init_events(p_hwfn, params); |
@@ -727,7 +733,7 @@ static int qed_rdma_stop(void *rdma_cxt) | |||
727 | /* Disable RoCE search */ | 733 | /* Disable RoCE search */ |
728 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0); | 734 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0); |
729 | p_hwfn->b_rdma_enabled_in_prs = false; | 735 | p_hwfn->b_rdma_enabled_in_prs = false; |
730 | 736 | p_hwfn->p_rdma_info->active = 0; | |
731 | qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0); | 737 | qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0); |
732 | 738 | ||
733 | ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN); | 739 | ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN); |
@@ -1236,7 +1242,8 @@ qed_rdma_create_qp(void *rdma_cxt, | |||
1236 | u8 max_stats_queues; | 1242 | u8 max_stats_queues; |
1237 | int rc; | 1243 | int rc; |
1238 | 1244 | ||
1239 | if (!rdma_cxt || !in_params || !out_params || !p_hwfn->p_rdma_info) { | 1245 | if (!rdma_cxt || !in_params || !out_params || |
1246 | !p_hwfn->p_rdma_info->active) { | ||
1240 | DP_ERR(p_hwfn->cdev, | 1247 | DP_ERR(p_hwfn->cdev, |
1241 | "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", | 1248 | "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", |
1242 | rdma_cxt, in_params, out_params); | 1249 | rdma_cxt, in_params, out_params); |
@@ -1802,8 +1809,8 @@ bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn) | |||
1802 | { | 1809 | { |
1803 | bool result; | 1810 | bool result; |
1804 | 1811 | ||
1805 | /* if rdma info has not been allocated, naturally there are no qps */ | 1812 | /* if rdma wasn't activated yet, naturally there are no qps */ |
1806 | if (!p_hwfn->p_rdma_info) | 1813 | if (!p_hwfn->p_rdma_info->active) |
1807 | return false; | 1814 | return false; |
1808 | 1815 | ||
1809 | spin_lock_bh(&p_hwfn->p_rdma_info->lock); | 1816 | spin_lock_bh(&p_hwfn->p_rdma_info->lock); |
@@ -1849,7 +1856,7 @@ static int qed_rdma_start(void *rdma_cxt, | |||
1849 | if (!p_ptt) | 1856 | if (!p_ptt) |
1850 | goto err; | 1857 | goto err; |
1851 | 1858 | ||
1852 | rc = qed_rdma_alloc(p_hwfn, p_ptt, params); | 1859 | rc = qed_rdma_alloc(p_hwfn); |
1853 | if (rc) | 1860 | if (rc) |
1854 | goto err1; | 1861 | goto err1; |
1855 | 1862 | ||
@@ -1858,6 +1865,7 @@ static int qed_rdma_start(void *rdma_cxt, | |||
1858 | goto err2; | 1865 | goto err2; |
1859 | 1866 | ||
1860 | qed_ptt_release(p_hwfn, p_ptt); | 1867 | qed_ptt_release(p_hwfn, p_ptt); |
1868 | p_hwfn->p_rdma_info->active = 1; | ||
1861 | 1869 | ||
1862 | return rc; | 1870 | return rc; |
1863 | 1871 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.h b/drivers/net/ethernet/qlogic/qed/qed_rdma.h index 6f722ee8ee94..3689fe3e5935 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.h +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.h | |||
@@ -102,6 +102,7 @@ struct qed_rdma_info { | |||
102 | u16 max_queue_zones; | 102 | u16 max_queue_zones; |
103 | enum protocol_type proto; | 103 | enum protocol_type proto; |
104 | struct qed_iwarp_info iwarp; | 104 | struct qed_iwarp_info iwarp; |
105 | u8 active:1; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | struct qed_rdma_qp { | 108 | struct qed_rdma_qp { |
@@ -176,10 +177,14 @@ struct qed_rdma_qp { | |||
176 | #if IS_ENABLED(CONFIG_QED_RDMA) | 177 | #if IS_ENABLED(CONFIG_QED_RDMA) |
177 | void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | 178 | void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); |
178 | void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | 179 | void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); |
180 | int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn); | ||
181 | void qed_rdma_info_free(struct qed_hwfn *p_hwfn); | ||
179 | #else | 182 | #else |
180 | static inline void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {} | 183 | static inline void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {} |
181 | static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, | 184 | static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, |
182 | struct qed_ptt *p_ptt) {} | 185 | struct qed_ptt *p_ptt) {} |
186 | static inline int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) {return -EINVAL;} | ||
187 | static inline void qed_rdma_info_free(struct qed_hwfn *p_hwfn) {} | ||
183 | #endif | 188 | #endif |
184 | 189 | ||
185 | int | 190 | int |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 33265747bf39..0fbcedcdf6e2 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -63,7 +63,7 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) | |||
63 | * assume the pin serves as pull-up. If direction is | 63 | * assume the pin serves as pull-up. If direction is |
64 | * output, the default value is high. | 64 | * output, the default value is high. |
65 | */ | 65 | */ |
66 | gpiod_set_value(bitbang->mdo, 1); | 66 | gpiod_set_value_cansleep(bitbang->mdo, 1); |
67 | return; | 67 | return; |
68 | } | 68 | } |
69 | 69 | ||
@@ -78,7 +78,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl) | |||
78 | struct mdio_gpio_info *bitbang = | 78 | struct mdio_gpio_info *bitbang = |
79 | container_of(ctrl, struct mdio_gpio_info, ctrl); | 79 | container_of(ctrl, struct mdio_gpio_info, ctrl); |
80 | 80 | ||
81 | return gpiod_get_value(bitbang->mdio); | 81 | return gpiod_get_value_cansleep(bitbang->mdio); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void mdio_set(struct mdiobb_ctrl *ctrl, int what) | 84 | static void mdio_set(struct mdiobb_ctrl *ctrl, int what) |
@@ -87,9 +87,9 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what) | |||
87 | container_of(ctrl, struct mdio_gpio_info, ctrl); | 87 | container_of(ctrl, struct mdio_gpio_info, ctrl); |
88 | 88 | ||
89 | if (bitbang->mdo) | 89 | if (bitbang->mdo) |
90 | gpiod_set_value(bitbang->mdo, what); | 90 | gpiod_set_value_cansleep(bitbang->mdo, what); |
91 | else | 91 | else |
92 | gpiod_set_value(bitbang->mdio, what); | 92 | gpiod_set_value_cansleep(bitbang->mdio, what); |
93 | } | 93 | } |
94 | 94 | ||
95 | static void mdc_set(struct mdiobb_ctrl *ctrl, int what) | 95 | static void mdc_set(struct mdiobb_ctrl *ctrl, int what) |
@@ -97,7 +97,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what) | |||
97 | struct mdio_gpio_info *bitbang = | 97 | struct mdio_gpio_info *bitbang = |
98 | container_of(ctrl, struct mdio_gpio_info, ctrl); | 98 | container_of(ctrl, struct mdio_gpio_info, ctrl); |
99 | 99 | ||
100 | gpiod_set_value(bitbang->mdc, what); | 100 | gpiod_set_value_cansleep(bitbang->mdc, what); |
101 | } | 101 | } |
102 | 102 | ||
103 | static const struct mdiobb_ops mdio_gpio_ops = { | 103 | static const struct mdiobb_ops mdio_gpio_ops = { |
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c index a2e59f4f6f01..7cae17517744 100644 --- a/drivers/net/phy/mscc.c +++ b/drivers/net/phy/mscc.c | |||
@@ -810,17 +810,13 @@ static int vsc85xx_default_config(struct phy_device *phydev) | |||
810 | 810 | ||
811 | phydev->mdix_ctrl = ETH_TP_MDI_AUTO; | 811 | phydev->mdix_ctrl = ETH_TP_MDI_AUTO; |
812 | mutex_lock(&phydev->lock); | 812 | mutex_lock(&phydev->lock); |
813 | rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2); | ||
814 | if (rc < 0) | ||
815 | goto out_unlock; | ||
816 | 813 | ||
817 | reg_val = phy_read(phydev, MSCC_PHY_RGMII_CNTL); | 814 | reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS; |
818 | reg_val &= ~(RGMII_RX_CLK_DELAY_MASK); | 815 | |
819 | reg_val |= (RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS); | 816 | rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, |
820 | phy_write(phydev, MSCC_PHY_RGMII_CNTL, reg_val); | 817 | MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK, |
818 | reg_val); | ||
821 | 819 | ||
822 | out_unlock: | ||
823 | rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc); | ||
824 | mutex_unlock(&phydev->lock); | 820 | mutex_unlock(&phydev->lock); |
825 | 821 | ||
826 | return rc; | 822 | return rc; |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index db633ae9f784..364f514d56d8 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -985,8 +985,6 @@ static void team_port_disable(struct team *team, | |||
985 | team->en_port_count--; | 985 | team->en_port_count--; |
986 | team_queue_override_port_del(team, port); | 986 | team_queue_override_port_del(team, port); |
987 | team_adjust_ops(team); | 987 | team_adjust_ops(team); |
988 | team_notify_peers(team); | ||
989 | team_mcast_rejoin(team); | ||
990 | team_lower_state_changed(port); | 988 | team_lower_state_changed(port); |
991 | } | 989 | } |
992 | 990 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 060135ceaf0e..e244f5d7512a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1536,6 +1536,7 @@ static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile, | |||
1536 | 1536 | ||
1537 | if (!rx_batched || (!more && skb_queue_empty(queue))) { | 1537 | if (!rx_batched || (!more && skb_queue_empty(queue))) { |
1538 | local_bh_disable(); | 1538 | local_bh_disable(); |
1539 | skb_record_rx_queue(skb, tfile->queue_index); | ||
1539 | netif_receive_skb(skb); | 1540 | netif_receive_skb(skb); |
1540 | local_bh_enable(); | 1541 | local_bh_enable(); |
1541 | return; | 1542 | return; |
@@ -1555,8 +1556,11 @@ static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile, | |||
1555 | struct sk_buff *nskb; | 1556 | struct sk_buff *nskb; |
1556 | 1557 | ||
1557 | local_bh_disable(); | 1558 | local_bh_disable(); |
1558 | while ((nskb = __skb_dequeue(&process_queue))) | 1559 | while ((nskb = __skb_dequeue(&process_queue))) { |
1560 | skb_record_rx_queue(nskb, tfile->queue_index); | ||
1559 | netif_receive_skb(nskb); | 1561 | netif_receive_skb(nskb); |
1562 | } | ||
1563 | skb_record_rx_queue(skb, tfile->queue_index); | ||
1560 | netif_receive_skb(skb); | 1564 | netif_receive_skb(skb); |
1561 | local_bh_enable(); | 1565 | local_bh_enable(); |
1562 | } | 1566 | } |
@@ -2451,6 +2455,7 @@ build: | |||
2451 | if (!rcu_dereference(tun->steering_prog)) | 2455 | if (!rcu_dereference(tun->steering_prog)) |
2452 | rxhash = __skb_get_hash_symmetric(skb); | 2456 | rxhash = __skb_get_hash_symmetric(skb); |
2453 | 2457 | ||
2458 | skb_record_rx_queue(skb, tfile->queue_index); | ||
2454 | netif_receive_skb(skb); | 2459 | netif_receive_skb(skb); |
2455 | 2460 | ||
2456 | stats = get_cpu_ptr(tun->pcpu_stats); | 2461 | stats = get_cpu_ptr(tun->pcpu_stats); |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 3e2c041d76ac..cecfd77c9f3c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -70,7 +70,8 @@ static const unsigned long guest_offloads[] = { | |||
70 | VIRTIO_NET_F_GUEST_TSO4, | 70 | VIRTIO_NET_F_GUEST_TSO4, |
71 | VIRTIO_NET_F_GUEST_TSO6, | 71 | VIRTIO_NET_F_GUEST_TSO6, |
72 | VIRTIO_NET_F_GUEST_ECN, | 72 | VIRTIO_NET_F_GUEST_ECN, |
73 | VIRTIO_NET_F_GUEST_UFO | 73 | VIRTIO_NET_F_GUEST_UFO, |
74 | VIRTIO_NET_F_GUEST_CSUM | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | struct virtnet_stat_desc { | 77 | struct virtnet_stat_desc { |
@@ -2334,9 +2335,6 @@ static int virtnet_clear_guest_offloads(struct virtnet_info *vi) | |||
2334 | if (!vi->guest_offloads) | 2335 | if (!vi->guest_offloads) |
2335 | return 0; | 2336 | return 0; |
2336 | 2337 | ||
2337 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM)) | ||
2338 | offloads = 1ULL << VIRTIO_NET_F_GUEST_CSUM; | ||
2339 | |||
2340 | return virtnet_set_guest_offloads(vi, offloads); | 2338 | return virtnet_set_guest_offloads(vi, offloads); |
2341 | } | 2339 | } |
2342 | 2340 | ||
@@ -2346,8 +2344,6 @@ static int virtnet_restore_guest_offloads(struct virtnet_info *vi) | |||
2346 | 2344 | ||
2347 | if (!vi->guest_offloads) | 2345 | if (!vi->guest_offloads) |
2348 | return 0; | 2346 | return 0; |
2349 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM)) | ||
2350 | offloads |= 1ULL << VIRTIO_NET_F_GUEST_CSUM; | ||
2351 | 2347 | ||
2352 | return virtnet_set_guest_offloads(vi, offloads); | 2348 | return virtnet_set_guest_offloads(vi, offloads); |
2353 | } | 2349 | } |
@@ -2365,8 +2361,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, | |||
2365 | && (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) || | 2361 | && (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) || |
2366 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) || | 2362 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) || |
2367 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || | 2363 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || |
2368 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO))) { | 2364 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) || |
2369 | NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO, disable LRO first"); | 2365 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) { |
2366 | NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO/CSUM, disable LRO/CSUM first"); | ||
2370 | return -EOPNOTSUPP; | 2367 | return -EOPNOTSUPP; |
2371 | } | 2368 | } |
2372 | 2369 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a1c2801ded10..7e49342bae38 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -6867,7 +6867,7 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
6867 | u32 bitmap; | 6867 | u32 bitmap; |
6868 | 6868 | ||
6869 | if (drop) { | 6869 | if (drop) { |
6870 | if (vif->type == NL80211_IFTYPE_STATION) { | 6870 | if (vif && vif->type == NL80211_IFTYPE_STATION) { |
6871 | bitmap = ~(1 << WMI_MGMT_TID); | 6871 | bitmap = ~(1 << WMI_MGMT_TID); |
6872 | list_for_each_entry(arvif, &ar->arvifs, list) { | 6872 | list_for_each_entry(arvif, &ar->arvifs, list) { |
6873 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) | 6873 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1e3b5f4a4cf9..f23cb2f3d296 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1251,6 +1251,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1251 | struct ath_vif *avp = (void *)vif->drv_priv; | 1251 | struct ath_vif *avp = (void *)vif->drv_priv; |
1252 | struct ath_node *an = &avp->mcast_node; | 1252 | struct ath_node *an = &avp->mcast_node; |
1253 | 1253 | ||
1254 | mutex_lock(&sc->mutex); | ||
1254 | if (IS_ENABLED(CONFIG_ATH9K_TX99)) { | 1255 | if (IS_ENABLED(CONFIG_ATH9K_TX99)) { |
1255 | if (sc->cur_chan->nvifs >= 1) { | 1256 | if (sc->cur_chan->nvifs >= 1) { |
1256 | mutex_unlock(&sc->mutex); | 1257 | mutex_unlock(&sc->mutex); |
@@ -1259,8 +1260,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1259 | sc->tx99_vif = vif; | 1260 | sc->tx99_vif = vif; |
1260 | } | 1261 | } |
1261 | 1262 | ||
1262 | mutex_lock(&sc->mutex); | ||
1263 | |||
1264 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); | 1263 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); |
1265 | sc->cur_chan->nvifs++; | 1264 | sc->cur_chan->nvifs++; |
1266 | 1265 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 230a378c26fc..7f0a5bade70a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |||
@@ -6005,7 +6005,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, | |||
6005 | * for subsequent chanspecs. | 6005 | * for subsequent chanspecs. |
6006 | */ | 6006 | */ |
6007 | channel->flags = IEEE80211_CHAN_NO_HT40 | | 6007 | channel->flags = IEEE80211_CHAN_NO_HT40 | |
6008 | IEEE80211_CHAN_NO_80MHZ; | 6008 | IEEE80211_CHAN_NO_80MHZ | |
6009 | IEEE80211_CHAN_NO_160MHZ; | ||
6009 | ch.bw = BRCMU_CHAN_BW_20; | 6010 | ch.bw = BRCMU_CHAN_BW_20; |
6010 | cfg->d11inf.encchspec(&ch); | 6011 | cfg->d11inf.encchspec(&ch); |
6011 | chaninfo = ch.chspec; | 6012 | chaninfo = ch.chspec; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c index e7584b842dce..eb5db94f5745 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c | |||
@@ -193,6 +193,9 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) | |||
193 | } | 193 | } |
194 | break; | 194 | break; |
195 | case BRCMU_CHSPEC_D11AC_BW_160: | 195 | case BRCMU_CHSPEC_D11AC_BW_160: |
196 | ch->bw = BRCMU_CHAN_BW_160; | ||
197 | ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK, | ||
198 | BRCMU_CHSPEC_D11AC_SB_SHIFT); | ||
196 | switch (ch->sb) { | 199 | switch (ch->sb) { |
197 | case BRCMU_CHAN_SB_LLL: | 200 | case BRCMU_CHAN_SB_LLL: |
198 | ch->control_ch_num -= CH_70MHZ_APART; | 201 | ch->control_ch_num -= CH_70MHZ_APART; |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 2439e98431ee..7492dfb6729b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
9 | * Copyright(c) 2018 Intel Corporation | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -26,6 +27,7 @@ | |||
26 | * BSD LICENSE | 27 | * BSD LICENSE |
27 | * | 28 | * |
28 | * Copyright(c) 2017 Intel Deutschland GmbH | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
30 | * Copyright(c) 2018 Intel Corporation | ||
29 | * All rights reserved. | 31 | * All rights reserved. |
30 | * | 32 | * |
31 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without |
@@ -81,7 +83,7 @@ | |||
81 | #define ACPI_WRDS_WIFI_DATA_SIZE (ACPI_SAR_TABLE_SIZE + 2) | 83 | #define ACPI_WRDS_WIFI_DATA_SIZE (ACPI_SAR_TABLE_SIZE + 2) |
82 | #define ACPI_EWRD_WIFI_DATA_SIZE ((ACPI_SAR_PROFILE_NUM - 1) * \ | 84 | #define ACPI_EWRD_WIFI_DATA_SIZE ((ACPI_SAR_PROFILE_NUM - 1) * \ |
83 | ACPI_SAR_TABLE_SIZE + 3) | 85 | ACPI_SAR_TABLE_SIZE + 3) |
84 | #define ACPI_WGDS_WIFI_DATA_SIZE 18 | 86 | #define ACPI_WGDS_WIFI_DATA_SIZE 19 |
85 | #define ACPI_WRDD_WIFI_DATA_SIZE 2 | 87 | #define ACPI_WRDD_WIFI_DATA_SIZE 2 |
86 | #define ACPI_SPLC_WIFI_DATA_SIZE 2 | 88 | #define ACPI_SPLC_WIFI_DATA_SIZE 2 |
87 | 89 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 6b95d0e75889..2b8b50a77990 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h | |||
@@ -154,7 +154,11 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, | |||
154 | const struct iwl_fw_runtime_ops *ops, void *ops_ctx, | 154 | const struct iwl_fw_runtime_ops *ops, void *ops_ctx, |
155 | struct dentry *dbgfs_dir); | 155 | struct dentry *dbgfs_dir); |
156 | 156 | ||
157 | void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt); | 157 | static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt) |
158 | { | ||
159 | kfree(fwrt->dump.d3_debug_data); | ||
160 | fwrt->dump.d3_debug_data = NULL; | ||
161 | } | ||
158 | 162 | ||
159 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); | 163 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); |
160 | 164 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index dade206d5511..2ba890445c35 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c | |||
@@ -893,7 +893,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) | |||
893 | IWL_DEBUG_RADIO(mvm, "Sending GEO_TX_POWER_LIMIT\n"); | 893 | IWL_DEBUG_RADIO(mvm, "Sending GEO_TX_POWER_LIMIT\n"); |
894 | 894 | ||
895 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS * | 895 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS * |
896 | ACPI_WGDS_TABLE_SIZE != ACPI_WGDS_WIFI_DATA_SIZE); | 896 | ACPI_WGDS_TABLE_SIZE + 1 != ACPI_WGDS_WIFI_DATA_SIZE); |
897 | 897 | ||
898 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES > IWL_NUM_GEO_PROFILES); | 898 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES > IWL_NUM_GEO_PROFILES); |
899 | 899 | ||
@@ -928,6 +928,11 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm) | |||
928 | return -ENOENT; | 928 | return -ENOENT; |
929 | } | 929 | } |
930 | 930 | ||
931 | static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) | ||
932 | { | ||
933 | return -ENOENT; | ||
934 | } | ||
935 | |||
931 | static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) | 936 | static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) |
932 | { | 937 | { |
933 | return 0; | 938 | return 0; |
@@ -954,8 +959,11 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm) | |||
954 | IWL_DEBUG_RADIO(mvm, | 959 | IWL_DEBUG_RADIO(mvm, |
955 | "WRDS SAR BIOS table invalid or unavailable. (%d)\n", | 960 | "WRDS SAR BIOS table invalid or unavailable. (%d)\n", |
956 | ret); | 961 | ret); |
957 | /* if not available, don't fail and don't bother with EWRD */ | 962 | /* |
958 | return 0; | 963 | * If not available, don't fail and don't bother with EWRD. |
964 | * Return 1 to tell that we can't use WGDS either. | ||
965 | */ | ||
966 | return 1; | ||
959 | } | 967 | } |
960 | 968 | ||
961 | ret = iwl_mvm_sar_get_ewrd_table(mvm); | 969 | ret = iwl_mvm_sar_get_ewrd_table(mvm); |
@@ -968,9 +976,13 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm) | |||
968 | /* choose profile 1 (WRDS) as default for both chains */ | 976 | /* choose profile 1 (WRDS) as default for both chains */ |
969 | ret = iwl_mvm_sar_select_profile(mvm, 1, 1); | 977 | ret = iwl_mvm_sar_select_profile(mvm, 1, 1); |
970 | 978 | ||
971 | /* if we don't have profile 0 from BIOS, just skip it */ | 979 | /* |
980 | * If we don't have profile 0 from BIOS, just skip it. This | ||
981 | * means that SAR Geo will not be enabled either, even if we | ||
982 | * have other valid profiles. | ||
983 | */ | ||
972 | if (ret == -ENOENT) | 984 | if (ret == -ENOENT) |
973 | return 0; | 985 | return 1; |
974 | 986 | ||
975 | return ret; | 987 | return ret; |
976 | } | 988 | } |
@@ -1168,11 +1180,19 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
1168 | iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); | 1180 | iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); |
1169 | 1181 | ||
1170 | ret = iwl_mvm_sar_init(mvm); | 1182 | ret = iwl_mvm_sar_init(mvm); |
1171 | if (ret) | 1183 | if (ret == 0) { |
1172 | goto error; | 1184 | ret = iwl_mvm_sar_geo_init(mvm); |
1185 | } else if (ret > 0 && !iwl_mvm_sar_get_wgds_table(mvm)) { | ||
1186 | /* | ||
1187 | * If basic SAR is not available, we check for WGDS, | ||
1188 | * which should *not* be available either. If it is | ||
1189 | * available, issue an error, because we can't use SAR | ||
1190 | * Geo without basic SAR. | ||
1191 | */ | ||
1192 | IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n"); | ||
1193 | } | ||
1173 | 1194 | ||
1174 | ret = iwl_mvm_sar_geo_init(mvm); | 1195 | if (ret < 0) |
1175 | if (ret) | ||
1176 | goto error; | 1196 | goto error; |
1177 | 1197 | ||
1178 | iwl_mvm_leds_sync(mvm); | 1198 | iwl_mvm_leds_sync(mvm); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 505b0385d800..00f831d88366 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | |||
@@ -301,8 +301,12 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy, | |||
301 | goto out; | 301 | goto out; |
302 | } | 302 | } |
303 | 303 | ||
304 | if (changed) | 304 | if (changed) { |
305 | *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE); | 305 | u32 status = le32_to_cpu(resp->status); |
306 | |||
307 | *changed = (status == MCC_RESP_NEW_CHAN_PROFILE || | ||
308 | status == MCC_RESP_ILLEGAL); | ||
309 | } | ||
306 | 310 | ||
307 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, | 311 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, |
308 | __le32_to_cpu(resp->n_channels), | 312 | __le32_to_cpu(resp->n_channels), |
@@ -4444,10 +4448,6 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, | |||
4444 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); | 4448 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); |
4445 | } | 4449 | } |
4446 | 4450 | ||
4447 | if (!fw_has_capa(&mvm->fw->ucode_capa, | ||
4448 | IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS)) | ||
4449 | return; | ||
4450 | |||
4451 | /* if beacon filtering isn't on mac80211 does it anyway */ | 4451 | /* if beacon filtering isn't on mac80211 does it anyway */ |
4452 | if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) | 4452 | if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) |
4453 | return; | 4453 | return; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index 3633f27d048a..6fc5cc1f2b5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | |||
@@ -539,9 +539,8 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2, | |||
539 | } | 539 | } |
540 | 540 | ||
541 | IWL_DEBUG_LAR(mvm, | 541 | IWL_DEBUG_LAR(mvm, |
542 | "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') change: %d n_chans: %d\n", | 542 | "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') n_chans: %d\n", |
543 | status, mcc, mcc >> 8, mcc & 0xff, | 543 | status, mcc, mcc >> 8, mcc & 0xff, n_channels); |
544 | !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels); | ||
545 | 544 | ||
546 | exit: | 545 | exit: |
547 | iwl_free_resp(&cmd); | 546 | iwl_free_resp(&cmd); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0e2092526fae..af3fba10abc1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -858,6 +858,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
858 | iwl_mvm_thermal_exit(mvm); | 858 | iwl_mvm_thermal_exit(mvm); |
859 | out_free: | 859 | out_free: |
860 | iwl_fw_flush_dump(&mvm->fwrt); | 860 | iwl_fw_flush_dump(&mvm->fwrt); |
861 | iwl_fw_runtime_free(&mvm->fwrt); | ||
861 | 862 | ||
862 | if (iwlmvm_mod_params.init_dbg) | 863 | if (iwlmvm_mod_params.init_dbg) |
863 | return op_mode; | 864 | return op_mode; |
@@ -910,6 +911,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) | |||
910 | 911 | ||
911 | iwl_mvm_tof_clean(mvm); | 912 | iwl_mvm_tof_clean(mvm); |
912 | 913 | ||
914 | iwl_fw_runtime_free(&mvm->fwrt); | ||
913 | mutex_destroy(&mvm->mutex); | 915 | mutex_destroy(&mvm->mutex); |
914 | mutex_destroy(&mvm->d0i3_suspend_mutex); | 916 | mutex_destroy(&mvm->d0i3_suspend_mutex); |
915 | 917 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig index 0ccbcd7e887d..c30d8f5bbf2a 100644 --- a/drivers/net/wireless/mediatek/mt76/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/Kconfig | |||
@@ -1,6 +1,12 @@ | |||
1 | config MT76_CORE | 1 | config MT76_CORE |
2 | tristate | 2 | tristate |
3 | 3 | ||
4 | config MT76_LEDS | ||
5 | bool | ||
6 | depends on MT76_CORE | ||
7 | depends on LEDS_CLASS=y || MT76_CORE=LEDS_CLASS | ||
8 | default y | ||
9 | |||
4 | config MT76_USB | 10 | config MT76_USB |
5 | tristate | 11 | tristate |
6 | depends on MT76_CORE | 12 | depends on MT76_CORE |
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 2a699e8b79bf..7d219ff2d480 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c | |||
@@ -345,9 +345,11 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, | |||
345 | mt76_check_sband(dev, NL80211_BAND_2GHZ); | 345 | mt76_check_sband(dev, NL80211_BAND_2GHZ); |
346 | mt76_check_sband(dev, NL80211_BAND_5GHZ); | 346 | mt76_check_sband(dev, NL80211_BAND_5GHZ); |
347 | 347 | ||
348 | ret = mt76_led_init(dev); | 348 | if (IS_ENABLED(CONFIG_MT76_LEDS)) { |
349 | if (ret) | 349 | ret = mt76_led_init(dev); |
350 | return ret; | 350 | if (ret) |
351 | return ret; | ||
352 | } | ||
351 | 353 | ||
352 | return ieee80211_register_hw(hw); | 354 | return ieee80211_register_hw(hw); |
353 | } | 355 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h index 47c42c607964..7806963b1905 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h | |||
@@ -71,7 +71,6 @@ struct mt76x02_dev { | |||
71 | struct mac_address macaddr_list[8]; | 71 | struct mac_address macaddr_list[8]; |
72 | 72 | ||
73 | struct mutex phy_mutex; | 73 | struct mutex phy_mutex; |
74 | struct mutex mutex; | ||
75 | 74 | ||
76 | u8 txdone_seq; | 75 | u8 txdone_seq; |
77 | DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); | 76 | DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c index 3824290b219d..fd125722d1fb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | |||
@@ -507,8 +507,10 @@ int mt76x2_register_device(struct mt76x02_dev *dev) | |||
507 | mt76x2_dfs_init_detector(dev); | 507 | mt76x2_dfs_init_detector(dev); |
508 | 508 | ||
509 | /* init led callbacks */ | 509 | /* init led callbacks */ |
510 | dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; | 510 | if (IS_ENABLED(CONFIG_MT76_LEDS)) { |
511 | dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; | 511 | dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; |
512 | dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; | ||
513 | } | ||
512 | 514 | ||
513 | ret = mt76_register_device(&dev->mt76, true, mt76x02_rates, | 515 | ret = mt76_register_device(&dev->mt76, true, mt76x02_rates, |
514 | ARRAY_SIZE(mt76x02_rates)); | 516 | ARRAY_SIZE(mt76x02_rates)); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c index 034a06295668..3f001bd6806c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c | |||
@@ -272,9 +272,9 @@ mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val) | |||
272 | if (val != ~0 && val > 0xffff) | 272 | if (val != ~0 && val > 0xffff) |
273 | return -EINVAL; | 273 | return -EINVAL; |
274 | 274 | ||
275 | mutex_lock(&dev->mutex); | 275 | mutex_lock(&dev->mt76.mutex); |
276 | mt76x2_mac_set_tx_protection(dev, val); | 276 | mt76x2_mac_set_tx_protection(dev, val); |
277 | mutex_unlock(&dev->mutex); | 277 | mutex_unlock(&dev->mt76.mutex); |
278 | 278 | ||
279 | return 0; | 279 | return 0; |
280 | } | 280 | } |
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 4c2154b9e6a3..bd10165d7eec 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c | |||
@@ -285,7 +285,7 @@ static int wl1271_probe(struct sdio_func *func, | |||
285 | struct resource res[2]; | 285 | struct resource res[2]; |
286 | mmc_pm_flag_t mmcflags; | 286 | mmc_pm_flag_t mmcflags; |
287 | int ret = -ENOMEM; | 287 | int ret = -ENOMEM; |
288 | int irq, wakeirq; | 288 | int irq, wakeirq, num_irqs; |
289 | const char *chip_family; | 289 | const char *chip_family; |
290 | 290 | ||
291 | /* We are only able to handle the wlan function */ | 291 | /* We are only able to handle the wlan function */ |
@@ -353,12 +353,17 @@ static int wl1271_probe(struct sdio_func *func, | |||
353 | irqd_get_trigger_type(irq_get_irq_data(irq)); | 353 | irqd_get_trigger_type(irq_get_irq_data(irq)); |
354 | res[0].name = "irq"; | 354 | res[0].name = "irq"; |
355 | 355 | ||
356 | res[1].start = wakeirq; | ||
357 | res[1].flags = IORESOURCE_IRQ | | ||
358 | irqd_get_trigger_type(irq_get_irq_data(wakeirq)); | ||
359 | res[1].name = "wakeirq"; | ||
360 | 356 | ||
361 | ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res)); | 357 | if (wakeirq > 0) { |
358 | res[1].start = wakeirq; | ||
359 | res[1].flags = IORESOURCE_IRQ | | ||
360 | irqd_get_trigger_type(irq_get_irq_data(wakeirq)); | ||
361 | res[1].name = "wakeirq"; | ||
362 | num_irqs = 2; | ||
363 | } else { | ||
364 | num_irqs = 1; | ||
365 | } | ||
366 | ret = platform_device_add_resources(glue->core, res, num_irqs); | ||
362 | if (ret) { | 367 | if (ret) { |
363 | dev_err(glue->dev, "can't add resources\n"); | 368 | dev_err(glue->dev, "can't add resources\n"); |
364 | goto out_dev_put; | 369 | goto out_dev_put; |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 0b70c8bab045..54032c466636 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
@@ -152,6 +152,7 @@ struct nvme_fc_ctrl { | |||
152 | 152 | ||
153 | bool ioq_live; | 153 | bool ioq_live; |
154 | bool assoc_active; | 154 | bool assoc_active; |
155 | atomic_t err_work_active; | ||
155 | u64 association_id; | 156 | u64 association_id; |
156 | 157 | ||
157 | struct list_head ctrl_list; /* rport->ctrl_list */ | 158 | struct list_head ctrl_list; /* rport->ctrl_list */ |
@@ -160,6 +161,7 @@ struct nvme_fc_ctrl { | |||
160 | struct blk_mq_tag_set tag_set; | 161 | struct blk_mq_tag_set tag_set; |
161 | 162 | ||
162 | struct delayed_work connect_work; | 163 | struct delayed_work connect_work; |
164 | struct work_struct err_work; | ||
163 | 165 | ||
164 | struct kref ref; | 166 | struct kref ref; |
165 | u32 flags; | 167 | u32 flags; |
@@ -1531,6 +1533,10 @@ nvme_fc_abort_aen_ops(struct nvme_fc_ctrl *ctrl) | |||
1531 | struct nvme_fc_fcp_op *aen_op = ctrl->aen_ops; | 1533 | struct nvme_fc_fcp_op *aen_op = ctrl->aen_ops; |
1532 | int i; | 1534 | int i; |
1533 | 1535 | ||
1536 | /* ensure we've initialized the ops once */ | ||
1537 | if (!(aen_op->flags & FCOP_FLAGS_AEN)) | ||
1538 | return; | ||
1539 | |||
1534 | for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) | 1540 | for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) |
1535 | __nvme_fc_abort_op(ctrl, aen_op); | 1541 | __nvme_fc_abort_op(ctrl, aen_op); |
1536 | } | 1542 | } |
@@ -2049,7 +2055,25 @@ nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl) | |||
2049 | static void | 2055 | static void |
2050 | nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) | 2056 | nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) |
2051 | { | 2057 | { |
2052 | /* only proceed if in LIVE state - e.g. on first error */ | 2058 | int active; |
2059 | |||
2060 | /* | ||
2061 | * if an error (io timeout, etc) while (re)connecting, | ||
2062 | * it's an error on creating the new association. | ||
2063 | * Start the error recovery thread if it hasn't already | ||
2064 | * been started. It is expected there could be multiple | ||
2065 | * ios hitting this path before things are cleaned up. | ||
2066 | */ | ||
2067 | if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) { | ||
2068 | active = atomic_xchg(&ctrl->err_work_active, 1); | ||
2069 | if (!active && !schedule_work(&ctrl->err_work)) { | ||
2070 | atomic_set(&ctrl->err_work_active, 0); | ||
2071 | WARN_ON(1); | ||
2072 | } | ||
2073 | return; | ||
2074 | } | ||
2075 | |||
2076 | /* Otherwise, only proceed if in LIVE state - e.g. on first error */ | ||
2053 | if (ctrl->ctrl.state != NVME_CTRL_LIVE) | 2077 | if (ctrl->ctrl.state != NVME_CTRL_LIVE) |
2054 | return; | 2078 | return; |
2055 | 2079 | ||
@@ -2814,6 +2838,7 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) | |||
2814 | { | 2838 | { |
2815 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); | 2839 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); |
2816 | 2840 | ||
2841 | cancel_work_sync(&ctrl->err_work); | ||
2817 | cancel_delayed_work_sync(&ctrl->connect_work); | 2842 | cancel_delayed_work_sync(&ctrl->connect_work); |
2818 | /* | 2843 | /* |
2819 | * kill the association on the link side. this will block | 2844 | * kill the association on the link side. this will block |
@@ -2866,23 +2891,30 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status) | |||
2866 | } | 2891 | } |
2867 | 2892 | ||
2868 | static void | 2893 | static void |
2869 | nvme_fc_reset_ctrl_work(struct work_struct *work) | 2894 | __nvme_fc_terminate_io(struct nvme_fc_ctrl *ctrl) |
2870 | { | 2895 | { |
2871 | struct nvme_fc_ctrl *ctrl = | 2896 | nvme_stop_keep_alive(&ctrl->ctrl); |
2872 | container_of(work, struct nvme_fc_ctrl, ctrl.reset_work); | ||
2873 | int ret; | ||
2874 | |||
2875 | nvme_stop_ctrl(&ctrl->ctrl); | ||
2876 | 2897 | ||
2877 | /* will block will waiting for io to terminate */ | 2898 | /* will block will waiting for io to terminate */ |
2878 | nvme_fc_delete_association(ctrl); | 2899 | nvme_fc_delete_association(ctrl); |
2879 | 2900 | ||
2880 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { | 2901 | if (ctrl->ctrl.state != NVME_CTRL_CONNECTING && |
2902 | !nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) | ||
2881 | dev_err(ctrl->ctrl.device, | 2903 | dev_err(ctrl->ctrl.device, |
2882 | "NVME-FC{%d}: error_recovery: Couldn't change state " | 2904 | "NVME-FC{%d}: error_recovery: Couldn't change state " |
2883 | "to CONNECTING\n", ctrl->cnum); | 2905 | "to CONNECTING\n", ctrl->cnum); |
2884 | return; | 2906 | } |
2885 | } | 2907 | |
2908 | static void | ||
2909 | nvme_fc_reset_ctrl_work(struct work_struct *work) | ||
2910 | { | ||
2911 | struct nvme_fc_ctrl *ctrl = | ||
2912 | container_of(work, struct nvme_fc_ctrl, ctrl.reset_work); | ||
2913 | int ret; | ||
2914 | |||
2915 | __nvme_fc_terminate_io(ctrl); | ||
2916 | |||
2917 | nvme_stop_ctrl(&ctrl->ctrl); | ||
2886 | 2918 | ||
2887 | if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE) | 2919 | if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE) |
2888 | ret = nvme_fc_create_association(ctrl); | 2920 | ret = nvme_fc_create_association(ctrl); |
@@ -2897,6 +2929,24 @@ nvme_fc_reset_ctrl_work(struct work_struct *work) | |||
2897 | ctrl->cnum); | 2929 | ctrl->cnum); |
2898 | } | 2930 | } |
2899 | 2931 | ||
2932 | static void | ||
2933 | nvme_fc_connect_err_work(struct work_struct *work) | ||
2934 | { | ||
2935 | struct nvme_fc_ctrl *ctrl = | ||
2936 | container_of(work, struct nvme_fc_ctrl, err_work); | ||
2937 | |||
2938 | __nvme_fc_terminate_io(ctrl); | ||
2939 | |||
2940 | atomic_set(&ctrl->err_work_active, 0); | ||
2941 | |||
2942 | /* | ||
2943 | * Rescheduling the connection after recovering | ||
2944 | * from the io error is left to the reconnect work | ||
2945 | * item, which is what should have stalled waiting on | ||
2946 | * the io that had the error that scheduled this work. | ||
2947 | */ | ||
2948 | } | ||
2949 | |||
2900 | static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = { | 2950 | static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = { |
2901 | .name = "fc", | 2951 | .name = "fc", |
2902 | .module = THIS_MODULE, | 2952 | .module = THIS_MODULE, |
@@ -3007,6 +3057,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
3007 | ctrl->cnum = idx; | 3057 | ctrl->cnum = idx; |
3008 | ctrl->ioq_live = false; | 3058 | ctrl->ioq_live = false; |
3009 | ctrl->assoc_active = false; | 3059 | ctrl->assoc_active = false; |
3060 | atomic_set(&ctrl->err_work_active, 0); | ||
3010 | init_waitqueue_head(&ctrl->ioabort_wait); | 3061 | init_waitqueue_head(&ctrl->ioabort_wait); |
3011 | 3062 | ||
3012 | get_device(ctrl->dev); | 3063 | get_device(ctrl->dev); |
@@ -3014,6 +3065,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
3014 | 3065 | ||
3015 | INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); | 3066 | INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); |
3016 | INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); | 3067 | INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); |
3068 | INIT_WORK(&ctrl->err_work, nvme_fc_connect_err_work); | ||
3017 | spin_lock_init(&ctrl->lock); | 3069 | spin_lock_init(&ctrl->lock); |
3018 | 3070 | ||
3019 | /* io queue count */ | 3071 | /* io queue count */ |
@@ -3103,6 +3155,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
3103 | fail_ctrl: | 3155 | fail_ctrl: |
3104 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); | 3156 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); |
3105 | cancel_work_sync(&ctrl->ctrl.reset_work); | 3157 | cancel_work_sync(&ctrl->ctrl.reset_work); |
3158 | cancel_work_sync(&ctrl->err_work); | ||
3106 | cancel_delayed_work_sync(&ctrl->connect_work); | 3159 | cancel_delayed_work_sync(&ctrl->connect_work); |
3107 | 3160 | ||
3108 | ctrl->ctrl.opts = NULL; | 3161 | ctrl->ctrl.opts = NULL; |
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 9b18ce90f907..27f67dfa649d 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c | |||
@@ -44,6 +44,7 @@ struct nvmem_cell { | |||
44 | int bytes; | 44 | int bytes; |
45 | int bit_offset; | 45 | int bit_offset; |
46 | int nbits; | 46 | int nbits; |
47 | struct device_node *np; | ||
47 | struct nvmem_device *nvmem; | 48 | struct nvmem_device *nvmem; |
48 | struct list_head node; | 49 | struct list_head node; |
49 | }; | 50 | }; |
@@ -298,6 +299,7 @@ static void nvmem_cell_drop(struct nvmem_cell *cell) | |||
298 | mutex_lock(&nvmem_mutex); | 299 | mutex_lock(&nvmem_mutex); |
299 | list_del(&cell->node); | 300 | list_del(&cell->node); |
300 | mutex_unlock(&nvmem_mutex); | 301 | mutex_unlock(&nvmem_mutex); |
302 | of_node_put(cell->np); | ||
301 | kfree(cell->name); | 303 | kfree(cell->name); |
302 | kfree(cell); | 304 | kfree(cell); |
303 | } | 305 | } |
@@ -530,6 +532,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) | |||
530 | return -ENOMEM; | 532 | return -ENOMEM; |
531 | 533 | ||
532 | cell->nvmem = nvmem; | 534 | cell->nvmem = nvmem; |
535 | cell->np = of_node_get(child); | ||
533 | cell->offset = be32_to_cpup(addr++); | 536 | cell->offset = be32_to_cpup(addr++); |
534 | cell->bytes = be32_to_cpup(addr); | 537 | cell->bytes = be32_to_cpup(addr); |
535 | cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); | 538 | cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); |
@@ -960,14 +963,13 @@ out: | |||
960 | 963 | ||
961 | #if IS_ENABLED(CONFIG_OF) | 964 | #if IS_ENABLED(CONFIG_OF) |
962 | static struct nvmem_cell * | 965 | static struct nvmem_cell * |
963 | nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index) | 966 | nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) |
964 | { | 967 | { |
965 | struct nvmem_cell *cell = NULL; | 968 | struct nvmem_cell *cell = NULL; |
966 | int i = 0; | ||
967 | 969 | ||
968 | mutex_lock(&nvmem_mutex); | 970 | mutex_lock(&nvmem_mutex); |
969 | list_for_each_entry(cell, &nvmem->cells, node) { | 971 | list_for_each_entry(cell, &nvmem->cells, node) { |
970 | if (index == i++) | 972 | if (np == cell->np) |
971 | break; | 973 | break; |
972 | } | 974 | } |
973 | mutex_unlock(&nvmem_mutex); | 975 | mutex_unlock(&nvmem_mutex); |
@@ -1011,7 +1013,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id) | |||
1011 | if (IS_ERR(nvmem)) | 1013 | if (IS_ERR(nvmem)) |
1012 | return ERR_CAST(nvmem); | 1014 | return ERR_CAST(nvmem); |
1013 | 1015 | ||
1014 | cell = nvmem_find_cell_by_index(nvmem, index); | 1016 | cell = nvmem_find_cell_by_node(nvmem, cell_np); |
1015 | if (!cell) { | 1017 | if (!cell) { |
1016 | __nvmem_device_put(nvmem); | 1018 | __nvmem_device_put(nvmem); |
1017 | return ERR_PTR(-ENOENT); | 1019 | return ERR_PTR(-ENOENT); |
diff --git a/drivers/opp/ti-opp-supply.c b/drivers/opp/ti-opp-supply.c index 9e5a9a3112c9..3f4fb4dbbe33 100644 --- a/drivers/opp/ti-opp-supply.c +++ b/drivers/opp/ti-opp-supply.c | |||
@@ -288,7 +288,10 @@ static int ti_opp_supply_set_opp(struct dev_pm_set_opp_data *data) | |||
288 | int ret; | 288 | int ret; |
289 | 289 | ||
290 | vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data, | 290 | vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data, |
291 | new_supply_vbb->u_volt); | 291 | new_supply_vdd->u_volt); |
292 | |||
293 | if (new_supply_vdd->u_volt_min < vdd_uv) | ||
294 | new_supply_vdd->u_volt_min = vdd_uv; | ||
292 | 295 | ||
293 | /* Scaling up? Scale voltage before frequency */ | 296 | /* Scaling up? Scale voltage before frequency */ |
294 | if (freq > old_freq) { | 297 | if (freq > old_freq) { |
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index f96ec68af2e5..dcbf5c857743 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c | |||
@@ -415,9 +415,9 @@ static irqreturn_t ism_handle_irq(int irq, void *data) | |||
415 | break; | 415 | break; |
416 | 416 | ||
417 | clear_bit_inv(bit, bv); | 417 | clear_bit_inv(bit, bv); |
418 | ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0; | ||
418 | barrier(); | 419 | barrier(); |
419 | smcd_handle_irq(ism->smcd, bit + ISM_DMB_BIT_OFFSET); | 420 | smcd_handle_irq(ism->smcd, bit + ISM_DMB_BIT_OFFSET); |
420 | ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0; | ||
421 | } | 421 | } |
422 | 422 | ||
423 | if (ism->sba->e) { | 423 | if (ism->sba->e) { |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 20c85eed1a75..b658b9a5eb1e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1749,7 +1749,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) | |||
1749 | static void | 1749 | static void |
1750 | __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) | 1750 | __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) |
1751 | { | 1751 | { |
1752 | int cnt; | 1752 | int cnt, status; |
1753 | unsigned long flags; | 1753 | unsigned long flags; |
1754 | srb_t *sp; | 1754 | srb_t *sp; |
1755 | scsi_qla_host_t *vha = qp->vha; | 1755 | scsi_qla_host_t *vha = qp->vha; |
@@ -1799,10 +1799,16 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) | |||
1799 | if (!sp_get(sp)) { | 1799 | if (!sp_get(sp)) { |
1800 | spin_unlock_irqrestore | 1800 | spin_unlock_irqrestore |
1801 | (qp->qp_lock_ptr, flags); | 1801 | (qp->qp_lock_ptr, flags); |
1802 | qla2xxx_eh_abort( | 1802 | status = qla2xxx_eh_abort( |
1803 | GET_CMD_SP(sp)); | 1803 | GET_CMD_SP(sp)); |
1804 | spin_lock_irqsave | 1804 | spin_lock_irqsave |
1805 | (qp->qp_lock_ptr, flags); | 1805 | (qp->qp_lock_ptr, flags); |
1806 | /* | ||
1807 | * Get rid of extra reference caused | ||
1808 | * by early exit from qla2xxx_eh_abort | ||
1809 | */ | ||
1810 | if (status == FAST_IO_FAIL) | ||
1811 | atomic_dec(&sp->ref_count); | ||
1806 | } | 1812 | } |
1807 | } | 1813 | } |
1808 | sp->done(sp, res); | 1814 | sp->done(sp, res); |
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index 46df707e6f2c..452e19f8fb47 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "unipro.h" | 20 | #include "unipro.h" |
21 | #include "ufs-hisi.h" | 21 | #include "ufs-hisi.h" |
22 | #include "ufshci.h" | 22 | #include "ufshci.h" |
23 | #include "ufs_quirks.h" | ||
23 | 24 | ||
24 | static int ufs_hisi_check_hibern8(struct ufs_hba *hba) | 25 | static int ufs_hisi_check_hibern8(struct ufs_hba *hba) |
25 | { | 26 | { |
@@ -390,6 +391,14 @@ static void ufs_hisi_set_dev_cap(struct ufs_hisi_dev_params *hisi_param) | |||
390 | 391 | ||
391 | static void ufs_hisi_pwr_change_pre_change(struct ufs_hba *hba) | 392 | static void ufs_hisi_pwr_change_pre_change(struct ufs_hba *hba) |
392 | { | 393 | { |
394 | if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_VS_DEBUGSAVECONFIGTIME) { | ||
395 | pr_info("ufs flash device must set VS_DebugSaveConfigTime 0x10\n"); | ||
396 | /* VS_DebugSaveConfigTime */ | ||
397 | ufshcd_dme_set(hba, UIC_ARG_MIB(0xD0A0), 0x10); | ||
398 | /* sync length */ | ||
399 | ufshcd_dme_set(hba, UIC_ARG_MIB(0x1556), 0x48); | ||
400 | } | ||
401 | |||
393 | /* update */ | 402 | /* update */ |
394 | ufshcd_dme_set(hba, UIC_ARG_MIB(0x15A8), 0x1); | 403 | ufshcd_dme_set(hba, UIC_ARG_MIB(0x15A8), 0x1); |
395 | /* PA_TxSkip */ | 404 | /* PA_TxSkip */ |
diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h index 71f73d1d1ad1..5d2dfdb41a6f 100644 --- a/drivers/scsi/ufs/ufs_quirks.h +++ b/drivers/scsi/ufs/ufs_quirks.h | |||
@@ -131,4 +131,10 @@ struct ufs_dev_fix { | |||
131 | */ | 131 | */ |
132 | #define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME (1 << 8) | 132 | #define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME (1 << 8) |
133 | 133 | ||
134 | /* | ||
135 | * Some UFS devices require VS_DebugSaveConfigTime is 0x10, | ||
136 | * enabling this quirk ensure this. | ||
137 | */ | ||
138 | #define UFS_DEVICE_QUIRK_HOST_VS_DEBUGSAVECONFIGTIME (1 << 9) | ||
139 | |||
134 | #endif /* UFS_QUIRKS_H_ */ | 140 | #endif /* UFS_QUIRKS_H_ */ |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 27db55b0ca7f..f1c57cd33b5b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -231,6 +231,8 @@ static struct ufs_dev_fix ufs_fixups[] = { | |||
231 | UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), | 231 | UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), |
232 | UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, | 232 | UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, |
233 | UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME), | 233 | UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME), |
234 | UFS_FIX(UFS_VENDOR_SKHYNIX, "hB8aL1" /*H28U62301AMR*/, | ||
235 | UFS_DEVICE_QUIRK_HOST_VS_DEBUGSAVECONFIGTIME), | ||
234 | 236 | ||
235 | END_FIX | 237 | END_FIX |
236 | }; | 238 | }; |
diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 7218fb963d0a..1382a8df6c75 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c | |||
@@ -777,9 +777,6 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl, | |||
777 | u8 la = txn->la; | 777 | u8 la = txn->la; |
778 | bool usr_msg = false; | 778 | bool usr_msg = false; |
779 | 779 | ||
780 | if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG) | ||
781 | return -EPROTONOSUPPORT; | ||
782 | |||
783 | if (txn->mt == SLIM_MSG_MT_CORE && | 780 | if (txn->mt == SLIM_MSG_MT_CORE && |
784 | (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION && | 781 | (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION && |
785 | txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW)) | 782 | txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW)) |
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h index 4399d1873e2d..9be41089edde 100644 --- a/drivers/slimbus/slimbus.h +++ b/drivers/slimbus/slimbus.h | |||
@@ -61,12 +61,6 @@ | |||
61 | #define SLIM_MSG_MC_NEXT_REMOVE_CHANNEL 0x58 | 61 | #define SLIM_MSG_MC_NEXT_REMOVE_CHANNEL 0x58 |
62 | #define SLIM_MSG_MC_RECONFIGURE_NOW 0x5F | 62 | #define SLIM_MSG_MC_RECONFIGURE_NOW 0x5F |
63 | 63 | ||
64 | /* | ||
65 | * Clock pause flag to indicate that the reconfig message | ||
66 | * corresponds to clock pause sequence | ||
67 | */ | ||
68 | #define SLIM_MSG_CLK_PAUSE_SEQ_FLG (1U << 8) | ||
69 | |||
70 | /* Clock pause values per SLIMbus spec */ | 64 | /* Clock pause values per SLIMbus spec */ |
71 | #define SLIM_CLK_FAST 0 | 65 | #define SLIM_CLK_FAST 0 |
72 | #define SLIM_CLK_CONST_PHASE 1 | 66 | #define SLIM_CLK_CONST_PHASE 1 |
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index a53231b08d30..e3425bf082ae 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c | |||
@@ -310,6 +310,7 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd) | |||
310 | ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2); | 310 | ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2); |
311 | break; | 311 | break; |
312 | } | 312 | } |
313 | /* fall through */ | ||
313 | 314 | ||
314 | case IPIPEIF_SDRAM_YUV: | 315 | case IPIPEIF_SDRAM_YUV: |
315 | /* Set clock divider */ | 316 | /* Set clock divider */ |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index 82558455384a..dd121f66fa2d 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c | |||
@@ -253,7 +253,7 @@ static const struct v4l2_m2m_ops cedrus_m2m_ops = { | |||
253 | 253 | ||
254 | static const struct media_device_ops cedrus_m2m_media_ops = { | 254 | static const struct media_device_ops cedrus_m2m_media_ops = { |
255 | .req_validate = cedrus_request_validate, | 255 | .req_validate = cedrus_request_validate, |
256 | .req_queue = vb2_m2m_request_queue, | 256 | .req_queue = v4l2_m2m_request_queue, |
257 | }; | 257 | }; |
258 | 258 | ||
259 | static int cedrus_probe(struct platform_device *pdev) | 259 | static int cedrus_probe(struct platform_device *pdev) |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 85644669fbe7..0a357db4b31b 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -961,6 +961,8 @@ int __uio_register_device(struct module *owner, | |||
961 | if (ret) | 961 | if (ret) |
962 | goto err_uio_dev_add_attributes; | 962 | goto err_uio_dev_add_attributes; |
963 | 963 | ||
964 | info->uio_dev = idev; | ||
965 | |||
964 | if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { | 966 | if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { |
965 | /* | 967 | /* |
966 | * Note that we deliberately don't use devm_request_irq | 968 | * Note that we deliberately don't use devm_request_irq |
@@ -972,11 +974,12 @@ int __uio_register_device(struct module *owner, | |||
972 | */ | 974 | */ |
973 | ret = request_irq(info->irq, uio_interrupt, | 975 | ret = request_irq(info->irq, uio_interrupt, |
974 | info->irq_flags, info->name, idev); | 976 | info->irq_flags, info->name, idev); |
975 | if (ret) | 977 | if (ret) { |
978 | info->uio_dev = NULL; | ||
976 | goto err_request_irq; | 979 | goto err_request_irq; |
980 | } | ||
977 | } | 981 | } |
978 | 982 | ||
979 | info->uio_dev = idev; | ||
980 | return 0; | 983 | return 0; |
981 | 984 | ||
982 | err_request_irq: | 985 | err_request_irq: |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 47d75c20c211..1b68fed464cb 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1696,6 +1696,9 @@ static const struct usb_device_id acm_ids[] = { | |||
1696 | { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */ | 1696 | { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */ |
1697 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1697 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1698 | }, | 1698 | }, |
1699 | { USB_DEVICE(0x0572, 0x1349), /* Hiro (Conexant) USB MODEM H50228 */ | ||
1700 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | ||
1701 | }, | ||
1699 | { USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */ | 1702 | { USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */ |
1700 | .driver_info = QUIRK_CONTROL_LINE_STATE, }, | 1703 | .driver_info = QUIRK_CONTROL_LINE_STATE, }, |
1701 | { USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */ | 1704 | { USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */ |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c6077d582d29..0f9381b69a3b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2794,6 +2794,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2794 | int i, status; | 2794 | int i, status; |
2795 | u16 portchange, portstatus; | 2795 | u16 portchange, portstatus; |
2796 | struct usb_port *port_dev = hub->ports[port1 - 1]; | 2796 | struct usb_port *port_dev = hub->ports[port1 - 1]; |
2797 | int reset_recovery_time; | ||
2797 | 2798 | ||
2798 | if (!hub_is_superspeed(hub->hdev)) { | 2799 | if (!hub_is_superspeed(hub->hdev)) { |
2799 | if (warm) { | 2800 | if (warm) { |
@@ -2849,7 +2850,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2849 | USB_PORT_FEAT_C_BH_PORT_RESET); | 2850 | USB_PORT_FEAT_C_BH_PORT_RESET); |
2850 | usb_clear_port_feature(hub->hdev, port1, | 2851 | usb_clear_port_feature(hub->hdev, port1, |
2851 | USB_PORT_FEAT_C_PORT_LINK_STATE); | 2852 | USB_PORT_FEAT_C_PORT_LINK_STATE); |
2852 | usb_clear_port_feature(hub->hdev, port1, | 2853 | |
2854 | if (udev) | ||
2855 | usb_clear_port_feature(hub->hdev, port1, | ||
2853 | USB_PORT_FEAT_C_CONNECTION); | 2856 | USB_PORT_FEAT_C_CONNECTION); |
2854 | 2857 | ||
2855 | /* | 2858 | /* |
@@ -2885,11 +2888,18 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2885 | 2888 | ||
2886 | done: | 2889 | done: |
2887 | if (status == 0) { | 2890 | if (status == 0) { |
2888 | /* TRSTRCY = 10 ms; plus some extra */ | ||
2889 | if (port_dev->quirks & USB_PORT_QUIRK_FAST_ENUM) | 2891 | if (port_dev->quirks & USB_PORT_QUIRK_FAST_ENUM) |
2890 | usleep_range(10000, 12000); | 2892 | usleep_range(10000, 12000); |
2891 | else | 2893 | else { |
2892 | msleep(10 + 40); | 2894 | /* TRSTRCY = 10 ms; plus some extra */ |
2895 | reset_recovery_time = 10 + 40; | ||
2896 | |||
2897 | /* Hub needs extra delay after resetting its port. */ | ||
2898 | if (hub->hdev->quirks & USB_QUIRK_HUB_SLOW_RESET) | ||
2899 | reset_recovery_time += 100; | ||
2900 | |||
2901 | msleep(reset_recovery_time); | ||
2902 | } | ||
2893 | 2903 | ||
2894 | if (udev) { | 2904 | if (udev) { |
2895 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | 2905 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 178d6c6063c0..f9ff03e6af93 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -128,6 +128,9 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp) | |||
128 | case 'n': | 128 | case 'n': |
129 | flags |= USB_QUIRK_DELAY_CTRL_MSG; | 129 | flags |= USB_QUIRK_DELAY_CTRL_MSG; |
130 | break; | 130 | break; |
131 | case 'o': | ||
132 | flags |= USB_QUIRK_HUB_SLOW_RESET; | ||
133 | break; | ||
131 | /* Ignore unrecognized flag characters */ | 134 | /* Ignore unrecognized flag characters */ |
132 | } | 135 | } |
133 | } | 136 | } |
@@ -380,6 +383,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
380 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = | 383 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = |
381 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | 384 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, |
382 | 385 | ||
386 | /* Terminus Technology Inc. Hub */ | ||
387 | { USB_DEVICE(0x1a40, 0x0101), .driver_info = USB_QUIRK_HUB_SLOW_RESET }, | ||
388 | |||
383 | /* Corsair K70 RGB */ | 389 | /* Corsair K70 RGB */ |
384 | { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, | 390 | { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, |
385 | 391 | ||
@@ -391,6 +397,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
391 | { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT | | 397 | { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT | |
392 | USB_QUIRK_DELAY_CTRL_MSG }, | 398 | USB_QUIRK_DELAY_CTRL_MSG }, |
393 | 399 | ||
400 | /* Corsair K70 LUX RGB */ | ||
401 | { USB_DEVICE(0x1b1c, 0x1b33), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
402 | |||
394 | /* Corsair K70 LUX */ | 403 | /* Corsair K70 LUX */ |
395 | { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, | 404 | { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, |
396 | 405 | ||
@@ -411,6 +420,11 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
411 | { USB_DEVICE(0x2040, 0x7200), .driver_info = | 420 | { USB_DEVICE(0x2040, 0x7200), .driver_info = |
412 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 421 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
413 | 422 | ||
423 | /* Raydium Touchscreen */ | ||
424 | { USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM }, | ||
425 | |||
426 | { USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM }, | ||
427 | |||
414 | /* DJI CineSSD */ | 428 | /* DJI CineSSD */ |
415 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, | 429 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, |
416 | 430 | ||
diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index d257c541e51b..7afc10872f1f 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c | |||
@@ -120,6 +120,7 @@ static int dwc2_pci_probe(struct pci_dev *pci, | |||
120 | dwc2 = platform_device_alloc("dwc2", PLATFORM_DEVID_AUTO); | 120 | dwc2 = platform_device_alloc("dwc2", PLATFORM_DEVID_AUTO); |
121 | if (!dwc2) { | 121 | if (!dwc2) { |
122 | dev_err(dev, "couldn't allocate dwc2 device\n"); | 122 | dev_err(dev, "couldn't allocate dwc2 device\n"); |
123 | ret = -ENOMEM; | ||
123 | goto err; | 124 | goto err; |
124 | } | 125 | } |
125 | 126 | ||
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index becfbb87f791..2f2048aa5fde 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -1499,6 +1499,7 @@ static int dwc3_probe(struct platform_device *pdev) | |||
1499 | 1499 | ||
1500 | err5: | 1500 | err5: |
1501 | dwc3_event_buffers_cleanup(dwc); | 1501 | dwc3_event_buffers_cleanup(dwc); |
1502 | dwc3_ulpi_exit(dwc); | ||
1502 | 1503 | ||
1503 | err4: | 1504 | err4: |
1504 | dwc3_free_scratch_buffers(dwc); | 1505 | dwc3_free_scratch_buffers(dwc); |
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 1286076a8890..842795856bf4 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -283,8 +283,10 @@ err: | |||
283 | static void dwc3_pci_remove(struct pci_dev *pci) | 283 | static void dwc3_pci_remove(struct pci_dev *pci) |
284 | { | 284 | { |
285 | struct dwc3_pci *dwc = pci_get_drvdata(pci); | 285 | struct dwc3_pci *dwc = pci_get_drvdata(pci); |
286 | struct pci_dev *pdev = dwc->pci; | ||
286 | 287 | ||
287 | gpiod_remove_lookup_table(&platform_bytcr_gpios); | 288 | if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) |
289 | gpiod_remove_lookup_table(&platform_bytcr_gpios); | ||
288 | #ifdef CONFIG_PM | 290 | #ifdef CONFIG_PM |
289 | cancel_work_sync(&dwc->wakeup_work); | 291 | cancel_work_sync(&dwc->wakeup_work); |
290 | #endif | 292 | #endif |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 679c12e14522..9faad896b3a1 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -1081,7 +1081,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, | |||
1081 | /* Now prepare one extra TRB to align transfer size */ | 1081 | /* Now prepare one extra TRB to align transfer size */ |
1082 | trb = &dep->trb_pool[dep->trb_enqueue]; | 1082 | trb = &dep->trb_pool[dep->trb_enqueue]; |
1083 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, | 1083 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, |
1084 | maxp - rem, false, 0, | 1084 | maxp - rem, false, 1, |
1085 | req->request.stream_id, | 1085 | req->request.stream_id, |
1086 | req->request.short_not_ok, | 1086 | req->request.short_not_ok, |
1087 | req->request.no_interrupt); | 1087 | req->request.no_interrupt); |
@@ -1125,7 +1125,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, | |||
1125 | /* Now prepare one extra TRB to align transfer size */ | 1125 | /* Now prepare one extra TRB to align transfer size */ |
1126 | trb = &dep->trb_pool[dep->trb_enqueue]; | 1126 | trb = &dep->trb_pool[dep->trb_enqueue]; |
1127 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem, | 1127 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem, |
1128 | false, 0, req->request.stream_id, | 1128 | false, 1, req->request.stream_id, |
1129 | req->request.short_not_ok, | 1129 | req->request.short_not_ok, |
1130 | req->request.no_interrupt); | 1130 | req->request.no_interrupt); |
1131 | } else if (req->request.zero && req->request.length && | 1131 | } else if (req->request.zero && req->request.length && |
@@ -1141,7 +1141,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, | |||
1141 | /* Now prepare one extra TRB to handle ZLP */ | 1141 | /* Now prepare one extra TRB to handle ZLP */ |
1142 | trb = &dep->trb_pool[dep->trb_enqueue]; | 1142 | trb = &dep->trb_pool[dep->trb_enqueue]; |
1143 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, | 1143 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, |
1144 | false, 0, req->request.stream_id, | 1144 | false, 1, req->request.stream_id, |
1145 | req->request.short_not_ok, | 1145 | req->request.short_not_ok, |
1146 | req->request.no_interrupt); | 1146 | req->request.no_interrupt); |
1147 | } else { | 1147 | } else { |
@@ -2259,7 +2259,7 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, | |||
2259 | * with one TRB pending in the ring. We need to manually clear HWO bit | 2259 | * with one TRB pending in the ring. We need to manually clear HWO bit |
2260 | * from that TRB. | 2260 | * from that TRB. |
2261 | */ | 2261 | */ |
2262 | if ((req->zero || req->unaligned) && (trb->ctrl & DWC3_TRB_CTRL_HWO)) { | 2262 | if ((req->zero || req->unaligned) && !(trb->ctrl & DWC3_TRB_CTRL_CHN)) { |
2263 | trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | 2263 | trb->ctrl &= ~DWC3_TRB_CTRL_HWO; |
2264 | return 1; | 2264 | return 1; |
2265 | } | 2265 | } |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 3ada83d81bda..31e8bf3578c8 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -215,7 +215,6 @@ struct ffs_io_data { | |||
215 | 215 | ||
216 | struct mm_struct *mm; | 216 | struct mm_struct *mm; |
217 | struct work_struct work; | 217 | struct work_struct work; |
218 | struct work_struct cancellation_work; | ||
219 | 218 | ||
220 | struct usb_ep *ep; | 219 | struct usb_ep *ep; |
221 | struct usb_request *req; | 220 | struct usb_request *req; |
@@ -1073,31 +1072,22 @@ ffs_epfile_open(struct inode *inode, struct file *file) | |||
1073 | return 0; | 1072 | return 0; |
1074 | } | 1073 | } |
1075 | 1074 | ||
1076 | static void ffs_aio_cancel_worker(struct work_struct *work) | ||
1077 | { | ||
1078 | struct ffs_io_data *io_data = container_of(work, struct ffs_io_data, | ||
1079 | cancellation_work); | ||
1080 | |||
1081 | ENTER(); | ||
1082 | |||
1083 | usb_ep_dequeue(io_data->ep, io_data->req); | ||
1084 | } | ||
1085 | |||
1086 | static int ffs_aio_cancel(struct kiocb *kiocb) | 1075 | static int ffs_aio_cancel(struct kiocb *kiocb) |
1087 | { | 1076 | { |
1088 | struct ffs_io_data *io_data = kiocb->private; | 1077 | struct ffs_io_data *io_data = kiocb->private; |
1089 | struct ffs_data *ffs = io_data->ffs; | 1078 | struct ffs_epfile *epfile = kiocb->ki_filp->private_data; |
1090 | int value; | 1079 | int value; |
1091 | 1080 | ||
1092 | ENTER(); | 1081 | ENTER(); |
1093 | 1082 | ||
1094 | if (likely(io_data && io_data->ep && io_data->req)) { | 1083 | spin_lock_irq(&epfile->ffs->eps_lock); |
1095 | INIT_WORK(&io_data->cancellation_work, ffs_aio_cancel_worker); | 1084 | |
1096 | queue_work(ffs->io_completion_wq, &io_data->cancellation_work); | 1085 | if (likely(io_data && io_data->ep && io_data->req)) |
1097 | value = -EINPROGRESS; | 1086 | value = usb_ep_dequeue(io_data->ep, io_data->req); |
1098 | } else { | 1087 | else |
1099 | value = -EINVAL; | 1088 | value = -EINVAL; |
1100 | } | 1089 | |
1090 | spin_unlock_irq(&epfile->ffs->eps_lock); | ||
1101 | 1091 | ||
1102 | return value; | 1092 | return value; |
1103 | } | 1093 | } |
diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c index 27f00160332e..3c4abb5a1c3f 100644 --- a/drivers/usb/host/xhci-histb.c +++ b/drivers/usb/host/xhci-histb.c | |||
@@ -325,14 +325,16 @@ static int xhci_histb_remove(struct platform_device *dev) | |||
325 | struct xhci_hcd_histb *histb = platform_get_drvdata(dev); | 325 | struct xhci_hcd_histb *histb = platform_get_drvdata(dev); |
326 | struct usb_hcd *hcd = histb->hcd; | 326 | struct usb_hcd *hcd = histb->hcd; |
327 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 327 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
328 | struct usb_hcd *shared_hcd = xhci->shared_hcd; | ||
328 | 329 | ||
329 | xhci->xhc_state |= XHCI_STATE_REMOVING; | 330 | xhci->xhc_state |= XHCI_STATE_REMOVING; |
330 | 331 | ||
331 | usb_remove_hcd(xhci->shared_hcd); | 332 | usb_remove_hcd(shared_hcd); |
333 | xhci->shared_hcd = NULL; | ||
332 | device_wakeup_disable(&dev->dev); | 334 | device_wakeup_disable(&dev->dev); |
333 | 335 | ||
334 | usb_remove_hcd(hcd); | 336 | usb_remove_hcd(hcd); |
335 | usb_put_hcd(xhci->shared_hcd); | 337 | usb_put_hcd(shared_hcd); |
336 | 338 | ||
337 | xhci_histb_host_disable(histb); | 339 | xhci_histb_host_disable(histb); |
338 | usb_put_hcd(hcd); | 340 | usb_put_hcd(hcd); |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 12eea73d9f20..94aca1b5ac8a 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -876,7 +876,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, | |||
876 | status |= USB_PORT_STAT_SUSPEND; | 876 | status |= USB_PORT_STAT_SUSPEND; |
877 | } | 877 | } |
878 | if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME && | 878 | if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME && |
879 | !DEV_SUPERSPEED_ANY(raw_port_status)) { | 879 | !DEV_SUPERSPEED_ANY(raw_port_status) && hcd->speed < HCD_USB3) { |
880 | if ((raw_port_status & PORT_RESET) || | 880 | if ((raw_port_status & PORT_RESET) || |
881 | !(raw_port_status & PORT_PE)) | 881 | !(raw_port_status & PORT_PE)) |
882 | return 0xffffffff; | 882 | return 0xffffffff; |
@@ -921,7 +921,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, | |||
921 | time_left = wait_for_completion_timeout( | 921 | time_left = wait_for_completion_timeout( |
922 | &bus_state->rexit_done[wIndex], | 922 | &bus_state->rexit_done[wIndex], |
923 | msecs_to_jiffies( | 923 | msecs_to_jiffies( |
924 | XHCI_MAX_REXIT_TIMEOUT)); | 924 | XHCI_MAX_REXIT_TIMEOUT_MS)); |
925 | spin_lock_irqsave(&xhci->lock, flags); | 925 | spin_lock_irqsave(&xhci->lock, flags); |
926 | 926 | ||
927 | if (time_left) { | 927 | if (time_left) { |
@@ -935,7 +935,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, | |||
935 | } else { | 935 | } else { |
936 | int port_status = readl(port->addr); | 936 | int port_status = readl(port->addr); |
937 | xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n", | 937 | xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n", |
938 | XHCI_MAX_REXIT_TIMEOUT, | 938 | XHCI_MAX_REXIT_TIMEOUT_MS, |
939 | port_status); | 939 | port_status); |
940 | status |= USB_PORT_STAT_SUSPEND; | 940 | status |= USB_PORT_STAT_SUSPEND; |
941 | clear_bit(wIndex, &bus_state->rexit_ports); | 941 | clear_bit(wIndex, &bus_state->rexit_ports); |
@@ -1474,15 +1474,18 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
1474 | unsigned long flags; | 1474 | unsigned long flags; |
1475 | struct xhci_hub *rhub; | 1475 | struct xhci_hub *rhub; |
1476 | struct xhci_port **ports; | 1476 | struct xhci_port **ports; |
1477 | u32 portsc_buf[USB_MAXCHILDREN]; | ||
1478 | bool wake_enabled; | ||
1477 | 1479 | ||
1478 | rhub = xhci_get_rhub(hcd); | 1480 | rhub = xhci_get_rhub(hcd); |
1479 | ports = rhub->ports; | 1481 | ports = rhub->ports; |
1480 | max_ports = rhub->num_ports; | 1482 | max_ports = rhub->num_ports; |
1481 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 1483 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
1484 | wake_enabled = hcd->self.root_hub->do_remote_wakeup; | ||
1482 | 1485 | ||
1483 | spin_lock_irqsave(&xhci->lock, flags); | 1486 | spin_lock_irqsave(&xhci->lock, flags); |
1484 | 1487 | ||
1485 | if (hcd->self.root_hub->do_remote_wakeup) { | 1488 | if (wake_enabled) { |
1486 | if (bus_state->resuming_ports || /* USB2 */ | 1489 | if (bus_state->resuming_ports || /* USB2 */ |
1487 | bus_state->port_remote_wakeup) { /* USB3 */ | 1490 | bus_state->port_remote_wakeup) { /* USB3 */ |
1488 | spin_unlock_irqrestore(&xhci->lock, flags); | 1491 | spin_unlock_irqrestore(&xhci->lock, flags); |
@@ -1490,26 +1493,36 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
1490 | return -EBUSY; | 1493 | return -EBUSY; |
1491 | } | 1494 | } |
1492 | } | 1495 | } |
1493 | 1496 | /* | |
1494 | port_index = max_ports; | 1497 | * Prepare ports for suspend, but don't write anything before all ports |
1498 | * are checked and we know bus suspend can proceed | ||
1499 | */ | ||
1495 | bus_state->bus_suspended = 0; | 1500 | bus_state->bus_suspended = 0; |
1501 | port_index = max_ports; | ||
1496 | while (port_index--) { | 1502 | while (port_index--) { |
1497 | /* suspend the port if the port is not suspended */ | ||
1498 | u32 t1, t2; | 1503 | u32 t1, t2; |
1499 | int slot_id; | ||
1500 | 1504 | ||
1501 | t1 = readl(ports[port_index]->addr); | 1505 | t1 = readl(ports[port_index]->addr); |
1502 | t2 = xhci_port_state_to_neutral(t1); | 1506 | t2 = xhci_port_state_to_neutral(t1); |
1507 | portsc_buf[port_index] = 0; | ||
1503 | 1508 | ||
1504 | if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { | 1509 | /* Bail out if a USB3 port has a new device in link training */ |
1505 | xhci_dbg(xhci, "port %d not suspended\n", port_index); | 1510 | if ((t1 & PORT_PLS_MASK) == XDEV_POLLING) { |
1506 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | 1511 | bus_state->bus_suspended = 0; |
1507 | port_index + 1); | 1512 | spin_unlock_irqrestore(&xhci->lock, flags); |
1508 | if (slot_id) { | 1513 | xhci_dbg(xhci, "Bus suspend bailout, port in polling\n"); |
1514 | return -EBUSY; | ||
1515 | } | ||
1516 | |||
1517 | /* suspend ports in U0, or bail out for new connect changes */ | ||
1518 | if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) { | ||
1519 | if ((t1 & PORT_CSC) && wake_enabled) { | ||
1520 | bus_state->bus_suspended = 0; | ||
1509 | spin_unlock_irqrestore(&xhci->lock, flags); | 1521 | spin_unlock_irqrestore(&xhci->lock, flags); |
1510 | xhci_stop_device(xhci, slot_id, 1); | 1522 | xhci_dbg(xhci, "Bus suspend bailout, port connect change\n"); |
1511 | spin_lock_irqsave(&xhci->lock, flags); | 1523 | return -EBUSY; |
1512 | } | 1524 | } |
1525 | xhci_dbg(xhci, "port %d not suspended\n", port_index); | ||
1513 | t2 &= ~PORT_PLS_MASK; | 1526 | t2 &= ~PORT_PLS_MASK; |
1514 | t2 |= PORT_LINK_STROBE | XDEV_U3; | 1527 | t2 |= PORT_LINK_STROBE | XDEV_U3; |
1515 | set_bit(port_index, &bus_state->bus_suspended); | 1528 | set_bit(port_index, &bus_state->bus_suspended); |
@@ -1518,7 +1531,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
1518 | * including the USB 3.0 roothub, but only if CONFIG_PM | 1531 | * including the USB 3.0 roothub, but only if CONFIG_PM |
1519 | * is enabled, so also enable remote wake here. | 1532 | * is enabled, so also enable remote wake here. |
1520 | */ | 1533 | */ |
1521 | if (hcd->self.root_hub->do_remote_wakeup) { | 1534 | if (wake_enabled) { |
1522 | if (t1 & PORT_CONNECT) { | 1535 | if (t1 & PORT_CONNECT) { |
1523 | t2 |= PORT_WKOC_E | PORT_WKDISC_E; | 1536 | t2 |= PORT_WKOC_E | PORT_WKDISC_E; |
1524 | t2 &= ~PORT_WKCONN_E; | 1537 | t2 &= ~PORT_WKCONN_E; |
@@ -1538,7 +1551,26 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
1538 | 1551 | ||
1539 | t1 = xhci_port_state_to_neutral(t1); | 1552 | t1 = xhci_port_state_to_neutral(t1); |
1540 | if (t1 != t2) | 1553 | if (t1 != t2) |
1541 | writel(t2, ports[port_index]->addr); | 1554 | portsc_buf[port_index] = t2; |
1555 | } | ||
1556 | |||
1557 | /* write port settings, stopping and suspending ports if needed */ | ||
1558 | port_index = max_ports; | ||
1559 | while (port_index--) { | ||
1560 | if (!portsc_buf[port_index]) | ||
1561 | continue; | ||
1562 | if (test_bit(port_index, &bus_state->bus_suspended)) { | ||
1563 | int slot_id; | ||
1564 | |||
1565 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | ||
1566 | port_index + 1); | ||
1567 | if (slot_id) { | ||
1568 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1569 | xhci_stop_device(xhci, slot_id, 1); | ||
1570 | spin_lock_irqsave(&xhci->lock, flags); | ||
1571 | } | ||
1572 | } | ||
1573 | writel(portsc_buf[port_index], ports[port_index]->addr); | ||
1542 | } | 1574 | } |
1543 | hcd->state = HC_STATE_SUSPENDED; | 1575 | hcd->state = HC_STATE_SUSPENDED; |
1544 | bus_state->next_statechange = jiffies + msecs_to_jiffies(10); | 1576 | bus_state->next_statechange = jiffies + msecs_to_jiffies(10); |
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 71d0d33c3286..60987c787e44 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c | |||
@@ -590,12 +590,14 @@ static int xhci_mtk_remove(struct platform_device *dev) | |||
590 | struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev); | 590 | struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev); |
591 | struct usb_hcd *hcd = mtk->hcd; | 591 | struct usb_hcd *hcd = mtk->hcd; |
592 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 592 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
593 | struct usb_hcd *shared_hcd = xhci->shared_hcd; | ||
593 | 594 | ||
594 | usb_remove_hcd(xhci->shared_hcd); | 595 | usb_remove_hcd(shared_hcd); |
596 | xhci->shared_hcd = NULL; | ||
595 | device_init_wakeup(&dev->dev, false); | 597 | device_init_wakeup(&dev->dev, false); |
596 | 598 | ||
597 | usb_remove_hcd(hcd); | 599 | usb_remove_hcd(hcd); |
598 | usb_put_hcd(xhci->shared_hcd); | 600 | usb_put_hcd(shared_hcd); |
599 | usb_put_hcd(hcd); | 601 | usb_put_hcd(hcd); |
600 | xhci_mtk_sch_exit(mtk); | 602 | xhci_mtk_sch_exit(mtk); |
601 | xhci_mtk_clks_disable(mtk); | 603 | xhci_mtk_clks_disable(mtk); |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 01c57055c0c5..a9515265db4d 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -248,6 +248,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
248 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) | 248 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) |
249 | xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; | 249 | xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; |
250 | 250 | ||
251 | if ((pdev->vendor == PCI_VENDOR_ID_BROADCOM || | ||
252 | pdev->vendor == PCI_VENDOR_ID_CAVIUM) && | ||
253 | pdev->device == 0x9026) | ||
254 | xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; | ||
255 | |||
251 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 256 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
252 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | 257 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
253 | "QUIRK: Resetting on resume"); | 258 | "QUIRK: Resetting on resume"); |
@@ -380,6 +385,7 @@ static void xhci_pci_remove(struct pci_dev *dev) | |||
380 | if (xhci->shared_hcd) { | 385 | if (xhci->shared_hcd) { |
381 | usb_remove_hcd(xhci->shared_hcd); | 386 | usb_remove_hcd(xhci->shared_hcd); |
382 | usb_put_hcd(xhci->shared_hcd); | 387 | usb_put_hcd(xhci->shared_hcd); |
388 | xhci->shared_hcd = NULL; | ||
383 | } | 389 | } |
384 | 390 | ||
385 | /* Workaround for spurious wakeups at shutdown with HSW */ | 391 | /* Workaround for spurious wakeups at shutdown with HSW */ |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 32b5574ad5c5..ef09cb06212f 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -362,14 +362,16 @@ static int xhci_plat_remove(struct platform_device *dev) | |||
362 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 362 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
363 | struct clk *clk = xhci->clk; | 363 | struct clk *clk = xhci->clk; |
364 | struct clk *reg_clk = xhci->reg_clk; | 364 | struct clk *reg_clk = xhci->reg_clk; |
365 | struct usb_hcd *shared_hcd = xhci->shared_hcd; | ||
365 | 366 | ||
366 | xhci->xhc_state |= XHCI_STATE_REMOVING; | 367 | xhci->xhc_state |= XHCI_STATE_REMOVING; |
367 | 368 | ||
368 | usb_remove_hcd(xhci->shared_hcd); | 369 | usb_remove_hcd(shared_hcd); |
370 | xhci->shared_hcd = NULL; | ||
369 | usb_phy_shutdown(hcd->usb_phy); | 371 | usb_phy_shutdown(hcd->usb_phy); |
370 | 372 | ||
371 | usb_remove_hcd(hcd); | 373 | usb_remove_hcd(hcd); |
372 | usb_put_hcd(xhci->shared_hcd); | 374 | usb_put_hcd(shared_hcd); |
373 | 375 | ||
374 | clk_disable_unprepare(clk); | 376 | clk_disable_unprepare(clk); |
375 | clk_disable_unprepare(reg_clk); | 377 | clk_disable_unprepare(reg_clk); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index a8d92c90fb58..65750582133f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1521,6 +1521,35 @@ static void handle_device_notification(struct xhci_hcd *xhci, | |||
1521 | usb_wakeup_notification(udev->parent, udev->portnum); | 1521 | usb_wakeup_notification(udev->parent, udev->portnum); |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | /* | ||
1525 | * Quirk hanlder for errata seen on Cavium ThunderX2 processor XHCI | ||
1526 | * Controller. | ||
1527 | * As per ThunderX2errata-129 USB 2 device may come up as USB 1 | ||
1528 | * If a connection to a USB 1 device is followed by another connection | ||
1529 | * to a USB 2 device. | ||
1530 | * | ||
1531 | * Reset the PHY after the USB device is disconnected if device speed | ||
1532 | * is less than HCD_USB3. | ||
1533 | * Retry the reset sequence max of 4 times checking the PLL lock status. | ||
1534 | * | ||
1535 | */ | ||
1536 | static void xhci_cavium_reset_phy_quirk(struct xhci_hcd *xhci) | ||
1537 | { | ||
1538 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | ||
1539 | u32 pll_lock_check; | ||
1540 | u32 retry_count = 4; | ||
1541 | |||
1542 | do { | ||
1543 | /* Assert PHY reset */ | ||
1544 | writel(0x6F, hcd->regs + 0x1048); | ||
1545 | udelay(10); | ||
1546 | /* De-assert the PHY reset */ | ||
1547 | writel(0x7F, hcd->regs + 0x1048); | ||
1548 | udelay(200); | ||
1549 | pll_lock_check = readl(hcd->regs + 0x1070); | ||
1550 | } while (!(pll_lock_check & 0x1) && --retry_count); | ||
1551 | } | ||
1552 | |||
1524 | static void handle_port_status(struct xhci_hcd *xhci, | 1553 | static void handle_port_status(struct xhci_hcd *xhci, |
1525 | union xhci_trb *event) | 1554 | union xhci_trb *event) |
1526 | { | 1555 | { |
@@ -1556,6 +1585,13 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1556 | goto cleanup; | 1585 | goto cleanup; |
1557 | } | 1586 | } |
1558 | 1587 | ||
1588 | /* We might get interrupts after shared_hcd is removed */ | ||
1589 | if (port->rhub == &xhci->usb3_rhub && xhci->shared_hcd == NULL) { | ||
1590 | xhci_dbg(xhci, "ignore port event for removed USB3 hcd\n"); | ||
1591 | bogus_port_status = true; | ||
1592 | goto cleanup; | ||
1593 | } | ||
1594 | |||
1559 | hcd = port->rhub->hcd; | 1595 | hcd = port->rhub->hcd; |
1560 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 1596 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
1561 | hcd_portnum = port->hcd_portnum; | 1597 | hcd_portnum = port->hcd_portnum; |
@@ -1639,7 +1675,7 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1639 | * RExit to a disconnect state). If so, let the the driver know it's | 1675 | * RExit to a disconnect state). If so, let the the driver know it's |
1640 | * out of the RExit state. | 1676 | * out of the RExit state. |
1641 | */ | 1677 | */ |
1642 | if (!DEV_SUPERSPEED_ANY(portsc) && | 1678 | if (!DEV_SUPERSPEED_ANY(portsc) && hcd->speed < HCD_USB3 && |
1643 | test_and_clear_bit(hcd_portnum, | 1679 | test_and_clear_bit(hcd_portnum, |
1644 | &bus_state->rexit_ports)) { | 1680 | &bus_state->rexit_ports)) { |
1645 | complete(&bus_state->rexit_done[hcd_portnum]); | 1681 | complete(&bus_state->rexit_done[hcd_portnum]); |
@@ -1647,8 +1683,12 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1647 | goto cleanup; | 1683 | goto cleanup; |
1648 | } | 1684 | } |
1649 | 1685 | ||
1650 | if (hcd->speed < HCD_USB3) | 1686 | if (hcd->speed < HCD_USB3) { |
1651 | xhci_test_and_clear_bit(xhci, port, PORT_PLC); | 1687 | xhci_test_and_clear_bit(xhci, port, PORT_PLC); |
1688 | if ((xhci->quirks & XHCI_RESET_PLL_ON_DISCONNECT) && | ||
1689 | (portsc & PORT_CSC) && !(portsc & PORT_CONNECT)) | ||
1690 | xhci_cavium_reset_phy_quirk(xhci); | ||
1691 | } | ||
1652 | 1692 | ||
1653 | cleanup: | 1693 | cleanup: |
1654 | /* Update event ring dequeue pointer before dropping the lock */ | 1694 | /* Update event ring dequeue pointer before dropping the lock */ |
@@ -2266,6 +2306,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2266 | goto cleanup; | 2306 | goto cleanup; |
2267 | case COMP_RING_UNDERRUN: | 2307 | case COMP_RING_UNDERRUN: |
2268 | case COMP_RING_OVERRUN: | 2308 | case COMP_RING_OVERRUN: |
2309 | case COMP_STOPPED_LENGTH_INVALID: | ||
2269 | goto cleanup; | 2310 | goto cleanup; |
2270 | default: | 2311 | default: |
2271 | xhci_err(xhci, "ERROR Transfer event for unknown stream ring slot %u ep %u\n", | 2312 | xhci_err(xhci, "ERROR Transfer event for unknown stream ring slot %u ep %u\n", |
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 6b5db344de30..938ff06c0349 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c | |||
@@ -1303,6 +1303,7 @@ static int tegra_xusb_remove(struct platform_device *pdev) | |||
1303 | 1303 | ||
1304 | usb_remove_hcd(xhci->shared_hcd); | 1304 | usb_remove_hcd(xhci->shared_hcd); |
1305 | usb_put_hcd(xhci->shared_hcd); | 1305 | usb_put_hcd(xhci->shared_hcd); |
1306 | xhci->shared_hcd = NULL; | ||
1306 | usb_remove_hcd(tegra->hcd); | 1307 | usb_remove_hcd(tegra->hcd); |
1307 | usb_put_hcd(tegra->hcd); | 1308 | usb_put_hcd(tegra->hcd); |
1308 | 1309 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 0420eefa647a..c928dbbff881 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -719,8 +719,6 @@ static void xhci_stop(struct usb_hcd *hcd) | |||
719 | 719 | ||
720 | /* Only halt host and free memory after both hcds are removed */ | 720 | /* Only halt host and free memory after both hcds are removed */ |
721 | if (!usb_hcd_is_primary_hcd(hcd)) { | 721 | if (!usb_hcd_is_primary_hcd(hcd)) { |
722 | /* usb core will free this hcd shortly, unset pointer */ | ||
723 | xhci->shared_hcd = NULL; | ||
724 | mutex_unlock(&xhci->mutex); | 722 | mutex_unlock(&xhci->mutex); |
725 | return; | 723 | return; |
726 | } | 724 | } |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index bf0b3692dc9a..260b259b72bc 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1680,7 +1680,7 @@ struct xhci_bus_state { | |||
1680 | * It can take up to 20 ms to transition from RExit to U0 on the | 1680 | * It can take up to 20 ms to transition from RExit to U0 on the |
1681 | * Intel Lynx Point LP xHCI host. | 1681 | * Intel Lynx Point LP xHCI host. |
1682 | */ | 1682 | */ |
1683 | #define XHCI_MAX_REXIT_TIMEOUT (20 * 1000) | 1683 | #define XHCI_MAX_REXIT_TIMEOUT_MS 20 |
1684 | 1684 | ||
1685 | static inline unsigned int hcd_index(struct usb_hcd *hcd) | 1685 | static inline unsigned int hcd_index(struct usb_hcd *hcd) |
1686 | { | 1686 | { |
@@ -1849,6 +1849,7 @@ struct xhci_hcd { | |||
1849 | #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) | 1849 | #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) |
1850 | #define XHCI_ZERO_64B_REGS BIT_ULL(32) | 1850 | #define XHCI_ZERO_64B_REGS BIT_ULL(32) |
1851 | #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) | 1851 | #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) |
1852 | #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) | ||
1852 | 1853 | ||
1853 | unsigned int num_active_eps; | 1854 | unsigned int num_active_eps; |
1854 | unsigned int limit_active_eps; | 1855 | unsigned int limit_active_eps; |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index bd539f3058bc..85b48c6ddc7e 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -50,6 +50,7 @@ static const struct usb_device_id appledisplay_table[] = { | |||
50 | { APPLEDISPLAY_DEVICE(0x9219) }, | 50 | { APPLEDISPLAY_DEVICE(0x9219) }, |
51 | { APPLEDISPLAY_DEVICE(0x921c) }, | 51 | { APPLEDISPLAY_DEVICE(0x921c) }, |
52 | { APPLEDISPLAY_DEVICE(0x921d) }, | 52 | { APPLEDISPLAY_DEVICE(0x921d) }, |
53 | { APPLEDISPLAY_DEVICE(0x9222) }, | ||
53 | { APPLEDISPLAY_DEVICE(0x9236) }, | 54 | { APPLEDISPLAY_DEVICE(0x9236) }, |
54 | 55 | ||
55 | /* Terminating entry */ | 56 | /* Terminating entry */ |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 59970886690f..a7b44863d502 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -576,6 +576,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
576 | { | 576 | { |
577 | signed long rtt2, timeout; | 577 | signed long rtt2, timeout; |
578 | long ret; | 578 | long ret; |
579 | bool stalled = false; | ||
579 | u64 rtt; | 580 | u64 rtt; |
580 | u32 life, last_life; | 581 | u32 life, last_life; |
581 | 582 | ||
@@ -609,12 +610,20 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
609 | 610 | ||
610 | life = rxrpc_kernel_check_life(call->net->socket, call->rxcall); | 611 | life = rxrpc_kernel_check_life(call->net->socket, call->rxcall); |
611 | if (timeout == 0 && | 612 | if (timeout == 0 && |
612 | life == last_life && signal_pending(current)) | 613 | life == last_life && signal_pending(current)) { |
614 | if (stalled) | ||
613 | break; | 615 | break; |
616 | __set_current_state(TASK_RUNNING); | ||
617 | rxrpc_kernel_probe_life(call->net->socket, call->rxcall); | ||
618 | timeout = rtt2; | ||
619 | stalled = true; | ||
620 | continue; | ||
621 | } | ||
614 | 622 | ||
615 | if (life != last_life) { | 623 | if (life != last_life) { |
616 | timeout = rtt2; | 624 | timeout = rtt2; |
617 | last_life = life; | 625 | last_life = life; |
626 | stalled = false; | ||
618 | } | 627 | } |
619 | 628 | ||
620 | timeout = schedule_timeout(timeout); | 629 | timeout = schedule_timeout(timeout); |
@@ -98,12 +98,6 @@ static void *dax_make_entry(pfn_t pfn, unsigned long flags) | |||
98 | return xa_mk_value(flags | (pfn_t_to_pfn(pfn) << DAX_SHIFT)); | 98 | return xa_mk_value(flags | (pfn_t_to_pfn(pfn) << DAX_SHIFT)); |
99 | } | 99 | } |
100 | 100 | ||
101 | static void *dax_make_page_entry(struct page *page) | ||
102 | { | ||
103 | pfn_t pfn = page_to_pfn_t(page); | ||
104 | return dax_make_entry(pfn, PageHead(page) ? DAX_PMD : 0); | ||
105 | } | ||
106 | |||
107 | static bool dax_is_locked(void *entry) | 101 | static bool dax_is_locked(void *entry) |
108 | { | 102 | { |
109 | return xa_to_value(entry) & DAX_LOCKED; | 103 | return xa_to_value(entry) & DAX_LOCKED; |
@@ -116,12 +110,12 @@ static unsigned int dax_entry_order(void *entry) | |||
116 | return 0; | 110 | return 0; |
117 | } | 111 | } |
118 | 112 | ||
119 | static int dax_is_pmd_entry(void *entry) | 113 | static unsigned long dax_is_pmd_entry(void *entry) |
120 | { | 114 | { |
121 | return xa_to_value(entry) & DAX_PMD; | 115 | return xa_to_value(entry) & DAX_PMD; |
122 | } | 116 | } |
123 | 117 | ||
124 | static int dax_is_pte_entry(void *entry) | 118 | static bool dax_is_pte_entry(void *entry) |
125 | { | 119 | { |
126 | return !(xa_to_value(entry) & DAX_PMD); | 120 | return !(xa_to_value(entry) & DAX_PMD); |
127 | } | 121 | } |
@@ -222,9 +216,8 @@ static void *get_unlocked_entry(struct xa_state *xas) | |||
222 | ewait.wait.func = wake_exceptional_entry_func; | 216 | ewait.wait.func = wake_exceptional_entry_func; |
223 | 217 | ||
224 | for (;;) { | 218 | for (;;) { |
225 | entry = xas_load(xas); | 219 | entry = xas_find_conflict(xas); |
226 | if (!entry || xa_is_internal(entry) || | 220 | if (!entry || WARN_ON_ONCE(!xa_is_value(entry)) || |
227 | WARN_ON_ONCE(!xa_is_value(entry)) || | ||
228 | !dax_is_locked(entry)) | 221 | !dax_is_locked(entry)) |
229 | return entry; | 222 | return entry; |
230 | 223 | ||
@@ -255,6 +248,7 @@ static void dax_unlock_entry(struct xa_state *xas, void *entry) | |||
255 | { | 248 | { |
256 | void *old; | 249 | void *old; |
257 | 250 | ||
251 | BUG_ON(dax_is_locked(entry)); | ||
258 | xas_reset(xas); | 252 | xas_reset(xas); |
259 | xas_lock_irq(xas); | 253 | xas_lock_irq(xas); |
260 | old = xas_store(xas, entry); | 254 | old = xas_store(xas, entry); |
@@ -352,16 +346,27 @@ static struct page *dax_busy_page(void *entry) | |||
352 | return NULL; | 346 | return NULL; |
353 | } | 347 | } |
354 | 348 | ||
349 | /* | ||
350 | * dax_lock_mapping_entry - Lock the DAX entry corresponding to a page | ||
351 | * @page: The page whose entry we want to lock | ||
352 | * | ||
353 | * Context: Process context. | ||
354 | * Return: %true if the entry was locked or does not need to be locked. | ||
355 | */ | ||
355 | bool dax_lock_mapping_entry(struct page *page) | 356 | bool dax_lock_mapping_entry(struct page *page) |
356 | { | 357 | { |
357 | XA_STATE(xas, NULL, 0); | 358 | XA_STATE(xas, NULL, 0); |
358 | void *entry; | 359 | void *entry; |
360 | bool locked; | ||
359 | 361 | ||
362 | /* Ensure page->mapping isn't freed while we look at it */ | ||
363 | rcu_read_lock(); | ||
360 | for (;;) { | 364 | for (;;) { |
361 | struct address_space *mapping = READ_ONCE(page->mapping); | 365 | struct address_space *mapping = READ_ONCE(page->mapping); |
362 | 366 | ||
367 | locked = false; | ||
363 | if (!dax_mapping(mapping)) | 368 | if (!dax_mapping(mapping)) |
364 | return false; | 369 | break; |
365 | 370 | ||
366 | /* | 371 | /* |
367 | * In the device-dax case there's no need to lock, a | 372 | * In the device-dax case there's no need to lock, a |
@@ -370,8 +375,9 @@ bool dax_lock_mapping_entry(struct page *page) | |||
370 | * otherwise we would not have a valid pfn_to_page() | 375 | * otherwise we would not have a valid pfn_to_page() |
371 | * translation. | 376 | * translation. |
372 | */ | 377 | */ |
378 | locked = true; | ||
373 | if (S_ISCHR(mapping->host->i_mode)) | 379 | if (S_ISCHR(mapping->host->i_mode)) |
374 | return true; | 380 | break; |
375 | 381 | ||
376 | xas.xa = &mapping->i_pages; | 382 | xas.xa = &mapping->i_pages; |
377 | xas_lock_irq(&xas); | 383 | xas_lock_irq(&xas); |
@@ -382,28 +388,35 @@ bool dax_lock_mapping_entry(struct page *page) | |||
382 | xas_set(&xas, page->index); | 388 | xas_set(&xas, page->index); |
383 | entry = xas_load(&xas); | 389 | entry = xas_load(&xas); |
384 | if (dax_is_locked(entry)) { | 390 | if (dax_is_locked(entry)) { |
391 | rcu_read_unlock(); | ||
385 | entry = get_unlocked_entry(&xas); | 392 | entry = get_unlocked_entry(&xas); |
386 | /* Did the page move while we slept? */ | 393 | xas_unlock_irq(&xas); |
387 | if (dax_to_pfn(entry) != page_to_pfn(page)) { | 394 | put_unlocked_entry(&xas, entry); |
388 | xas_unlock_irq(&xas); | 395 | rcu_read_lock(); |
389 | continue; | 396 | continue; |
390 | } | ||
391 | } | 397 | } |
392 | dax_lock_entry(&xas, entry); | 398 | dax_lock_entry(&xas, entry); |
393 | xas_unlock_irq(&xas); | 399 | xas_unlock_irq(&xas); |
394 | return true; | 400 | break; |
395 | } | 401 | } |
402 | rcu_read_unlock(); | ||
403 | return locked; | ||
396 | } | 404 | } |
397 | 405 | ||
398 | void dax_unlock_mapping_entry(struct page *page) | 406 | void dax_unlock_mapping_entry(struct page *page) |
399 | { | 407 | { |
400 | struct address_space *mapping = page->mapping; | 408 | struct address_space *mapping = page->mapping; |
401 | XA_STATE(xas, &mapping->i_pages, page->index); | 409 | XA_STATE(xas, &mapping->i_pages, page->index); |
410 | void *entry; | ||
402 | 411 | ||
403 | if (S_ISCHR(mapping->host->i_mode)) | 412 | if (S_ISCHR(mapping->host->i_mode)) |
404 | return; | 413 | return; |
405 | 414 | ||
406 | dax_unlock_entry(&xas, dax_make_page_entry(page)); | 415 | rcu_read_lock(); |
416 | entry = xas_load(&xas); | ||
417 | rcu_read_unlock(); | ||
418 | entry = dax_make_entry(page_to_pfn_t(page), dax_is_pmd_entry(entry)); | ||
419 | dax_unlock_entry(&xas, entry); | ||
407 | } | 420 | } |
408 | 421 | ||
409 | /* | 422 | /* |
@@ -445,11 +458,9 @@ static void *grab_mapping_entry(struct xa_state *xas, | |||
445 | retry: | 458 | retry: |
446 | xas_lock_irq(xas); | 459 | xas_lock_irq(xas); |
447 | entry = get_unlocked_entry(xas); | 460 | entry = get_unlocked_entry(xas); |
448 | if (xa_is_internal(entry)) | ||
449 | goto fallback; | ||
450 | 461 | ||
451 | if (entry) { | 462 | if (entry) { |
452 | if (WARN_ON_ONCE(!xa_is_value(entry))) { | 463 | if (!xa_is_value(entry)) { |
453 | xas_set_err(xas, EIO); | 464 | xas_set_err(xas, EIO); |
454 | goto out_unlock; | 465 | goto out_unlock; |
455 | } | 466 | } |
@@ -1628,8 +1639,7 @@ dax_insert_pfn_mkwrite(struct vm_fault *vmf, pfn_t pfn, unsigned int order) | |||
1628 | /* Did we race with someone splitting entry or so? */ | 1639 | /* Did we race with someone splitting entry or so? */ |
1629 | if (!entry || | 1640 | if (!entry || |
1630 | (order == 0 && !dax_is_pte_entry(entry)) || | 1641 | (order == 0 && !dax_is_pte_entry(entry)) || |
1631 | (order == PMD_ORDER && (xa_is_internal(entry) || | 1642 | (order == PMD_ORDER && !dax_is_pmd_entry(entry))) { |
1632 | !dax_is_pmd_entry(entry)))) { | ||
1633 | put_unlocked_entry(&xas, entry); | 1643 | put_unlocked_entry(&xas, entry); |
1634 | xas_unlock_irq(&xas); | 1644 | xas_unlock_irq(&xas); |
1635 | trace_dax_insert_pfn_mkwrite_no_entry(mapping->host, vmf, | 1645 | trace_dax_insert_pfn_mkwrite_no_entry(mapping->host, vmf, |
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/oom.h> | 62 | #include <linux/oom.h> |
63 | #include <linux/compat.h> | 63 | #include <linux/compat.h> |
64 | #include <linux/vmalloc.h> | 64 | #include <linux/vmalloc.h> |
65 | #include <linux/freezer.h> | ||
65 | 66 | ||
66 | #include <linux/uaccess.h> | 67 | #include <linux/uaccess.h> |
67 | #include <asm/mmu_context.h> | 68 | #include <asm/mmu_context.h> |
@@ -1083,7 +1084,7 @@ static int de_thread(struct task_struct *tsk) | |||
1083 | while (sig->notify_count) { | 1084 | while (sig->notify_count) { |
1084 | __set_current_state(TASK_KILLABLE); | 1085 | __set_current_state(TASK_KILLABLE); |
1085 | spin_unlock_irq(lock); | 1086 | spin_unlock_irq(lock); |
1086 | schedule(); | 1087 | freezable_schedule(); |
1087 | if (unlikely(__fatal_signal_pending(tsk))) | 1088 | if (unlikely(__fatal_signal_pending(tsk))) |
1088 | goto killed; | 1089 | goto killed; |
1089 | spin_lock_irq(lock); | 1090 | spin_lock_irq(lock); |
@@ -1111,7 +1112,7 @@ static int de_thread(struct task_struct *tsk) | |||
1111 | __set_current_state(TASK_KILLABLE); | 1112 | __set_current_state(TASK_KILLABLE); |
1112 | write_unlock_irq(&tasklist_lock); | 1113 | write_unlock_irq(&tasklist_lock); |
1113 | cgroup_threadgroup_change_end(tsk); | 1114 | cgroup_threadgroup_change_end(tsk); |
1114 | schedule(); | 1115 | freezable_schedule(); |
1115 | if (unlikely(__fatal_signal_pending(tsk))) | 1116 | if (unlikely(__fatal_signal_pending(tsk))) |
1116 | goto killed; | 1117 | goto killed; |
1117 | } | 1118 | } |
diff --git a/fs/iomap.c b/fs/iomap.c index 64ce240217a1..3ffb776fbebe 100644 --- a/fs/iomap.c +++ b/fs/iomap.c | |||
@@ -142,13 +142,14 @@ static void | |||
142 | iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop, | 142 | iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop, |
143 | loff_t *pos, loff_t length, unsigned *offp, unsigned *lenp) | 143 | loff_t *pos, loff_t length, unsigned *offp, unsigned *lenp) |
144 | { | 144 | { |
145 | loff_t orig_pos = *pos; | ||
146 | loff_t isize = i_size_read(inode); | ||
145 | unsigned block_bits = inode->i_blkbits; | 147 | unsigned block_bits = inode->i_blkbits; |
146 | unsigned block_size = (1 << block_bits); | 148 | unsigned block_size = (1 << block_bits); |
147 | unsigned poff = offset_in_page(*pos); | 149 | unsigned poff = offset_in_page(*pos); |
148 | unsigned plen = min_t(loff_t, PAGE_SIZE - poff, length); | 150 | unsigned plen = min_t(loff_t, PAGE_SIZE - poff, length); |
149 | unsigned first = poff >> block_bits; | 151 | unsigned first = poff >> block_bits; |
150 | unsigned last = (poff + plen - 1) >> block_bits; | 152 | unsigned last = (poff + plen - 1) >> block_bits; |
151 | unsigned end = offset_in_page(i_size_read(inode)) >> block_bits; | ||
152 | 153 | ||
153 | /* | 154 | /* |
154 | * If the block size is smaller than the page size we need to check the | 155 | * If the block size is smaller than the page size we need to check the |
@@ -183,8 +184,12 @@ iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop, | |||
183 | * handle both halves separately so that we properly zero data in the | 184 | * handle both halves separately so that we properly zero data in the |
184 | * page cache for blocks that are entirely outside of i_size. | 185 | * page cache for blocks that are entirely outside of i_size. |
185 | */ | 186 | */ |
186 | if (first <= end && last > end) | 187 | if (orig_pos <= isize && orig_pos + length > isize) { |
187 | plen -= (last - end) * block_size; | 188 | unsigned end = offset_in_page(isize - 1) >> block_bits; |
189 | |||
190 | if (first <= end && last > end) | ||
191 | plen -= (last - end) * block_size; | ||
192 | } | ||
188 | 193 | ||
189 | *offp = poff; | 194 | *offp = poff; |
190 | *lenp = plen; | 195 | *lenp = plen; |
@@ -1580,7 +1585,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, | |||
1580 | struct bio *bio; | 1585 | struct bio *bio; |
1581 | bool need_zeroout = false; | 1586 | bool need_zeroout = false; |
1582 | bool use_fua = false; | 1587 | bool use_fua = false; |
1583 | int nr_pages, ret; | 1588 | int nr_pages, ret = 0; |
1584 | size_t copied = 0; | 1589 | size_t copied = 0; |
1585 | 1590 | ||
1586 | if ((pos | length | align) & ((1 << blkbits) - 1)) | 1591 | if ((pos | length | align) & ((1 << blkbits) - 1)) |
@@ -1596,12 +1601,13 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, | |||
1596 | 1601 | ||
1597 | if (iomap->flags & IOMAP_F_NEW) { | 1602 | if (iomap->flags & IOMAP_F_NEW) { |
1598 | need_zeroout = true; | 1603 | need_zeroout = true; |
1599 | } else { | 1604 | } else if (iomap->type == IOMAP_MAPPED) { |
1600 | /* | 1605 | /* |
1601 | * Use a FUA write if we need datasync semantics, this | 1606 | * Use a FUA write if we need datasync semantics, this is a pure |
1602 | * is a pure data IO that doesn't require any metadata | 1607 | * data IO that doesn't require any metadata updates (including |
1603 | * updates and the underlying device supports FUA. This | 1608 | * after IO completion such as unwritten extent conversion) and |
1604 | * allows us to avoid cache flushes on IO completion. | 1609 | * the underlying device supports FUA. This allows us to avoid |
1610 | * cache flushes on IO completion. | ||
1605 | */ | 1611 | */ |
1606 | if (!(iomap->flags & (IOMAP_F_SHARED|IOMAP_F_DIRTY)) && | 1612 | if (!(iomap->flags & (IOMAP_F_SHARED|IOMAP_F_DIRTY)) && |
1607 | (dio->flags & IOMAP_DIO_WRITE_FUA) && | 1613 | (dio->flags & IOMAP_DIO_WRITE_FUA) && |
@@ -1644,8 +1650,14 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, | |||
1644 | 1650 | ||
1645 | ret = bio_iov_iter_get_pages(bio, &iter); | 1651 | ret = bio_iov_iter_get_pages(bio, &iter); |
1646 | if (unlikely(ret)) { | 1652 | if (unlikely(ret)) { |
1653 | /* | ||
1654 | * We have to stop part way through an IO. We must fall | ||
1655 | * through to the sub-block tail zeroing here, otherwise | ||
1656 | * this short IO may expose stale data in the tail of | ||
1657 | * the block we haven't written data to. | ||
1658 | */ | ||
1647 | bio_put(bio); | 1659 | bio_put(bio); |
1648 | return copied ? copied : ret; | 1660 | goto zero_tail; |
1649 | } | 1661 | } |
1650 | 1662 | ||
1651 | n = bio->bi_iter.bi_size; | 1663 | n = bio->bi_iter.bi_size; |
@@ -1676,13 +1688,21 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length, | |||
1676 | dio->submit.cookie = submit_bio(bio); | 1688 | dio->submit.cookie = submit_bio(bio); |
1677 | } while (nr_pages); | 1689 | } while (nr_pages); |
1678 | 1690 | ||
1679 | if (need_zeroout) { | 1691 | /* |
1692 | * We need to zeroout the tail of a sub-block write if the extent type | ||
1693 | * requires zeroing or the write extends beyond EOF. If we don't zero | ||
1694 | * the block tail in the latter case, we can expose stale data via mmap | ||
1695 | * reads of the EOF block. | ||
1696 | */ | ||
1697 | zero_tail: | ||
1698 | if (need_zeroout || | ||
1699 | ((dio->flags & IOMAP_DIO_WRITE) && pos >= i_size_read(inode))) { | ||
1680 | /* zero out from the end of the write to the end of the block */ | 1700 | /* zero out from the end of the write to the end of the block */ |
1681 | pad = pos & (fs_block_size - 1); | 1701 | pad = pos & (fs_block_size - 1); |
1682 | if (pad) | 1702 | if (pad) |
1683 | iomap_dio_zero(dio, iomap, pos, fs_block_size - pad); | 1703 | iomap_dio_zero(dio, iomap, pos, fs_block_size - pad); |
1684 | } | 1704 | } |
1685 | return copied; | 1705 | return copied ? copied : ret; |
1686 | } | 1706 | } |
1687 | 1707 | ||
1688 | static loff_t | 1708 | static loff_t |
@@ -1857,6 +1877,15 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, | |||
1857 | dio->wait_for_completion = true; | 1877 | dio->wait_for_completion = true; |
1858 | ret = 0; | 1878 | ret = 0; |
1859 | } | 1879 | } |
1880 | |||
1881 | /* | ||
1882 | * Splicing to pipes can fail on a full pipe. We have to | ||
1883 | * swallow this to make it look like a short IO | ||
1884 | * otherwise the higher splice layers will completely | ||
1885 | * mishandle the error and stop moving data. | ||
1886 | */ | ||
1887 | if (ret == -EFAULT) | ||
1888 | ret = 0; | ||
1860 | break; | 1889 | break; |
1861 | } | 1890 | } |
1862 | pos += ret; | 1891 | pos += ret; |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 7b861bbc0b43..315967354954 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -686,20 +686,24 @@ __be32 nfs4_callback_offload(void *data, void *dummy, | |||
686 | { | 686 | { |
687 | struct cb_offloadargs *args = data; | 687 | struct cb_offloadargs *args = data; |
688 | struct nfs_server *server; | 688 | struct nfs_server *server; |
689 | struct nfs4_copy_state *copy; | 689 | struct nfs4_copy_state *copy, *tmp_copy; |
690 | bool found = false; | 690 | bool found = false; |
691 | 691 | ||
692 | copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); | ||
693 | if (!copy) | ||
694 | return htonl(NFS4ERR_SERVERFAULT); | ||
695 | |||
692 | spin_lock(&cps->clp->cl_lock); | 696 | spin_lock(&cps->clp->cl_lock); |
693 | rcu_read_lock(); | 697 | rcu_read_lock(); |
694 | list_for_each_entry_rcu(server, &cps->clp->cl_superblocks, | 698 | list_for_each_entry_rcu(server, &cps->clp->cl_superblocks, |
695 | client_link) { | 699 | client_link) { |
696 | list_for_each_entry(copy, &server->ss_copies, copies) { | 700 | list_for_each_entry(tmp_copy, &server->ss_copies, copies) { |
697 | if (memcmp(args->coa_stateid.other, | 701 | if (memcmp(args->coa_stateid.other, |
698 | copy->stateid.other, | 702 | tmp_copy->stateid.other, |
699 | sizeof(args->coa_stateid.other))) | 703 | sizeof(args->coa_stateid.other))) |
700 | continue; | 704 | continue; |
701 | nfs4_copy_cb_args(copy, args); | 705 | nfs4_copy_cb_args(tmp_copy, args); |
702 | complete(©->completion); | 706 | complete(&tmp_copy->completion); |
703 | found = true; | 707 | found = true; |
704 | goto out; | 708 | goto out; |
705 | } | 709 | } |
@@ -707,15 +711,11 @@ __be32 nfs4_callback_offload(void *data, void *dummy, | |||
707 | out: | 711 | out: |
708 | rcu_read_unlock(); | 712 | rcu_read_unlock(); |
709 | if (!found) { | 713 | if (!found) { |
710 | copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); | ||
711 | if (!copy) { | ||
712 | spin_unlock(&cps->clp->cl_lock); | ||
713 | return htonl(NFS4ERR_SERVERFAULT); | ||
714 | } | ||
715 | memcpy(©->stateid, &args->coa_stateid, NFS4_STATEID_SIZE); | 714 | memcpy(©->stateid, &args->coa_stateid, NFS4_STATEID_SIZE); |
716 | nfs4_copy_cb_args(copy, args); | 715 | nfs4_copy_cb_args(copy, args); |
717 | list_add_tail(©->copies, &cps->clp->pending_cb_stateids); | 716 | list_add_tail(©->copies, &cps->clp->pending_cb_stateids); |
718 | } | 717 | } else |
718 | kfree(copy); | ||
719 | spin_unlock(&cps->clp->cl_lock); | 719 | spin_unlock(&cps->clp->cl_lock); |
720 | 720 | ||
721 | return 0; | 721 | return 0; |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 86bcba40ca61..74b36ed883ca 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c | |||
@@ -1361,12 +1361,7 @@ static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data) | |||
1361 | task)) | 1361 | task)) |
1362 | return; | 1362 | return; |
1363 | 1363 | ||
1364 | if (ff_layout_read_prepare_common(task, hdr)) | 1364 | ff_layout_read_prepare_common(task, hdr); |
1365 | return; | ||
1366 | |||
1367 | if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context, | ||
1368 | hdr->args.lock_context, FMODE_READ) == -EIO) | ||
1369 | rpc_exit(task, -EIO); /* lost lock, terminate I/O */ | ||
1370 | } | 1365 | } |
1371 | 1366 | ||
1372 | static void ff_layout_read_call_done(struct rpc_task *task, void *data) | 1367 | static void ff_layout_read_call_done(struct rpc_task *task, void *data) |
@@ -1542,12 +1537,7 @@ static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data) | |||
1542 | task)) | 1537 | task)) |
1543 | return; | 1538 | return; |
1544 | 1539 | ||
1545 | if (ff_layout_write_prepare_common(task, hdr)) | 1540 | ff_layout_write_prepare_common(task, hdr); |
1546 | return; | ||
1547 | |||
1548 | if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context, | ||
1549 | hdr->args.lock_context, FMODE_WRITE) == -EIO) | ||
1550 | rpc_exit(task, -EIO); /* lost lock, terminate I/O */ | ||
1551 | } | 1541 | } |
1552 | 1542 | ||
1553 | static void ff_layout_write_call_done(struct rpc_task *task, void *data) | 1543 | static void ff_layout_write_call_done(struct rpc_task *task, void *data) |
@@ -1742,6 +1732,10 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) | |||
1742 | fh = nfs4_ff_layout_select_ds_fh(lseg, idx); | 1732 | fh = nfs4_ff_layout_select_ds_fh(lseg, idx); |
1743 | if (fh) | 1733 | if (fh) |
1744 | hdr->args.fh = fh; | 1734 | hdr->args.fh = fh; |
1735 | |||
1736 | if (!nfs4_ff_layout_select_ds_stateid(lseg, idx, &hdr->args.stateid)) | ||
1737 | goto out_failed; | ||
1738 | |||
1745 | /* | 1739 | /* |
1746 | * Note that if we ever decide to split across DSes, | 1740 | * Note that if we ever decide to split across DSes, |
1747 | * then we may need to handle dense-like offsets. | 1741 | * then we may need to handle dense-like offsets. |
@@ -1804,6 +1798,9 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) | |||
1804 | if (fh) | 1798 | if (fh) |
1805 | hdr->args.fh = fh; | 1799 | hdr->args.fh = fh; |
1806 | 1800 | ||
1801 | if (!nfs4_ff_layout_select_ds_stateid(lseg, idx, &hdr->args.stateid)) | ||
1802 | goto out_failed; | ||
1803 | |||
1807 | /* | 1804 | /* |
1808 | * Note that if we ever decide to split across DSes, | 1805 | * Note that if we ever decide to split across DSes, |
1809 | * then we may need to handle dense-like offsets. | 1806 | * then we may need to handle dense-like offsets. |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h index 411798346e48..de50a342d5a5 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.h +++ b/fs/nfs/flexfilelayout/flexfilelayout.h | |||
@@ -215,6 +215,10 @@ unsigned int ff_layout_fetch_ds_ioerr(struct pnfs_layout_hdr *lo, | |||
215 | unsigned int maxnum); | 215 | unsigned int maxnum); |
216 | struct nfs_fh * | 216 | struct nfs_fh * |
217 | nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx); | 217 | nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx); |
218 | int | ||
219 | nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg, | ||
220 | u32 mirror_idx, | ||
221 | nfs4_stateid *stateid); | ||
218 | 222 | ||
219 | struct nfs4_pnfs_ds * | 223 | struct nfs4_pnfs_ds * |
220 | nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, | 224 | nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, |
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index 74d8d5352438..d23347389626 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c | |||
@@ -370,6 +370,25 @@ out: | |||
370 | return fh; | 370 | return fh; |
371 | } | 371 | } |
372 | 372 | ||
373 | int | ||
374 | nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg, | ||
375 | u32 mirror_idx, | ||
376 | nfs4_stateid *stateid) | ||
377 | { | ||
378 | struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx); | ||
379 | |||
380 | if (!ff_layout_mirror_valid(lseg, mirror, false)) { | ||
381 | pr_err_ratelimited("NFS: %s: No data server for mirror offset index %d\n", | ||
382 | __func__, mirror_idx); | ||
383 | goto out; | ||
384 | } | ||
385 | |||
386 | nfs4_stateid_copy(stateid, &mirror->stateid); | ||
387 | return 1; | ||
388 | out: | ||
389 | return 0; | ||
390 | } | ||
391 | |||
373 | /** | 392 | /** |
374 | * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call | 393 | * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call |
375 | * @lseg: the layout segment we're operating on | 394 | * @lseg: the layout segment we're operating on |
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index ac5b784a1de0..fed06fd9998d 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c | |||
@@ -137,31 +137,32 @@ static int handle_async_copy(struct nfs42_copy_res *res, | |||
137 | struct file *dst, | 137 | struct file *dst, |
138 | nfs4_stateid *src_stateid) | 138 | nfs4_stateid *src_stateid) |
139 | { | 139 | { |
140 | struct nfs4_copy_state *copy; | 140 | struct nfs4_copy_state *copy, *tmp_copy; |
141 | int status = NFS4_OK; | 141 | int status = NFS4_OK; |
142 | bool found_pending = false; | 142 | bool found_pending = false; |
143 | struct nfs_open_context *ctx = nfs_file_open_context(dst); | 143 | struct nfs_open_context *ctx = nfs_file_open_context(dst); |
144 | 144 | ||
145 | copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); | ||
146 | if (!copy) | ||
147 | return -ENOMEM; | ||
148 | |||
145 | spin_lock(&server->nfs_client->cl_lock); | 149 | spin_lock(&server->nfs_client->cl_lock); |
146 | list_for_each_entry(copy, &server->nfs_client->pending_cb_stateids, | 150 | list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids, |
147 | copies) { | 151 | copies) { |
148 | if (memcmp(&res->write_res.stateid, ©->stateid, | 152 | if (memcmp(&res->write_res.stateid, &tmp_copy->stateid, |
149 | NFS4_STATEID_SIZE)) | 153 | NFS4_STATEID_SIZE)) |
150 | continue; | 154 | continue; |
151 | found_pending = true; | 155 | found_pending = true; |
152 | list_del(©->copies); | 156 | list_del(&tmp_copy->copies); |
153 | break; | 157 | break; |
154 | } | 158 | } |
155 | if (found_pending) { | 159 | if (found_pending) { |
156 | spin_unlock(&server->nfs_client->cl_lock); | 160 | spin_unlock(&server->nfs_client->cl_lock); |
161 | kfree(copy); | ||
162 | copy = tmp_copy; | ||
157 | goto out; | 163 | goto out; |
158 | } | 164 | } |
159 | 165 | ||
160 | copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); | ||
161 | if (!copy) { | ||
162 | spin_unlock(&server->nfs_client->cl_lock); | ||
163 | return -ENOMEM; | ||
164 | } | ||
165 | memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE); | 166 | memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE); |
166 | init_completion(©->completion); | 167 | init_completion(©->completion); |
167 | copy->parent_state = ctx->state; | 168 | copy->parent_state = ctx->state; |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 8d59c9655ec4..1b994b527518 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -41,6 +41,8 @@ enum nfs4_client_state { | |||
41 | NFS4CLNT_MOVED, | 41 | NFS4CLNT_MOVED, |
42 | NFS4CLNT_LEASE_MOVED, | 42 | NFS4CLNT_LEASE_MOVED, |
43 | NFS4CLNT_DELEGATION_EXPIRED, | 43 | NFS4CLNT_DELEGATION_EXPIRED, |
44 | NFS4CLNT_RUN_MANAGER, | ||
45 | NFS4CLNT_DELEGRETURN_RUNNING, | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | #define NFS4_RENEW_TIMEOUT 0x01 | 48 | #define NFS4_RENEW_TIMEOUT 0x01 |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index ffea57885394..d8decf2ec48f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1210,6 +1210,7 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) | |||
1210 | struct task_struct *task; | 1210 | struct task_struct *task; |
1211 | char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; | 1211 | char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; |
1212 | 1212 | ||
1213 | set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); | ||
1213 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) | 1214 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) |
1214 | return; | 1215 | return; |
1215 | __module_get(THIS_MODULE); | 1216 | __module_get(THIS_MODULE); |
@@ -2503,6 +2504,7 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
2503 | 2504 | ||
2504 | /* Ensure exclusive access to NFSv4 state */ | 2505 | /* Ensure exclusive access to NFSv4 state */ |
2505 | do { | 2506 | do { |
2507 | clear_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); | ||
2506 | if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) { | 2508 | if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) { |
2507 | section = "purge state"; | 2509 | section = "purge state"; |
2508 | status = nfs4_purge_lease(clp); | 2510 | status = nfs4_purge_lease(clp); |
@@ -2593,14 +2595,18 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
2593 | } | 2595 | } |
2594 | 2596 | ||
2595 | nfs4_end_drain_session(clp); | 2597 | nfs4_end_drain_session(clp); |
2596 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { | 2598 | nfs4_clear_state_manager_bit(clp); |
2597 | nfs_client_return_marked_delegations(clp); | 2599 | |
2598 | continue; | 2600 | if (!test_and_set_bit(NFS4CLNT_DELEGRETURN_RUNNING, &clp->cl_state)) { |
2601 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { | ||
2602 | nfs_client_return_marked_delegations(clp); | ||
2603 | set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); | ||
2604 | } | ||
2605 | clear_bit(NFS4CLNT_DELEGRETURN_RUNNING, &clp->cl_state); | ||
2599 | } | 2606 | } |
2600 | 2607 | ||
2601 | nfs4_clear_state_manager_bit(clp); | ||
2602 | /* Did we race with an attempt to give us more work? */ | 2608 | /* Did we race with an attempt to give us more work? */ |
2603 | if (clp->cl_state == 0) | 2609 | if (!test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)) |
2604 | return; | 2610 | return; |
2605 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) | 2611 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) |
2606 | return; | 2612 | return; |
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c index de99db518571..f2129a5d9f23 100644 --- a/fs/nilfs2/btnode.c +++ b/fs/nilfs2/btnode.c | |||
@@ -266,9 +266,7 @@ void nilfs_btnode_abort_change_key(struct address_space *btnc, | |||
266 | return; | 266 | return; |
267 | 267 | ||
268 | if (nbh == NULL) { /* blocksize == pagesize */ | 268 | if (nbh == NULL) { /* blocksize == pagesize */ |
269 | xa_lock_irq(&btnc->i_pages); | 269 | xa_erase_irq(&btnc->i_pages, newkey); |
270 | __xa_erase(&btnc->i_pages, newkey); | ||
271 | xa_unlock_irq(&btnc->i_pages); | ||
272 | unlock_page(ctxt->bh->b_page); | 270 | unlock_page(ctxt->bh->b_page); |
273 | } else | 271 | } else |
274 | brelse(nbh); | 272 | brelse(nbh); |
diff --git a/fs/read_write.c b/fs/read_write.c index bfcb4ced5664..4dae0399c75a 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -2094,17 +2094,18 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same) | |||
2094 | off = same->src_offset; | 2094 | off = same->src_offset; |
2095 | len = same->src_length; | 2095 | len = same->src_length; |
2096 | 2096 | ||
2097 | ret = -EISDIR; | ||
2098 | if (S_ISDIR(src->i_mode)) | 2097 | if (S_ISDIR(src->i_mode)) |
2099 | goto out; | 2098 | return -EISDIR; |
2100 | 2099 | ||
2101 | ret = -EINVAL; | ||
2102 | if (!S_ISREG(src->i_mode)) | 2100 | if (!S_ISREG(src->i_mode)) |
2103 | goto out; | 2101 | return -EINVAL; |
2102 | |||
2103 | if (!file->f_op->remap_file_range) | ||
2104 | return -EOPNOTSUPP; | ||
2104 | 2105 | ||
2105 | ret = remap_verify_area(file, off, len, false); | 2106 | ret = remap_verify_area(file, off, len, false); |
2106 | if (ret < 0) | 2107 | if (ret < 0) |
2107 | goto out; | 2108 | return ret; |
2108 | ret = 0; | 2109 | ret = 0; |
2109 | 2110 | ||
2110 | if (off + len > i_size_read(src)) | 2111 | if (off + len > i_size_read(src)) |
@@ -2147,10 +2148,8 @@ next_fdput: | |||
2147 | fdput(dst_fd); | 2148 | fdput(dst_fd); |
2148 | next_loop: | 2149 | next_loop: |
2149 | if (fatal_signal_pending(current)) | 2150 | if (fatal_signal_pending(current)) |
2150 | goto out; | 2151 | break; |
2151 | } | 2152 | } |
2152 | |||
2153 | out: | ||
2154 | return ret; | 2153 | return ret; |
2155 | } | 2154 | } |
2156 | EXPORT_SYMBOL(vfs_dedupe_file_range); | 2155 | EXPORT_SYMBOL(vfs_dedupe_file_range); |
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 74d7228e755b..19e921d1586f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -1694,10 +1694,13 @@ xfs_bmap_add_extent_delay_real( | |||
1694 | case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: | 1694 | case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: |
1695 | /* | 1695 | /* |
1696 | * Filling in all of a previously delayed allocation extent. | 1696 | * Filling in all of a previously delayed allocation extent. |
1697 | * The right neighbor is contiguous, the left is not. | 1697 | * The right neighbor is contiguous, the left is not. Take care |
1698 | * with delay -> unwritten extent allocation here because the | ||
1699 | * delalloc record we are overwriting is always written. | ||
1698 | */ | 1700 | */ |
1699 | PREV.br_startblock = new->br_startblock; | 1701 | PREV.br_startblock = new->br_startblock; |
1700 | PREV.br_blockcount += RIGHT.br_blockcount; | 1702 | PREV.br_blockcount += RIGHT.br_blockcount; |
1703 | PREV.br_state = new->br_state; | ||
1701 | 1704 | ||
1702 | xfs_iext_next(ifp, &bma->icur); | 1705 | xfs_iext_next(ifp, &bma->icur); |
1703 | xfs_iext_remove(bma->ip, &bma->icur, state); | 1706 | xfs_iext_remove(bma->ip, &bma->icur, state); |
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 86c50208a143..7fbf8af0b159 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c | |||
@@ -538,15 +538,18 @@ xfs_inobt_rec_check_count( | |||
538 | 538 | ||
539 | static xfs_extlen_t | 539 | static xfs_extlen_t |
540 | xfs_inobt_max_size( | 540 | xfs_inobt_max_size( |
541 | struct xfs_mount *mp) | 541 | struct xfs_mount *mp, |
542 | xfs_agnumber_t agno) | ||
542 | { | 543 | { |
544 | xfs_agblock_t agblocks = xfs_ag_block_count(mp, agno); | ||
545 | |||
543 | /* Bail out if we're uninitialized, which can happen in mkfs. */ | 546 | /* Bail out if we're uninitialized, which can happen in mkfs. */ |
544 | if (mp->m_inobt_mxr[0] == 0) | 547 | if (mp->m_inobt_mxr[0] == 0) |
545 | return 0; | 548 | return 0; |
546 | 549 | ||
547 | return xfs_btree_calc_size(mp->m_inobt_mnr, | 550 | return xfs_btree_calc_size(mp->m_inobt_mnr, |
548 | (uint64_t)mp->m_sb.sb_agblocks * mp->m_sb.sb_inopblock / | 551 | (uint64_t)agblocks * mp->m_sb.sb_inopblock / |
549 | XFS_INODES_PER_CHUNK); | 552 | XFS_INODES_PER_CHUNK); |
550 | } | 553 | } |
551 | 554 | ||
552 | static int | 555 | static int |
@@ -594,7 +597,7 @@ xfs_finobt_calc_reserves( | |||
594 | if (error) | 597 | if (error) |
595 | return error; | 598 | return error; |
596 | 599 | ||
597 | *ask += xfs_inobt_max_size(mp); | 600 | *ask += xfs_inobt_max_size(mp, agno); |
598 | *used += tree_len; | 601 | *used += tree_len; |
599 | return 0; | 602 | return 0; |
600 | } | 603 | } |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 5d263dfdb3bc..404e581f1ea1 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -1042,7 +1042,7 @@ out_trans_cancel: | |||
1042 | goto out_unlock; | 1042 | goto out_unlock; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | static int | 1045 | int |
1046 | xfs_flush_unmap_range( | 1046 | xfs_flush_unmap_range( |
1047 | struct xfs_inode *ip, | 1047 | struct xfs_inode *ip, |
1048 | xfs_off_t offset, | 1048 | xfs_off_t offset, |
@@ -1195,13 +1195,7 @@ xfs_prepare_shift( | |||
1195 | * Writeback and invalidate cache for the remainder of the file as we're | 1195 | * Writeback and invalidate cache for the remainder of the file as we're |
1196 | * about to shift down every extent from offset to EOF. | 1196 | * about to shift down every extent from offset to EOF. |
1197 | */ | 1197 | */ |
1198 | error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, offset, -1); | 1198 | error = xfs_flush_unmap_range(ip, offset, XFS_ISIZE(ip)); |
1199 | if (error) | ||
1200 | return error; | ||
1201 | error = invalidate_inode_pages2_range(VFS_I(ip)->i_mapping, | ||
1202 | offset >> PAGE_SHIFT, -1); | ||
1203 | if (error) | ||
1204 | return error; | ||
1205 | 1199 | ||
1206 | /* | 1200 | /* |
1207 | * Clean out anything hanging around in the cow fork now that | 1201 | * Clean out anything hanging around in the cow fork now that |
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index 87363d136bb6..7a78229cf1a7 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h | |||
@@ -80,4 +80,7 @@ int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip, | |||
80 | int whichfork, xfs_extnum_t *nextents, | 80 | int whichfork, xfs_extnum_t *nextents, |
81 | xfs_filblks_t *count); | 81 | xfs_filblks_t *count); |
82 | 82 | ||
83 | int xfs_flush_unmap_range(struct xfs_inode *ip, xfs_off_t offset, | ||
84 | xfs_off_t len); | ||
85 | |||
83 | #endif /* __XFS_BMAP_UTIL_H__ */ | 86 | #endif /* __XFS_BMAP_UTIL_H__ */ |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 12d8455bfbb2..010db5f8fb00 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -1233,9 +1233,23 @@ xfs_buf_iodone( | |||
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | /* | 1235 | /* |
1236 | * Requeue a failed buffer for writeback | 1236 | * Requeue a failed buffer for writeback. |
1237 | * | 1237 | * |
1238 | * Return true if the buffer has been re-queued properly, false otherwise | 1238 | * We clear the log item failed state here as well, but we have to be careful |
1239 | * about reference counts because the only active reference counts on the buffer | ||
1240 | * may be the failed log items. Hence if we clear the log item failed state | ||
1241 | * before queuing the buffer for IO we can release all active references to | ||
1242 | * the buffer and free it, leading to use after free problems in | ||
1243 | * xfs_buf_delwri_queue. It makes no difference to the buffer or log items which | ||
1244 | * order we process them in - the buffer is locked, and we own the buffer list | ||
1245 | * so nothing on them is going to change while we are performing this action. | ||
1246 | * | ||
1247 | * Hence we can safely queue the buffer for IO before we clear the failed log | ||
1248 | * item state, therefore always having an active reference to the buffer and | ||
1249 | * avoiding the transient zero-reference state that leads to use-after-free. | ||
1250 | * | ||
1251 | * Return true if the buffer was added to the buffer list, false if it was | ||
1252 | * already on the buffer list. | ||
1239 | */ | 1253 | */ |
1240 | bool | 1254 | bool |
1241 | xfs_buf_resubmit_failed_buffers( | 1255 | xfs_buf_resubmit_failed_buffers( |
@@ -1243,16 +1257,16 @@ xfs_buf_resubmit_failed_buffers( | |||
1243 | struct list_head *buffer_list) | 1257 | struct list_head *buffer_list) |
1244 | { | 1258 | { |
1245 | struct xfs_log_item *lip; | 1259 | struct xfs_log_item *lip; |
1260 | bool ret; | ||
1261 | |||
1262 | ret = xfs_buf_delwri_queue(bp, buffer_list); | ||
1246 | 1263 | ||
1247 | /* | 1264 | /* |
1248 | * Clear XFS_LI_FAILED flag from all items before resubmit | 1265 | * XFS_LI_FAILED set/clear is protected by ail_lock, caller of this |
1249 | * | ||
1250 | * XFS_LI_FAILED set/clear is protected by ail_lock, caller this | ||
1251 | * function already have it acquired | 1266 | * function already have it acquired |
1252 | */ | 1267 | */ |
1253 | list_for_each_entry(lip, &bp->b_li_list, li_bio_list) | 1268 | list_for_each_entry(lip, &bp->b_li_list, li_bio_list) |
1254 | xfs_clear_li_failed(lip); | 1269 | xfs_clear_li_failed(lip); |
1255 | 1270 | ||
1256 | /* Add this buffer back to the delayed write list */ | 1271 | return ret; |
1257 | return xfs_buf_delwri_queue(bp, buffer_list); | ||
1258 | } | 1272 | } |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 53c9ab8fb777..e47425071e65 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -920,7 +920,7 @@ out_unlock: | |||
920 | } | 920 | } |
921 | 921 | ||
922 | 922 | ||
923 | loff_t | 923 | STATIC loff_t |
924 | xfs_file_remap_range( | 924 | xfs_file_remap_range( |
925 | struct file *file_in, | 925 | struct file *file_in, |
926 | loff_t pos_in, | 926 | loff_t pos_in, |
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index ecdb086bc23e..322a852ce284 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c | |||
@@ -296,6 +296,7 @@ xfs_reflink_reserve_cow( | |||
296 | if (error) | 296 | if (error) |
297 | return error; | 297 | return error; |
298 | 298 | ||
299 | xfs_trim_extent(imap, got.br_startoff, got.br_blockcount); | ||
299 | trace_xfs_reflink_cow_alloc(ip, &got); | 300 | trace_xfs_reflink_cow_alloc(ip, &got); |
300 | return 0; | 301 | return 0; |
301 | } | 302 | } |
@@ -1351,10 +1352,19 @@ xfs_reflink_remap_prep( | |||
1351 | if (ret) | 1352 | if (ret) |
1352 | goto out_unlock; | 1353 | goto out_unlock; |
1353 | 1354 | ||
1354 | /* Zap any page cache for the destination file's range. */ | 1355 | /* |
1355 | truncate_inode_pages_range(&inode_out->i_data, | 1356 | * If pos_out > EOF, we may have dirtied blocks between EOF and |
1356 | round_down(pos_out, PAGE_SIZE), | 1357 | * pos_out. In that case, we need to extend the flush and unmap to cover |
1357 | round_up(pos_out + *len, PAGE_SIZE) - 1); | 1358 | * from EOF to the end of the copy length. |
1359 | */ | ||
1360 | if (pos_out > XFS_ISIZE(dest)) { | ||
1361 | loff_t flen = *len + (pos_out - XFS_ISIZE(dest)); | ||
1362 | ret = xfs_flush_unmap_range(dest, XFS_ISIZE(dest), flen); | ||
1363 | } else { | ||
1364 | ret = xfs_flush_unmap_range(dest, pos_out, *len); | ||
1365 | } | ||
1366 | if (ret) | ||
1367 | goto out_unlock; | ||
1358 | 1368 | ||
1359 | return 1; | 1369 | return 1; |
1360 | out_unlock: | 1370 | out_unlock: |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 3043e5ed6495..8a6532aae779 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -280,7 +280,10 @@ DECLARE_EVENT_CLASS(xfs_buf_class, | |||
280 | ), | 280 | ), |
281 | TP_fast_assign( | 281 | TP_fast_assign( |
282 | __entry->dev = bp->b_target->bt_dev; | 282 | __entry->dev = bp->b_target->bt_dev; |
283 | __entry->bno = bp->b_bn; | 283 | if (bp->b_bn == XFS_BUF_DADDR_NULL) |
284 | __entry->bno = bp->b_maps[0].bm_bn; | ||
285 | else | ||
286 | __entry->bno = bp->b_bn; | ||
284 | __entry->nblks = bp->b_length; | 287 | __entry->nblks = bp->b_length; |
285 | __entry->hold = atomic_read(&bp->b_hold); | 288 | __entry->hold = atomic_read(&bp->b_hold); |
286 | __entry->pincount = atomic_read(&bp->b_pin_count); | 289 | __entry->pincount = atomic_read(&bp->b_pin_count); |
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index a83e1f632eb7..f01623aef2f7 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h | |||
@@ -169,6 +169,7 @@ void can_change_state(struct net_device *dev, struct can_frame *cf, | |||
169 | 169 | ||
170 | void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | 170 | void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, |
171 | unsigned int idx); | 171 | unsigned int idx); |
172 | struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr); | ||
172 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); | 173 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); |
173 | void can_free_echo_skb(struct net_device *dev, unsigned int idx); | 174 | void can_free_echo_skb(struct net_device *dev, unsigned int idx); |
174 | 175 | ||
diff --git a/include/linux/can/rx-offload.h b/include/linux/can/rx-offload.h index cb31683bbe15..8268811a697e 100644 --- a/include/linux/can/rx-offload.h +++ b/include/linux/can/rx-offload.h | |||
@@ -41,7 +41,12 @@ int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload * | |||
41 | int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight); | 41 | int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight); |
42 | int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 reg); | 42 | int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 reg); |
43 | int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload); | 43 | int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload); |
44 | int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb); | 44 | int can_rx_offload_queue_sorted(struct can_rx_offload *offload, |
45 | struct sk_buff *skb, u32 timestamp); | ||
46 | unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, | ||
47 | unsigned int idx, u32 timestamp); | ||
48 | int can_rx_offload_queue_tail(struct can_rx_offload *offload, | ||
49 | struct sk_buff *skb); | ||
45 | void can_rx_offload_reset(struct can_rx_offload *offload); | 50 | void can_rx_offload_reset(struct can_rx_offload *offload); |
46 | void can_rx_offload_del(struct can_rx_offload *offload); | 51 | void can_rx_offload_del(struct can_rx_offload *offload); |
47 | void can_rx_offload_enable(struct can_rx_offload *offload); | 52 | void can_rx_offload_enable(struct can_rx_offload *offload); |
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index bd73e7a91410..9e66bfe369aa 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/dma-mapping.h> | 5 | #include <linux/dma-mapping.h> |
6 | #include <linux/mem_encrypt.h> | 6 | #include <linux/mem_encrypt.h> |
7 | 7 | ||
8 | #define DIRECT_MAPPING_ERROR 0 | 8 | #define DIRECT_MAPPING_ERROR (~(dma_addr_t)0) |
9 | 9 | ||
10 | #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA | 10 | #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA |
11 | #include <asm/dma-direct.h> | 11 | #include <asm/dma-direct.h> |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 387c70df6f29..a355d61940f2 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -1139,34 +1139,6 @@ static inline u32 hid_report_len(struct hid_report *report) | |||
1139 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, | 1139 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, |
1140 | int interrupt); | 1140 | int interrupt); |
1141 | 1141 | ||
1142 | |||
1143 | /** | ||
1144 | * struct hid_scroll_counter - Utility class for processing high-resolution | ||
1145 | * scroll events. | ||
1146 | * @dev: the input device for which events should be reported. | ||
1147 | * @microns_per_hi_res_unit: the amount moved by the user's finger for each | ||
1148 | * high-resolution unit reported by the mouse, in | ||
1149 | * microns. | ||
1150 | * @resolution_multiplier: the wheel's resolution in high-resolution mode as a | ||
1151 | * multiple of its lower resolution. For example, if | ||
1152 | * moving the wheel by one "notch" would result in a | ||
1153 | * value of 1 in low-resolution mode but 8 in | ||
1154 | * high-resolution, the multiplier is 8. | ||
1155 | * @remainder: counts the number of high-resolution units moved since the last | ||
1156 | * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should | ||
1157 | * only be used by class methods. | ||
1158 | */ | ||
1159 | struct hid_scroll_counter { | ||
1160 | struct input_dev *dev; | ||
1161 | int microns_per_hi_res_unit; | ||
1162 | int resolution_multiplier; | ||
1163 | |||
1164 | int remainder; | ||
1165 | }; | ||
1166 | |||
1167 | void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter, | ||
1168 | int hi_res_value); | ||
1169 | |||
1170 | /* HID quirks API */ | 1142 | /* HID quirks API */ |
1171 | unsigned long hid_lookup_quirk(const struct hid_device *hdev); | 1143 | unsigned long hid_lookup_quirk(const struct hid_device *hdev); |
1172 | int hid_quirks_init(char **quirks_param, __u16 bus, int count); | 1144 | int hid_quirks_init(char **quirks_param, __u16 bus, int count); |
diff --git a/include/linux/net_dim.h b/include/linux/net_dim.h index c79e859408e6..fd458389f7d1 100644 --- a/include/linux/net_dim.h +++ b/include/linux/net_dim.h | |||
@@ -406,6 +406,8 @@ static inline void net_dim(struct net_dim *dim, | |||
406 | } | 406 | } |
407 | /* fall through */ | 407 | /* fall through */ |
408 | case NET_DIM_START_MEASURE: | 408 | case NET_DIM_START_MEASURE: |
409 | net_dim_sample(end_sample.event_ctr, end_sample.pkt_ctr, end_sample.byte_ctr, | ||
410 | &dim->start_sample); | ||
409 | dim->state = NET_DIM_MEASURE_IN_PROGRESS; | 411 | dim->state = NET_DIM_MEASURE_IN_PROGRESS; |
410 | break; | 412 | break; |
411 | case NET_DIM_APPLY_NEW_PROFILE: | 413 | case NET_DIM_APPLY_NEW_PROFILE: |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 0ba687454267..0d1b2c3f127b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -1326,6 +1326,22 @@ static inline void skb_zcopy_set(struct sk_buff *skb, struct ubuf_info *uarg) | |||
1326 | } | 1326 | } |
1327 | } | 1327 | } |
1328 | 1328 | ||
1329 | static inline void skb_zcopy_set_nouarg(struct sk_buff *skb, void *val) | ||
1330 | { | ||
1331 | skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t) val | 0x1UL); | ||
1332 | skb_shinfo(skb)->tx_flags |= SKBTX_ZEROCOPY_FRAG; | ||
1333 | } | ||
1334 | |||
1335 | static inline bool skb_zcopy_is_nouarg(struct sk_buff *skb) | ||
1336 | { | ||
1337 | return (uintptr_t) skb_shinfo(skb)->destructor_arg & 0x1UL; | ||
1338 | } | ||
1339 | |||
1340 | static inline void *skb_zcopy_get_nouarg(struct sk_buff *skb) | ||
1341 | { | ||
1342 | return (void *)((uintptr_t) skb_shinfo(skb)->destructor_arg & ~0x1UL); | ||
1343 | } | ||
1344 | |||
1329 | /* Release a reference on a zerocopy structure */ | 1345 | /* Release a reference on a zerocopy structure */ |
1330 | static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy) | 1346 | static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy) |
1331 | { | 1347 | { |
@@ -1335,7 +1351,7 @@ static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy) | |||
1335 | if (uarg->callback == sock_zerocopy_callback) { | 1351 | if (uarg->callback == sock_zerocopy_callback) { |
1336 | uarg->zerocopy = uarg->zerocopy && zerocopy; | 1352 | uarg->zerocopy = uarg->zerocopy && zerocopy; |
1337 | sock_zerocopy_put(uarg); | 1353 | sock_zerocopy_put(uarg); |
1338 | } else { | 1354 | } else if (!skb_zcopy_is_nouarg(skb)) { |
1339 | uarg->callback(uarg, zerocopy); | 1355 | uarg->callback(uarg, zerocopy); |
1340 | } | 1356 | } |
1341 | 1357 | ||
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 8ed77bb4ed86..a9b0280687d5 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
@@ -196,6 +196,7 @@ struct tcp_sock { | |||
196 | u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ | 196 | u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ |
197 | u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ | 197 | u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ |
198 | u32 last_oow_ack_time; /* timestamp of last out-of-window ACK */ | 198 | u32 last_oow_ack_time; /* timestamp of last out-of-window ACK */ |
199 | u32 compressed_ack_rcv_nxt; | ||
199 | 200 | ||
200 | u32 tsoffset; /* timestamp offset */ | 201 | u32 tsoffset; /* timestamp offset */ |
201 | 202 | ||
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index b7a99ce56bc9..a1be64c9940f 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h | |||
@@ -66,4 +66,7 @@ | |||
66 | /* Device needs a pause after every control message. */ | 66 | /* Device needs a pause after every control message. */ |
67 | #define USB_QUIRK_DELAY_CTRL_MSG BIT(13) | 67 | #define USB_QUIRK_DELAY_CTRL_MSG BIT(13) |
68 | 68 | ||
69 | /* Hub needs extra delay after resetting its port. */ | ||
70 | #define USB_QUIRK_HUB_SLOW_RESET BIT(14) | ||
71 | |||
69 | #endif /* __LINUX_USB_QUIRKS_H */ | 72 | #endif /* __LINUX_USB_QUIRKS_H */ |
diff --git a/include/linux/xarray.h b/include/linux/xarray.h index d9514928ddac..564892e19f8c 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h | |||
@@ -289,9 +289,7 @@ struct xarray { | |||
289 | void xa_init_flags(struct xarray *, gfp_t flags); | 289 | void xa_init_flags(struct xarray *, gfp_t flags); |
290 | void *xa_load(struct xarray *, unsigned long index); | 290 | void *xa_load(struct xarray *, unsigned long index); |
291 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | 291 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); |
292 | void *xa_cmpxchg(struct xarray *, unsigned long index, | 292 | void *xa_erase(struct xarray *, unsigned long index); |
293 | void *old, void *entry, gfp_t); | ||
294 | int xa_reserve(struct xarray *, unsigned long index, gfp_t); | ||
295 | void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, | 293 | void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, |
296 | void *entry, gfp_t); | 294 | void *entry, gfp_t); |
297 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); | 295 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); |
@@ -344,65 +342,6 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark) | |||
344 | } | 342 | } |
345 | 343 | ||
346 | /** | 344 | /** |
347 | * xa_erase() - Erase this entry from the XArray. | ||
348 | * @xa: XArray. | ||
349 | * @index: Index of entry. | ||
350 | * | ||
351 | * This function is the equivalent of calling xa_store() with %NULL as | ||
352 | * the third argument. The XArray does not need to allocate memory, so | ||
353 | * the user does not need to provide GFP flags. | ||
354 | * | ||
355 | * Context: Process context. Takes and releases the xa_lock. | ||
356 | * Return: The entry which used to be at this index. | ||
357 | */ | ||
358 | static inline void *xa_erase(struct xarray *xa, unsigned long index) | ||
359 | { | ||
360 | return xa_store(xa, index, NULL, 0); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * xa_insert() - Store this entry in the XArray unless another entry is | ||
365 | * already present. | ||
366 | * @xa: XArray. | ||
367 | * @index: Index into array. | ||
368 | * @entry: New entry. | ||
369 | * @gfp: Memory allocation flags. | ||
370 | * | ||
371 | * If you would rather see the existing entry in the array, use xa_cmpxchg(). | ||
372 | * This function is for users who don't care what the entry is, only that | ||
373 | * one is present. | ||
374 | * | ||
375 | * Context: Process context. Takes and releases the xa_lock. | ||
376 | * May sleep if the @gfp flags permit. | ||
377 | * Return: 0 if the store succeeded. -EEXIST if another entry was present. | ||
378 | * -ENOMEM if memory could not be allocated. | ||
379 | */ | ||
380 | static inline int xa_insert(struct xarray *xa, unsigned long index, | ||
381 | void *entry, gfp_t gfp) | ||
382 | { | ||
383 | void *curr = xa_cmpxchg(xa, index, NULL, entry, gfp); | ||
384 | if (!curr) | ||
385 | return 0; | ||
386 | if (xa_is_err(curr)) | ||
387 | return xa_err(curr); | ||
388 | return -EEXIST; | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * xa_release() - Release a reserved entry. | ||
393 | * @xa: XArray. | ||
394 | * @index: Index of entry. | ||
395 | * | ||
396 | * After calling xa_reserve(), you can call this function to release the | ||
397 | * reservation. If the entry at @index has been stored to, this function | ||
398 | * will do nothing. | ||
399 | */ | ||
400 | static inline void xa_release(struct xarray *xa, unsigned long index) | ||
401 | { | ||
402 | xa_cmpxchg(xa, index, NULL, NULL, 0); | ||
403 | } | ||
404 | |||
405 | /** | ||
406 | * xa_for_each() - Iterate over a portion of an XArray. | 345 | * xa_for_each() - Iterate over a portion of an XArray. |
407 | * @xa: XArray. | 346 | * @xa: XArray. |
408 | * @entry: Entry retrieved from array. | 347 | * @entry: Entry retrieved from array. |
@@ -455,6 +394,7 @@ void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | |||
455 | void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, | 394 | void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, |
456 | void *entry, gfp_t); | 395 | void *entry, gfp_t); |
457 | int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); | 396 | int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); |
397 | int __xa_reserve(struct xarray *, unsigned long index, gfp_t); | ||
458 | void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); | 398 | void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); |
459 | void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); | 399 | void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); |
460 | 400 | ||
@@ -487,6 +427,58 @@ static inline int __xa_insert(struct xarray *xa, unsigned long index, | |||
487 | } | 427 | } |
488 | 428 | ||
489 | /** | 429 | /** |
430 | * xa_store_bh() - Store this entry in the XArray. | ||
431 | * @xa: XArray. | ||
432 | * @index: Index into array. | ||
433 | * @entry: New entry. | ||
434 | * @gfp: Memory allocation flags. | ||
435 | * | ||
436 | * This function is like calling xa_store() except it disables softirqs | ||
437 | * while holding the array lock. | ||
438 | * | ||
439 | * Context: Any context. Takes and releases the xa_lock while | ||
440 | * disabling softirqs. | ||
441 | * Return: The entry which used to be at this index. | ||
442 | */ | ||
443 | static inline void *xa_store_bh(struct xarray *xa, unsigned long index, | ||
444 | void *entry, gfp_t gfp) | ||
445 | { | ||
446 | void *curr; | ||
447 | |||
448 | xa_lock_bh(xa); | ||
449 | curr = __xa_store(xa, index, entry, gfp); | ||
450 | xa_unlock_bh(xa); | ||
451 | |||
452 | return curr; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * xa_store_irq() - Erase this entry from the XArray. | ||
457 | * @xa: XArray. | ||
458 | * @index: Index into array. | ||
459 | * @entry: New entry. | ||
460 | * @gfp: Memory allocation flags. | ||
461 | * | ||
462 | * This function is like calling xa_store() except it disables interrupts | ||
463 | * while holding the array lock. | ||
464 | * | ||
465 | * Context: Process context. Takes and releases the xa_lock while | ||
466 | * disabling interrupts. | ||
467 | * Return: The entry which used to be at this index. | ||
468 | */ | ||
469 | static inline void *xa_store_irq(struct xarray *xa, unsigned long index, | ||
470 | void *entry, gfp_t gfp) | ||
471 | { | ||
472 | void *curr; | ||
473 | |||
474 | xa_lock_irq(xa); | ||
475 | curr = __xa_store(xa, index, entry, gfp); | ||
476 | xa_unlock_irq(xa); | ||
477 | |||
478 | return curr; | ||
479 | } | ||
480 | |||
481 | /** | ||
490 | * xa_erase_bh() - Erase this entry from the XArray. | 482 | * xa_erase_bh() - Erase this entry from the XArray. |
491 | * @xa: XArray. | 483 | * @xa: XArray. |
492 | * @index: Index of entry. | 484 | * @index: Index of entry. |
@@ -495,7 +487,7 @@ static inline int __xa_insert(struct xarray *xa, unsigned long index, | |||
495 | * the third argument. The XArray does not need to allocate memory, so | 487 | * the third argument. The XArray does not need to allocate memory, so |
496 | * the user does not need to provide GFP flags. | 488 | * the user does not need to provide GFP flags. |
497 | * | 489 | * |
498 | * Context: Process context. Takes and releases the xa_lock while | 490 | * Context: Any context. Takes and releases the xa_lock while |
499 | * disabling softirqs. | 491 | * disabling softirqs. |
500 | * Return: The entry which used to be at this index. | 492 | * Return: The entry which used to be at this index. |
501 | */ | 493 | */ |
@@ -535,6 +527,61 @@ static inline void *xa_erase_irq(struct xarray *xa, unsigned long index) | |||
535 | } | 527 | } |
536 | 528 | ||
537 | /** | 529 | /** |
530 | * xa_cmpxchg() - Conditionally replace an entry in the XArray. | ||
531 | * @xa: XArray. | ||
532 | * @index: Index into array. | ||
533 | * @old: Old value to test against. | ||
534 | * @entry: New value to place in array. | ||
535 | * @gfp: Memory allocation flags. | ||
536 | * | ||
537 | * If the entry at @index is the same as @old, replace it with @entry. | ||
538 | * If the return value is equal to @old, then the exchange was successful. | ||
539 | * | ||
540 | * Context: Any context. Takes and releases the xa_lock. May sleep | ||
541 | * if the @gfp flags permit. | ||
542 | * Return: The old value at this index or xa_err() if an error happened. | ||
543 | */ | ||
544 | static inline void *xa_cmpxchg(struct xarray *xa, unsigned long index, | ||
545 | void *old, void *entry, gfp_t gfp) | ||
546 | { | ||
547 | void *curr; | ||
548 | |||
549 | xa_lock(xa); | ||
550 | curr = __xa_cmpxchg(xa, index, old, entry, gfp); | ||
551 | xa_unlock(xa); | ||
552 | |||
553 | return curr; | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * xa_insert() - Store this entry in the XArray unless another entry is | ||
558 | * already present. | ||
559 | * @xa: XArray. | ||
560 | * @index: Index into array. | ||
561 | * @entry: New entry. | ||
562 | * @gfp: Memory allocation flags. | ||
563 | * | ||
564 | * If you would rather see the existing entry in the array, use xa_cmpxchg(). | ||
565 | * This function is for users who don't care what the entry is, only that | ||
566 | * one is present. | ||
567 | * | ||
568 | * Context: Process context. Takes and releases the xa_lock. | ||
569 | * May sleep if the @gfp flags permit. | ||
570 | * Return: 0 if the store succeeded. -EEXIST if another entry was present. | ||
571 | * -ENOMEM if memory could not be allocated. | ||
572 | */ | ||
573 | static inline int xa_insert(struct xarray *xa, unsigned long index, | ||
574 | void *entry, gfp_t gfp) | ||
575 | { | ||
576 | void *curr = xa_cmpxchg(xa, index, NULL, entry, gfp); | ||
577 | if (!curr) | ||
578 | return 0; | ||
579 | if (xa_is_err(curr)) | ||
580 | return xa_err(curr); | ||
581 | return -EEXIST; | ||
582 | } | ||
583 | |||
584 | /** | ||
538 | * xa_alloc() - Find somewhere to store this entry in the XArray. | 585 | * xa_alloc() - Find somewhere to store this entry in the XArray. |
539 | * @xa: XArray. | 586 | * @xa: XArray. |
540 | * @id: Pointer to ID. | 587 | * @id: Pointer to ID. |
@@ -575,7 +622,7 @@ static inline int xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, | |||
575 | * Updates the @id pointer with the index, then stores the entry at that | 622 | * Updates the @id pointer with the index, then stores the entry at that |
576 | * index. A concurrent lookup will not see an uninitialised @id. | 623 | * index. A concurrent lookup will not see an uninitialised @id. |
577 | * | 624 | * |
578 | * Context: Process context. Takes and releases the xa_lock while | 625 | * Context: Any context. Takes and releases the xa_lock while |
579 | * disabling softirqs. May sleep if the @gfp flags permit. | 626 | * disabling softirqs. May sleep if the @gfp flags permit. |
580 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if | 627 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if |
581 | * there is no more space in the XArray. | 628 | * there is no more space in the XArray. |
@@ -621,6 +668,98 @@ static inline int xa_alloc_irq(struct xarray *xa, u32 *id, u32 max, void *entry, | |||
621 | return err; | 668 | return err; |
622 | } | 669 | } |
623 | 670 | ||
671 | /** | ||
672 | * xa_reserve() - Reserve this index in the XArray. | ||
673 | * @xa: XArray. | ||
674 | * @index: Index into array. | ||
675 | * @gfp: Memory allocation flags. | ||
676 | * | ||
677 | * Ensures there is somewhere to store an entry at @index in the array. | ||
678 | * If there is already something stored at @index, this function does | ||
679 | * nothing. If there was nothing there, the entry is marked as reserved. | ||
680 | * Loading from a reserved entry returns a %NULL pointer. | ||
681 | * | ||
682 | * If you do not use the entry that you have reserved, call xa_release() | ||
683 | * or xa_erase() to free any unnecessary memory. | ||
684 | * | ||
685 | * Context: Any context. Takes and releases the xa_lock. | ||
686 | * May sleep if the @gfp flags permit. | ||
687 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | ||
688 | */ | ||
689 | static inline | ||
690 | int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) | ||
691 | { | ||
692 | int ret; | ||
693 | |||
694 | xa_lock(xa); | ||
695 | ret = __xa_reserve(xa, index, gfp); | ||
696 | xa_unlock(xa); | ||
697 | |||
698 | return ret; | ||
699 | } | ||
700 | |||
701 | /** | ||
702 | * xa_reserve_bh() - Reserve this index in the XArray. | ||
703 | * @xa: XArray. | ||
704 | * @index: Index into array. | ||
705 | * @gfp: Memory allocation flags. | ||
706 | * | ||
707 | * A softirq-disabling version of xa_reserve(). | ||
708 | * | ||
709 | * Context: Any context. Takes and releases the xa_lock while | ||
710 | * disabling softirqs. | ||
711 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | ||
712 | */ | ||
713 | static inline | ||
714 | int xa_reserve_bh(struct xarray *xa, unsigned long index, gfp_t gfp) | ||
715 | { | ||
716 | int ret; | ||
717 | |||
718 | xa_lock_bh(xa); | ||
719 | ret = __xa_reserve(xa, index, gfp); | ||
720 | xa_unlock_bh(xa); | ||
721 | |||
722 | return ret; | ||
723 | } | ||
724 | |||
725 | /** | ||
726 | * xa_reserve_irq() - Reserve this index in the XArray. | ||
727 | * @xa: XArray. | ||
728 | * @index: Index into array. | ||
729 | * @gfp: Memory allocation flags. | ||
730 | * | ||
731 | * An interrupt-disabling version of xa_reserve(). | ||
732 | * | ||
733 | * Context: Process context. Takes and releases the xa_lock while | ||
734 | * disabling interrupts. | ||
735 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | ||
736 | */ | ||
737 | static inline | ||
738 | int xa_reserve_irq(struct xarray *xa, unsigned long index, gfp_t gfp) | ||
739 | { | ||
740 | int ret; | ||
741 | |||
742 | xa_lock_irq(xa); | ||
743 | ret = __xa_reserve(xa, index, gfp); | ||
744 | xa_unlock_irq(xa); | ||
745 | |||
746 | return ret; | ||
747 | } | ||
748 | |||
749 | /** | ||
750 | * xa_release() - Release a reserved entry. | ||
751 | * @xa: XArray. | ||
752 | * @index: Index of entry. | ||
753 | * | ||
754 | * After calling xa_reserve(), you can call this function to release the | ||
755 | * reservation. If the entry at @index has been stored to, this function | ||
756 | * will do nothing. | ||
757 | */ | ||
758 | static inline void xa_release(struct xarray *xa, unsigned long index) | ||
759 | { | ||
760 | xa_cmpxchg(xa, index, NULL, NULL, 0); | ||
761 | } | ||
762 | |||
624 | /* Everything below here is the Advanced API. Proceed with caution. */ | 763 | /* Everything below here is the Advanced API. Proceed with caution. */ |
625 | 764 | ||
626 | /* | 765 | /* |
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 58c1ecf3d648..5467264771ec 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h | |||
@@ -624,7 +624,7 @@ v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx) | |||
624 | 624 | ||
625 | /* v4l2 request helper */ | 625 | /* v4l2 request helper */ |
626 | 626 | ||
627 | void vb2_m2m_request_queue(struct media_request *req); | 627 | void v4l2_m2m_request_queue(struct media_request *req); |
628 | 628 | ||
629 | /* v4l2 ioctl helpers */ | 629 | /* v4l2 ioctl helpers */ |
630 | 630 | ||
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h index de587948042a..1adefe42c0a6 100644 --- a/include/net/af_rxrpc.h +++ b/include/net/af_rxrpc.h | |||
@@ -77,7 +77,8 @@ int rxrpc_kernel_retry_call(struct socket *, struct rxrpc_call *, | |||
77 | struct sockaddr_rxrpc *, struct key *); | 77 | struct sockaddr_rxrpc *, struct key *); |
78 | int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *, | 78 | int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *, |
79 | enum rxrpc_call_completion *, u32 *); | 79 | enum rxrpc_call_completion *, u32 *); |
80 | u32 rxrpc_kernel_check_life(struct socket *, struct rxrpc_call *); | 80 | u32 rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *); |
81 | void rxrpc_kernel_probe_life(struct socket *, struct rxrpc_call *); | ||
81 | u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); | 82 | u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); |
82 | bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, | 83 | bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, |
83 | ktime_t *); | 84 | ktime_t *); |
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 8c2caa370e0f..ab9242e51d9e 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
@@ -608,4 +608,16 @@ static inline __u32 sctp_dst_mtu(const struct dst_entry *dst) | |||
608 | SCTP_DEFAULT_MINSEGMENT)); | 608 | SCTP_DEFAULT_MINSEGMENT)); |
609 | } | 609 | } |
610 | 610 | ||
611 | static inline bool sctp_transport_pmtu_check(struct sctp_transport *t) | ||
612 | { | ||
613 | __u32 pmtu = sctp_dst_mtu(t->dst); | ||
614 | |||
615 | if (t->pathmtu == pmtu) | ||
616 | return true; | ||
617 | |||
618 | t->pathmtu = pmtu; | ||
619 | |||
620 | return false; | ||
621 | } | ||
622 | |||
611 | #endif /* __net_sctp_h__ */ | 623 | #endif /* __net_sctp_h__ */ |
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 573d5b901fb1..5b50fe4906d2 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h | |||
@@ -181,6 +181,7 @@ enum rxrpc_timer_trace { | |||
181 | enum rxrpc_propose_ack_trace { | 181 | enum rxrpc_propose_ack_trace { |
182 | rxrpc_propose_ack_client_tx_end, | 182 | rxrpc_propose_ack_client_tx_end, |
183 | rxrpc_propose_ack_input_data, | 183 | rxrpc_propose_ack_input_data, |
184 | rxrpc_propose_ack_ping_for_check_life, | ||
184 | rxrpc_propose_ack_ping_for_keepalive, | 185 | rxrpc_propose_ack_ping_for_keepalive, |
185 | rxrpc_propose_ack_ping_for_lost_ack, | 186 | rxrpc_propose_ack_ping_for_lost_ack, |
186 | rxrpc_propose_ack_ping_for_lost_reply, | 187 | rxrpc_propose_ack_ping_for_lost_reply, |
@@ -380,6 +381,7 @@ enum rxrpc_tx_point { | |||
380 | #define rxrpc_propose_ack_traces \ | 381 | #define rxrpc_propose_ack_traces \ |
381 | EM(rxrpc_propose_ack_client_tx_end, "ClTxEnd") \ | 382 | EM(rxrpc_propose_ack_client_tx_end, "ClTxEnd") \ |
382 | EM(rxrpc_propose_ack_input_data, "DataIn ") \ | 383 | EM(rxrpc_propose_ack_input_data, "DataIn ") \ |
384 | EM(rxrpc_propose_ack_ping_for_check_life, "ChkLife") \ | ||
383 | EM(rxrpc_propose_ack_ping_for_keepalive, "KeepAlv") \ | 385 | EM(rxrpc_propose_ack_ping_for_keepalive, "KeepAlv") \ |
384 | EM(rxrpc_propose_ack_ping_for_lost_ack, "LostAck") \ | 386 | EM(rxrpc_propose_ack_ping_for_lost_ack, "LostAck") \ |
385 | EM(rxrpc_propose_ack_ping_for_lost_reply, "LostRpl") \ | 387 | EM(rxrpc_propose_ack_ping_for_lost_reply, "LostRpl") \ |
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 6d180cc60a5d..3eb5a4c3d60a 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h | |||
@@ -716,7 +716,6 @@ | |||
716 | * the situation described above. | 716 | * the situation described above. |
717 | */ | 717 | */ |
718 | #define REL_RESERVED 0x0a | 718 | #define REL_RESERVED 0x0a |
719 | #define REL_WHEEL_HI_RES 0x0b | ||
720 | #define REL_MAX 0x0f | 719 | #define REL_MAX 0x0f |
721 | #define REL_CNT (REL_MAX+1) | 720 | #define REL_CNT (REL_MAX+1) |
722 | 721 | ||
@@ -753,15 +752,6 @@ | |||
753 | 752 | ||
754 | #define ABS_MISC 0x28 | 753 | #define ABS_MISC 0x28 |
755 | 754 | ||
756 | /* | ||
757 | * 0x2e is reserved and should not be used in input drivers. | ||
758 | * It was used by HID as ABS_MISC+6 and userspace needs to detect if | ||
759 | * the next ABS_* event is correct or is just ABS_MISC + n. | ||
760 | * We define here ABS_RESERVED so userspace can rely on it and detect | ||
761 | * the situation described above. | ||
762 | */ | ||
763 | #define ABS_RESERVED 0x2e | ||
764 | |||
765 | #define ABS_MT_SLOT 0x2f /* MT slot being modified */ | 755 | #define ABS_MT_SLOT 0x2f /* MT slot being modified */ |
766 | #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ | 756 | #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ |
767 | #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ | 757 | #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ |
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 51b095898f4b..998983a6e6b7 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h | |||
@@ -50,6 +50,8 @@ | |||
50 | #ifndef __LINUX_V4L2_CONTROLS_H | 50 | #ifndef __LINUX_V4L2_CONTROLS_H |
51 | #define __LINUX_V4L2_CONTROLS_H | 51 | #define __LINUX_V4L2_CONTROLS_H |
52 | 52 | ||
53 | #include <linux/types.h> | ||
54 | |||
53 | /* Control classes */ | 55 | /* Control classes */ |
54 | #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ | 56 | #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ |
55 | #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ | 57 | #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ |
@@ -1110,6 +1112,7 @@ struct v4l2_mpeg2_sequence { | |||
1110 | __u8 profile_and_level_indication; | 1112 | __u8 profile_and_level_indication; |
1111 | __u8 progressive_sequence; | 1113 | __u8 progressive_sequence; |
1112 | __u8 chroma_format; | 1114 | __u8 chroma_format; |
1115 | __u8 pad; | ||
1113 | }; | 1116 | }; |
1114 | 1117 | ||
1115 | struct v4l2_mpeg2_picture { | 1118 | struct v4l2_mpeg2_picture { |
@@ -1128,6 +1131,7 @@ struct v4l2_mpeg2_picture { | |||
1128 | __u8 alternate_scan; | 1131 | __u8 alternate_scan; |
1129 | __u8 repeat_first_field; | 1132 | __u8 repeat_first_field; |
1130 | __u8 progressive_frame; | 1133 | __u8 progressive_frame; |
1134 | __u8 pad; | ||
1131 | }; | 1135 | }; |
1132 | 1136 | ||
1133 | struct v4l2_ctrl_mpeg2_slice_params { | 1137 | struct v4l2_ctrl_mpeg2_slice_params { |
@@ -1142,6 +1146,7 @@ struct v4l2_ctrl_mpeg2_slice_params { | |||
1142 | 1146 | ||
1143 | __u8 backward_ref_index; | 1147 | __u8 backward_ref_index; |
1144 | __u8 forward_ref_index; | 1148 | __u8 forward_ref_index; |
1149 | __u8 pad; | ||
1145 | }; | 1150 | }; |
1146 | 1151 | ||
1147 | struct v4l2_ctrl_mpeg2_quantization { | 1152 | struct v4l2_ctrl_mpeg2_quantization { |
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 5731daa09a32..045930e32c0e 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c | |||
@@ -679,7 +679,8 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, | |||
679 | } | 679 | } |
680 | 680 | ||
681 | if (!dev_is_dma_coherent(dev) && | 681 | if (!dev_is_dma_coherent(dev) && |
682 | (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) | 682 | (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0 && |
683 | dev_addr != DIRECT_MAPPING_ERROR) | ||
683 | arch_sync_dma_for_device(dev, phys, size, dir); | 684 | arch_sync_dma_for_device(dev, phys, size, dir); |
684 | 685 | ||
685 | return dev_addr; | 686 | return dev_addr; |
diff --git a/lib/test_firmware.c b/lib/test_firmware.c index b984806d7d7b..7cab9a9869ac 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c | |||
@@ -837,6 +837,7 @@ static ssize_t read_firmware_show(struct device *dev, | |||
837 | if (req->fw->size > PAGE_SIZE) { | 837 | if (req->fw->size > PAGE_SIZE) { |
838 | pr_err("Testing interface must use PAGE_SIZE firmware for now\n"); | 838 | pr_err("Testing interface must use PAGE_SIZE firmware for now\n"); |
839 | rc = -EINVAL; | 839 | rc = -EINVAL; |
840 | goto out; | ||
840 | } | 841 | } |
841 | memcpy(buf, req->fw->data, req->fw->size); | 842 | memcpy(buf, req->fw->data, req->fw->size); |
842 | 843 | ||
diff --git a/lib/test_xarray.c b/lib/test_xarray.c index aa47754150ce..0598e86af8fc 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c | |||
@@ -208,15 +208,19 @@ static noinline void check_xa_mark_1(struct xarray *xa, unsigned long index) | |||
208 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_2)); | 208 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_2)); |
209 | 209 | ||
210 | /* We should see two elements in the array */ | 210 | /* We should see two elements in the array */ |
211 | rcu_read_lock(); | ||
211 | xas_for_each(&xas, entry, ULONG_MAX) | 212 | xas_for_each(&xas, entry, ULONG_MAX) |
212 | seen++; | 213 | seen++; |
214 | rcu_read_unlock(); | ||
213 | XA_BUG_ON(xa, seen != 2); | 215 | XA_BUG_ON(xa, seen != 2); |
214 | 216 | ||
215 | /* One of which is marked */ | 217 | /* One of which is marked */ |
216 | xas_set(&xas, 0); | 218 | xas_set(&xas, 0); |
217 | seen = 0; | 219 | seen = 0; |
220 | rcu_read_lock(); | ||
218 | xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) | 221 | xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) |
219 | seen++; | 222 | seen++; |
223 | rcu_read_unlock(); | ||
220 | XA_BUG_ON(xa, seen != 1); | 224 | XA_BUG_ON(xa, seen != 1); |
221 | } | 225 | } |
222 | XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_0)); | 226 | XA_BUG_ON(xa, xa_get_mark(xa, next, XA_MARK_0)); |
@@ -373,6 +377,12 @@ static noinline void check_reserve(struct xarray *xa) | |||
373 | xa_erase_index(xa, 12345678); | 377 | xa_erase_index(xa, 12345678); |
374 | XA_BUG_ON(xa, !xa_empty(xa)); | 378 | XA_BUG_ON(xa, !xa_empty(xa)); |
375 | 379 | ||
380 | /* And so does xa_insert */ | ||
381 | xa_reserve(xa, 12345678, GFP_KERNEL); | ||
382 | XA_BUG_ON(xa, xa_insert(xa, 12345678, xa_mk_value(12345678), 0) != 0); | ||
383 | xa_erase_index(xa, 12345678); | ||
384 | XA_BUG_ON(xa, !xa_empty(xa)); | ||
385 | |||
376 | /* Can iterate through a reserved entry */ | 386 | /* Can iterate through a reserved entry */ |
377 | xa_store_index(xa, 5, GFP_KERNEL); | 387 | xa_store_index(xa, 5, GFP_KERNEL); |
378 | xa_reserve(xa, 6, GFP_KERNEL); | 388 | xa_reserve(xa, 6, GFP_KERNEL); |
@@ -436,7 +446,9 @@ static noinline void check_multi_store_1(struct xarray *xa, unsigned long index, | |||
436 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); | 446 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); |
437 | XA_BUG_ON(xa, xa_load(xa, min - 1) != NULL); | 447 | XA_BUG_ON(xa, xa_load(xa, min - 1) != NULL); |
438 | 448 | ||
449 | xas_lock(&xas); | ||
439 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(min)) != xa_mk_value(index)); | 450 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(min)) != xa_mk_value(index)); |
451 | xas_unlock(&xas); | ||
440 | XA_BUG_ON(xa, xa_load(xa, min) != xa_mk_value(min)); | 452 | XA_BUG_ON(xa, xa_load(xa, min) != xa_mk_value(min)); |
441 | XA_BUG_ON(xa, xa_load(xa, max - 1) != xa_mk_value(min)); | 453 | XA_BUG_ON(xa, xa_load(xa, max - 1) != xa_mk_value(min)); |
442 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); | 454 | XA_BUG_ON(xa, xa_load(xa, max) != NULL); |
@@ -452,9 +464,11 @@ static noinline void check_multi_store_2(struct xarray *xa, unsigned long index, | |||
452 | XA_STATE(xas, xa, index); | 464 | XA_STATE(xas, xa, index); |
453 | xa_store_order(xa, index, order, xa_mk_value(0), GFP_KERNEL); | 465 | xa_store_order(xa, index, order, xa_mk_value(0), GFP_KERNEL); |
454 | 466 | ||
467 | xas_lock(&xas); | ||
455 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(1)) != xa_mk_value(0)); | 468 | XA_BUG_ON(xa, xas_store(&xas, xa_mk_value(1)) != xa_mk_value(0)); |
456 | XA_BUG_ON(xa, xas.xa_index != index); | 469 | XA_BUG_ON(xa, xas.xa_index != index); |
457 | XA_BUG_ON(xa, xas_store(&xas, NULL) != xa_mk_value(1)); | 470 | XA_BUG_ON(xa, xas_store(&xas, NULL) != xa_mk_value(1)); |
471 | xas_unlock(&xas); | ||
458 | XA_BUG_ON(xa, !xa_empty(xa)); | 472 | XA_BUG_ON(xa, !xa_empty(xa)); |
459 | } | 473 | } |
460 | #endif | 474 | #endif |
@@ -498,7 +512,7 @@ static noinline void check_multi_store(struct xarray *xa) | |||
498 | rcu_read_unlock(); | 512 | rcu_read_unlock(); |
499 | 513 | ||
500 | /* We can erase multiple values with a single store */ | 514 | /* We can erase multiple values with a single store */ |
501 | xa_store_order(xa, 0, 63, NULL, GFP_KERNEL); | 515 | xa_store_order(xa, 0, BITS_PER_LONG - 1, NULL, GFP_KERNEL); |
502 | XA_BUG_ON(xa, !xa_empty(xa)); | 516 | XA_BUG_ON(xa, !xa_empty(xa)); |
503 | 517 | ||
504 | /* Even when the first slot is empty but the others aren't */ | 518 | /* Even when the first slot is empty but the others aren't */ |
@@ -702,7 +716,7 @@ static noinline void check_multi_find_2(struct xarray *xa) | |||
702 | } | 716 | } |
703 | } | 717 | } |
704 | 718 | ||
705 | static noinline void check_find(struct xarray *xa) | 719 | static noinline void check_find_1(struct xarray *xa) |
706 | { | 720 | { |
707 | unsigned long i, j, k; | 721 | unsigned long i, j, k; |
708 | 722 | ||
@@ -748,6 +762,34 @@ static noinline void check_find(struct xarray *xa) | |||
748 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_0)); | 762 | XA_BUG_ON(xa, xa_get_mark(xa, i, XA_MARK_0)); |
749 | } | 763 | } |
750 | XA_BUG_ON(xa, !xa_empty(xa)); | 764 | XA_BUG_ON(xa, !xa_empty(xa)); |
765 | } | ||
766 | |||
767 | static noinline void check_find_2(struct xarray *xa) | ||
768 | { | ||
769 | void *entry; | ||
770 | unsigned long i, j, index = 0; | ||
771 | |||
772 | xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { | ||
773 | XA_BUG_ON(xa, true); | ||
774 | } | ||
775 | |||
776 | for (i = 0; i < 1024; i++) { | ||
777 | xa_store_index(xa, index, GFP_KERNEL); | ||
778 | j = 0; | ||
779 | index = 0; | ||
780 | xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { | ||
781 | XA_BUG_ON(xa, xa_mk_value(index) != entry); | ||
782 | XA_BUG_ON(xa, index != j++); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | xa_destroy(xa); | ||
787 | } | ||
788 | |||
789 | static noinline void check_find(struct xarray *xa) | ||
790 | { | ||
791 | check_find_1(xa); | ||
792 | check_find_2(xa); | ||
751 | check_multi_find(xa); | 793 | check_multi_find(xa); |
752 | check_multi_find_2(xa); | 794 | check_multi_find_2(xa); |
753 | } | 795 | } |
@@ -1067,7 +1109,7 @@ static noinline void check_store_range(struct xarray *xa) | |||
1067 | __check_store_range(xa, 4095 + i, 4095 + j); | 1109 | __check_store_range(xa, 4095 + i, 4095 + j); |
1068 | __check_store_range(xa, 4096 + i, 4096 + j); | 1110 | __check_store_range(xa, 4096 + i, 4096 + j); |
1069 | __check_store_range(xa, 123456 + i, 123456 + j); | 1111 | __check_store_range(xa, 123456 + i, 123456 + j); |
1070 | __check_store_range(xa, UINT_MAX + i, UINT_MAX + j); | 1112 | __check_store_range(xa, (1 << 24) + i, (1 << 24) + j); |
1071 | } | 1113 | } |
1072 | } | 1114 | } |
1073 | } | 1115 | } |
@@ -1146,10 +1188,12 @@ static noinline void check_account(struct xarray *xa) | |||
1146 | XA_STATE(xas, xa, 1 << order); | 1188 | XA_STATE(xas, xa, 1 << order); |
1147 | 1189 | ||
1148 | xa_store_order(xa, 0, order, xa, GFP_KERNEL); | 1190 | xa_store_order(xa, 0, order, xa, GFP_KERNEL); |
1191 | rcu_read_lock(); | ||
1149 | xas_load(&xas); | 1192 | xas_load(&xas); |
1150 | XA_BUG_ON(xa, xas.xa_node->count == 0); | 1193 | XA_BUG_ON(xa, xas.xa_node->count == 0); |
1151 | XA_BUG_ON(xa, xas.xa_node->count > (1 << order)); | 1194 | XA_BUG_ON(xa, xas.xa_node->count > (1 << order)); |
1152 | XA_BUG_ON(xa, xas.xa_node->nr_values != 0); | 1195 | XA_BUG_ON(xa, xas.xa_node->nr_values != 0); |
1196 | rcu_read_unlock(); | ||
1153 | 1197 | ||
1154 | xa_store_order(xa, 1 << order, order, xa_mk_value(1 << order), | 1198 | xa_store_order(xa, 1 << order, order, xa_mk_value(1 << order), |
1155 | GFP_KERNEL); | 1199 | GFP_KERNEL); |
diff --git a/lib/xarray.c b/lib/xarray.c index 8b176f009c08..bbacca576593 100644 --- a/lib/xarray.c +++ b/lib/xarray.c | |||
@@ -610,8 +610,8 @@ static int xas_expand(struct xa_state *xas, void *head) | |||
610 | * (see the xa_cmpxchg() implementation for an example). | 610 | * (see the xa_cmpxchg() implementation for an example). |
611 | * | 611 | * |
612 | * Return: If the slot already existed, returns the contents of this slot. | 612 | * Return: If the slot already existed, returns the contents of this slot. |
613 | * If the slot was newly created, returns NULL. If it failed to create the | 613 | * If the slot was newly created, returns %NULL. If it failed to create the |
614 | * slot, returns NULL and indicates the error in @xas. | 614 | * slot, returns %NULL and indicates the error in @xas. |
615 | */ | 615 | */ |
616 | static void *xas_create(struct xa_state *xas) | 616 | static void *xas_create(struct xa_state *xas) |
617 | { | 617 | { |
@@ -1334,44 +1334,31 @@ void *__xa_erase(struct xarray *xa, unsigned long index) | |||
1334 | XA_STATE(xas, xa, index); | 1334 | XA_STATE(xas, xa, index); |
1335 | return xas_result(&xas, xas_store(&xas, NULL)); | 1335 | return xas_result(&xas, xas_store(&xas, NULL)); |
1336 | } | 1336 | } |
1337 | EXPORT_SYMBOL_GPL(__xa_erase); | 1337 | EXPORT_SYMBOL(__xa_erase); |
1338 | 1338 | ||
1339 | /** | 1339 | /** |
1340 | * xa_store() - Store this entry in the XArray. | 1340 | * xa_erase() - Erase this entry from the XArray. |
1341 | * @xa: XArray. | 1341 | * @xa: XArray. |
1342 | * @index: Index into array. | 1342 | * @index: Index of entry. |
1343 | * @entry: New entry. | ||
1344 | * @gfp: Memory allocation flags. | ||
1345 | * | 1343 | * |
1346 | * After this function returns, loads from this index will return @entry. | 1344 | * This function is the equivalent of calling xa_store() with %NULL as |
1347 | * Storing into an existing multislot entry updates the entry of every index. | 1345 | * the third argument. The XArray does not need to allocate memory, so |
1348 | * The marks associated with @index are unaffected unless @entry is %NULL. | 1346 | * the user does not need to provide GFP flags. |
1349 | * | 1347 | * |
1350 | * Context: Process context. Takes and releases the xa_lock. May sleep | 1348 | * Context: Any context. Takes and releases the xa_lock. |
1351 | * if the @gfp flags permit. | 1349 | * Return: The entry which used to be at this index. |
1352 | * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry | ||
1353 | * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation | ||
1354 | * failed. | ||
1355 | */ | 1350 | */ |
1356 | void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) | 1351 | void *xa_erase(struct xarray *xa, unsigned long index) |
1357 | { | 1352 | { |
1358 | XA_STATE(xas, xa, index); | 1353 | void *entry; |
1359 | void *curr; | ||
1360 | |||
1361 | if (WARN_ON_ONCE(xa_is_internal(entry))) | ||
1362 | return XA_ERROR(-EINVAL); | ||
1363 | 1354 | ||
1364 | do { | 1355 | xa_lock(xa); |
1365 | xas_lock(&xas); | 1356 | entry = __xa_erase(xa, index); |
1366 | curr = xas_store(&xas, entry); | 1357 | xa_unlock(xa); |
1367 | if (xa_track_free(xa) && entry) | ||
1368 | xas_clear_mark(&xas, XA_FREE_MARK); | ||
1369 | xas_unlock(&xas); | ||
1370 | } while (xas_nomem(&xas, gfp)); | ||
1371 | 1358 | ||
1372 | return xas_result(&xas, curr); | 1359 | return entry; |
1373 | } | 1360 | } |
1374 | EXPORT_SYMBOL(xa_store); | 1361 | EXPORT_SYMBOL(xa_erase); |
1375 | 1362 | ||
1376 | /** | 1363 | /** |
1377 | * __xa_store() - Store this entry in the XArray. | 1364 | * __xa_store() - Store this entry in the XArray. |
@@ -1395,10 +1382,12 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) | |||
1395 | 1382 | ||
1396 | if (WARN_ON_ONCE(xa_is_internal(entry))) | 1383 | if (WARN_ON_ONCE(xa_is_internal(entry))) |
1397 | return XA_ERROR(-EINVAL); | 1384 | return XA_ERROR(-EINVAL); |
1385 | if (xa_track_free(xa) && !entry) | ||
1386 | entry = XA_ZERO_ENTRY; | ||
1398 | 1387 | ||
1399 | do { | 1388 | do { |
1400 | curr = xas_store(&xas, entry); | 1389 | curr = xas_store(&xas, entry); |
1401 | if (xa_track_free(xa) && entry) | 1390 | if (xa_track_free(xa)) |
1402 | xas_clear_mark(&xas, XA_FREE_MARK); | 1391 | xas_clear_mark(&xas, XA_FREE_MARK); |
1403 | } while (__xas_nomem(&xas, gfp)); | 1392 | } while (__xas_nomem(&xas, gfp)); |
1404 | 1393 | ||
@@ -1407,45 +1396,33 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) | |||
1407 | EXPORT_SYMBOL(__xa_store); | 1396 | EXPORT_SYMBOL(__xa_store); |
1408 | 1397 | ||
1409 | /** | 1398 | /** |
1410 | * xa_cmpxchg() - Conditionally replace an entry in the XArray. | 1399 | * xa_store() - Store this entry in the XArray. |
1411 | * @xa: XArray. | 1400 | * @xa: XArray. |
1412 | * @index: Index into array. | 1401 | * @index: Index into array. |
1413 | * @old: Old value to test against. | 1402 | * @entry: New entry. |
1414 | * @entry: New value to place in array. | ||
1415 | * @gfp: Memory allocation flags. | 1403 | * @gfp: Memory allocation flags. |
1416 | * | 1404 | * |
1417 | * If the entry at @index is the same as @old, replace it with @entry. | 1405 | * After this function returns, loads from this index will return @entry. |
1418 | * If the return value is equal to @old, then the exchange was successful. | 1406 | * Storing into an existing multislot entry updates the entry of every index. |
1407 | * The marks associated with @index are unaffected unless @entry is %NULL. | ||
1419 | * | 1408 | * |
1420 | * Context: Process context. Takes and releases the xa_lock. May sleep | 1409 | * Context: Any context. Takes and releases the xa_lock. |
1421 | * if the @gfp flags permit. | 1410 | * May sleep if the @gfp flags permit. |
1422 | * Return: The old value at this index or xa_err() if an error happened. | 1411 | * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry |
1412 | * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation | ||
1413 | * failed. | ||
1423 | */ | 1414 | */ |
1424 | void *xa_cmpxchg(struct xarray *xa, unsigned long index, | 1415 | void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) |
1425 | void *old, void *entry, gfp_t gfp) | ||
1426 | { | 1416 | { |
1427 | XA_STATE(xas, xa, index); | ||
1428 | void *curr; | 1417 | void *curr; |
1429 | 1418 | ||
1430 | if (WARN_ON_ONCE(xa_is_internal(entry))) | 1419 | xa_lock(xa); |
1431 | return XA_ERROR(-EINVAL); | 1420 | curr = __xa_store(xa, index, entry, gfp); |
1432 | 1421 | xa_unlock(xa); | |
1433 | do { | ||
1434 | xas_lock(&xas); | ||
1435 | curr = xas_load(&xas); | ||
1436 | if (curr == XA_ZERO_ENTRY) | ||
1437 | curr = NULL; | ||
1438 | if (curr == old) { | ||
1439 | xas_store(&xas, entry); | ||
1440 | if (xa_track_free(xa) && entry) | ||
1441 | xas_clear_mark(&xas, XA_FREE_MARK); | ||
1442 | } | ||
1443 | xas_unlock(&xas); | ||
1444 | } while (xas_nomem(&xas, gfp)); | ||
1445 | 1422 | ||
1446 | return xas_result(&xas, curr); | 1423 | return curr; |
1447 | } | 1424 | } |
1448 | EXPORT_SYMBOL(xa_cmpxchg); | 1425 | EXPORT_SYMBOL(xa_store); |
1449 | 1426 | ||
1450 | /** | 1427 | /** |
1451 | * __xa_cmpxchg() - Store this entry in the XArray. | 1428 | * __xa_cmpxchg() - Store this entry in the XArray. |
@@ -1471,6 +1448,8 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, | |||
1471 | 1448 | ||
1472 | if (WARN_ON_ONCE(xa_is_internal(entry))) | 1449 | if (WARN_ON_ONCE(xa_is_internal(entry))) |
1473 | return XA_ERROR(-EINVAL); | 1450 | return XA_ERROR(-EINVAL); |
1451 | if (xa_track_free(xa) && !entry) | ||
1452 | entry = XA_ZERO_ENTRY; | ||
1474 | 1453 | ||
1475 | do { | 1454 | do { |
1476 | curr = xas_load(&xas); | 1455 | curr = xas_load(&xas); |
@@ -1478,7 +1457,7 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, | |||
1478 | curr = NULL; | 1457 | curr = NULL; |
1479 | if (curr == old) { | 1458 | if (curr == old) { |
1480 | xas_store(&xas, entry); | 1459 | xas_store(&xas, entry); |
1481 | if (xa_track_free(xa) && entry) | 1460 | if (xa_track_free(xa)) |
1482 | xas_clear_mark(&xas, XA_FREE_MARK); | 1461 | xas_clear_mark(&xas, XA_FREE_MARK); |
1483 | } | 1462 | } |
1484 | } while (__xas_nomem(&xas, gfp)); | 1463 | } while (__xas_nomem(&xas, gfp)); |
@@ -1488,7 +1467,7 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, | |||
1488 | EXPORT_SYMBOL(__xa_cmpxchg); | 1467 | EXPORT_SYMBOL(__xa_cmpxchg); |
1489 | 1468 | ||
1490 | /** | 1469 | /** |
1491 | * xa_reserve() - Reserve this index in the XArray. | 1470 | * __xa_reserve() - Reserve this index in the XArray. |
1492 | * @xa: XArray. | 1471 | * @xa: XArray. |
1493 | * @index: Index into array. | 1472 | * @index: Index into array. |
1494 | * @gfp: Memory allocation flags. | 1473 | * @gfp: Memory allocation flags. |
@@ -1496,33 +1475,32 @@ EXPORT_SYMBOL(__xa_cmpxchg); | |||
1496 | * Ensures there is somewhere to store an entry at @index in the array. | 1475 | * Ensures there is somewhere to store an entry at @index in the array. |
1497 | * If there is already something stored at @index, this function does | 1476 | * If there is already something stored at @index, this function does |
1498 | * nothing. If there was nothing there, the entry is marked as reserved. | 1477 | * nothing. If there was nothing there, the entry is marked as reserved. |
1499 | * Loads from @index will continue to see a %NULL pointer until a | 1478 | * Loading from a reserved entry returns a %NULL pointer. |
1500 | * subsequent store to @index. | ||
1501 | * | 1479 | * |
1502 | * If you do not use the entry that you have reserved, call xa_release() | 1480 | * If you do not use the entry that you have reserved, call xa_release() |
1503 | * or xa_erase() to free any unnecessary memory. | 1481 | * or xa_erase() to free any unnecessary memory. |
1504 | * | 1482 | * |
1505 | * Context: Process context. Takes and releases the xa_lock, IRQ or BH safe | 1483 | * Context: Any context. Expects the xa_lock to be held on entry. May |
1506 | * if specified in XArray flags. May sleep if the @gfp flags permit. | 1484 | * release the lock, sleep and reacquire the lock if the @gfp flags permit. |
1507 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. | 1485 | * Return: 0 if the reservation succeeded or -ENOMEM if it failed. |
1508 | */ | 1486 | */ |
1509 | int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) | 1487 | int __xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) |
1510 | { | 1488 | { |
1511 | XA_STATE(xas, xa, index); | 1489 | XA_STATE(xas, xa, index); |
1512 | unsigned int lock_type = xa_lock_type(xa); | ||
1513 | void *curr; | 1490 | void *curr; |
1514 | 1491 | ||
1515 | do { | 1492 | do { |
1516 | xas_lock_type(&xas, lock_type); | ||
1517 | curr = xas_load(&xas); | 1493 | curr = xas_load(&xas); |
1518 | if (!curr) | 1494 | if (!curr) { |
1519 | xas_store(&xas, XA_ZERO_ENTRY); | 1495 | xas_store(&xas, XA_ZERO_ENTRY); |
1520 | xas_unlock_type(&xas, lock_type); | 1496 | if (xa_track_free(xa)) |
1521 | } while (xas_nomem(&xas, gfp)); | 1497 | xas_clear_mark(&xas, XA_FREE_MARK); |
1498 | } | ||
1499 | } while (__xas_nomem(&xas, gfp)); | ||
1522 | 1500 | ||
1523 | return xas_error(&xas); | 1501 | return xas_error(&xas); |
1524 | } | 1502 | } |
1525 | EXPORT_SYMBOL(xa_reserve); | 1503 | EXPORT_SYMBOL(__xa_reserve); |
1526 | 1504 | ||
1527 | #ifdef CONFIG_XARRAY_MULTI | 1505 | #ifdef CONFIG_XARRAY_MULTI |
1528 | static void xas_set_range(struct xa_state *xas, unsigned long first, | 1506 | static void xas_set_range(struct xa_state *xas, unsigned long first, |
@@ -1587,8 +1565,9 @@ void *xa_store_range(struct xarray *xa, unsigned long first, | |||
1587 | do { | 1565 | do { |
1588 | xas_lock(&xas); | 1566 | xas_lock(&xas); |
1589 | if (entry) { | 1567 | if (entry) { |
1590 | unsigned int order = (last == ~0UL) ? 64 : | 1568 | unsigned int order = BITS_PER_LONG; |
1591 | ilog2(last + 1); | 1569 | if (last + 1) |
1570 | order = __ffs(last + 1); | ||
1592 | xas_set_order(&xas, last, order); | 1571 | xas_set_order(&xas, last, order); |
1593 | xas_create(&xas); | 1572 | xas_create(&xas); |
1594 | if (xas_error(&xas)) | 1573 | if (xas_error(&xas)) |
@@ -1662,7 +1641,7 @@ EXPORT_SYMBOL(__xa_alloc); | |||
1662 | * @index: Index of entry. | 1641 | * @index: Index of entry. |
1663 | * @mark: Mark number. | 1642 | * @mark: Mark number. |
1664 | * | 1643 | * |
1665 | * Attempting to set a mark on a NULL entry does not succeed. | 1644 | * Attempting to set a mark on a %NULL entry does not succeed. |
1666 | * | 1645 | * |
1667 | * Context: Any context. Expects xa_lock to be held on entry. | 1646 | * Context: Any context. Expects xa_lock to be held on entry. |
1668 | */ | 1647 | */ |
@@ -1674,7 +1653,7 @@ void __xa_set_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) | |||
1674 | if (entry) | 1653 | if (entry) |
1675 | xas_set_mark(&xas, mark); | 1654 | xas_set_mark(&xas, mark); |
1676 | } | 1655 | } |
1677 | EXPORT_SYMBOL_GPL(__xa_set_mark); | 1656 | EXPORT_SYMBOL(__xa_set_mark); |
1678 | 1657 | ||
1679 | /** | 1658 | /** |
1680 | * __xa_clear_mark() - Clear this mark on this entry while locked. | 1659 | * __xa_clear_mark() - Clear this mark on this entry while locked. |
@@ -1692,7 +1671,7 @@ void __xa_clear_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) | |||
1692 | if (entry) | 1671 | if (entry) |
1693 | xas_clear_mark(&xas, mark); | 1672 | xas_clear_mark(&xas, mark); |
1694 | } | 1673 | } |
1695 | EXPORT_SYMBOL_GPL(__xa_clear_mark); | 1674 | EXPORT_SYMBOL(__xa_clear_mark); |
1696 | 1675 | ||
1697 | /** | 1676 | /** |
1698 | * xa_get_mark() - Inquire whether this mark is set on this entry. | 1677 | * xa_get_mark() - Inquire whether this mark is set on this entry. |
@@ -1732,7 +1711,7 @@ EXPORT_SYMBOL(xa_get_mark); | |||
1732 | * @index: Index of entry. | 1711 | * @index: Index of entry. |
1733 | * @mark: Mark number. | 1712 | * @mark: Mark number. |
1734 | * | 1713 | * |
1735 | * Attempting to set a mark on a NULL entry does not succeed. | 1714 | * Attempting to set a mark on a %NULL entry does not succeed. |
1736 | * | 1715 | * |
1737 | * Context: Process context. Takes and releases the xa_lock. | 1716 | * Context: Process context. Takes and releases the xa_lock. |
1738 | */ | 1717 | */ |
@@ -1829,6 +1808,8 @@ void *xa_find_after(struct xarray *xa, unsigned long *indexp, | |||
1829 | entry = xas_find_marked(&xas, max, filter); | 1808 | entry = xas_find_marked(&xas, max, filter); |
1830 | else | 1809 | else |
1831 | entry = xas_find(&xas, max); | 1810 | entry = xas_find(&xas, max); |
1811 | if (xas.xa_node == XAS_BOUNDS) | ||
1812 | break; | ||
1832 | if (xas.xa_shift) { | 1813 | if (xas.xa_shift) { |
1833 | if (xas.xa_index & ((1UL << xas.xa_shift) - 1)) | 1814 | if (xas.xa_index & ((1UL << xas.xa_shift) - 1)) |
1834 | continue; | 1815 | continue; |
@@ -1899,7 +1880,7 @@ static unsigned int xas_extract_marked(struct xa_state *xas, void **dst, | |||
1899 | * | 1880 | * |
1900 | * The @filter may be an XArray mark value, in which case entries which are | 1881 | * The @filter may be an XArray mark value, in which case entries which are |
1901 | * marked with that mark will be copied. It may also be %XA_PRESENT, in | 1882 | * marked with that mark will be copied. It may also be %XA_PRESENT, in |
1902 | * which case all entries which are not NULL will be copied. | 1883 | * which case all entries which are not %NULL will be copied. |
1903 | * | 1884 | * |
1904 | * The entries returned may not represent a snapshot of the XArray at a | 1885 | * The entries returned may not represent a snapshot of the XArray at a |
1905 | * moment in time. For example, if another thread stores to index 5, then | 1886 | * moment in time. For example, if another thread stores to index 5, then |
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 9f481cfdf77d..e8090f099eb8 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c | |||
@@ -352,19 +352,21 @@ out: | |||
352 | */ | 352 | */ |
353 | int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) | 353 | int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) |
354 | { | 354 | { |
355 | static const size_t tvlv_padding = sizeof(__be32); | ||
355 | struct batadv_elp_packet *elp_packet; | 356 | struct batadv_elp_packet *elp_packet; |
356 | unsigned char *elp_buff; | 357 | unsigned char *elp_buff; |
357 | u32 random_seqno; | 358 | u32 random_seqno; |
358 | size_t size; | 359 | size_t size; |
359 | int res = -ENOMEM; | 360 | int res = -ENOMEM; |
360 | 361 | ||
361 | size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN; | 362 | size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN + tvlv_padding; |
362 | hard_iface->bat_v.elp_skb = dev_alloc_skb(size); | 363 | hard_iface->bat_v.elp_skb = dev_alloc_skb(size); |
363 | if (!hard_iface->bat_v.elp_skb) | 364 | if (!hard_iface->bat_v.elp_skb) |
364 | goto out; | 365 | goto out; |
365 | 366 | ||
366 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); | 367 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); |
367 | elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN); | 368 | elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb, |
369 | BATADV_ELP_HLEN + tvlv_padding); | ||
368 | elp_packet = (struct batadv_elp_packet *)elp_buff; | 370 | elp_packet = (struct batadv_elp_packet *)elp_buff; |
369 | 371 | ||
370 | elp_packet->packet_type = BATADV_ELP; | 372 | elp_packet->packet_type = BATADV_ELP; |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 0fddc17106bd..5b71a289d04f 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -275,7 +275,7 @@ batadv_frag_merge_packets(struct hlist_head *chain) | |||
275 | kfree(entry); | 275 | kfree(entry); |
276 | 276 | ||
277 | packet = (struct batadv_frag_packet *)skb_out->data; | 277 | packet = (struct batadv_frag_packet *)skb_out->data; |
278 | size = ntohs(packet->total_size); | 278 | size = ntohs(packet->total_size) + hdr_size; |
279 | 279 | ||
280 | /* Make room for the rest of the fragments. */ | 280 | /* Make room for the rest of the fragments. */ |
281 | if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { | 281 | if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 2920e06a5403..04c19a37e500 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -102,12 +102,18 @@ struct br_tunnel_info { | |||
102 | struct metadata_dst *tunnel_dst; | 102 | struct metadata_dst *tunnel_dst; |
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* private vlan flags */ | ||
106 | enum { | ||
107 | BR_VLFLAG_PER_PORT_STATS = BIT(0), | ||
108 | }; | ||
109 | |||
105 | /** | 110 | /** |
106 | * struct net_bridge_vlan - per-vlan entry | 111 | * struct net_bridge_vlan - per-vlan entry |
107 | * | 112 | * |
108 | * @vnode: rhashtable member | 113 | * @vnode: rhashtable member |
109 | * @vid: VLAN id | 114 | * @vid: VLAN id |
110 | * @flags: bridge vlan flags | 115 | * @flags: bridge vlan flags |
116 | * @priv_flags: private (in-kernel) bridge vlan flags | ||
111 | * @stats: per-cpu VLAN statistics | 117 | * @stats: per-cpu VLAN statistics |
112 | * @br: if MASTER flag set, this points to a bridge struct | 118 | * @br: if MASTER flag set, this points to a bridge struct |
113 | * @port: if MASTER flag unset, this points to a port struct | 119 | * @port: if MASTER flag unset, this points to a port struct |
@@ -127,6 +133,7 @@ struct net_bridge_vlan { | |||
127 | struct rhash_head tnode; | 133 | struct rhash_head tnode; |
128 | u16 vid; | 134 | u16 vid; |
129 | u16 flags; | 135 | u16 flags; |
136 | u16 priv_flags; | ||
130 | struct br_vlan_stats __percpu *stats; | 137 | struct br_vlan_stats __percpu *stats; |
131 | union { | 138 | union { |
132 | struct net_bridge *br; | 139 | struct net_bridge *br; |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 8c9297a01947..e84be08b8285 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -197,7 +197,7 @@ static void nbp_vlan_rcu_free(struct rcu_head *rcu) | |||
197 | v = container_of(rcu, struct net_bridge_vlan, rcu); | 197 | v = container_of(rcu, struct net_bridge_vlan, rcu); |
198 | WARN_ON(br_vlan_is_master(v)); | 198 | WARN_ON(br_vlan_is_master(v)); |
199 | /* if we had per-port stats configured then free them here */ | 199 | /* if we had per-port stats configured then free them here */ |
200 | if (v->brvlan->stats != v->stats) | 200 | if (v->priv_flags & BR_VLFLAG_PER_PORT_STATS) |
201 | free_percpu(v->stats); | 201 | free_percpu(v->stats); |
202 | v->stats = NULL; | 202 | v->stats = NULL; |
203 | kfree(v); | 203 | kfree(v); |
@@ -264,6 +264,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags) | |||
264 | err = -ENOMEM; | 264 | err = -ENOMEM; |
265 | goto out_filt; | 265 | goto out_filt; |
266 | } | 266 | } |
267 | v->priv_flags |= BR_VLFLAG_PER_PORT_STATS; | ||
267 | } else { | 268 | } else { |
268 | v->stats = masterv->stats; | 269 | v->stats = masterv->stats; |
269 | } | 270 | } |
diff --git a/net/can/raw.c b/net/can/raw.c index 1051eee82581..3aab7664933f 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -745,18 +745,19 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
745 | } else | 745 | } else |
746 | ifindex = ro->ifindex; | 746 | ifindex = ro->ifindex; |
747 | 747 | ||
748 | if (ro->fd_frames) { | 748 | dev = dev_get_by_index(sock_net(sk), ifindex); |
749 | if (!dev) | ||
750 | return -ENXIO; | ||
751 | |||
752 | err = -EINVAL; | ||
753 | if (ro->fd_frames && dev->mtu == CANFD_MTU) { | ||
749 | if (unlikely(size != CANFD_MTU && size != CAN_MTU)) | 754 | if (unlikely(size != CANFD_MTU && size != CAN_MTU)) |
750 | return -EINVAL; | 755 | goto put_dev; |
751 | } else { | 756 | } else { |
752 | if (unlikely(size != CAN_MTU)) | 757 | if (unlikely(size != CAN_MTU)) |
753 | return -EINVAL; | 758 | goto put_dev; |
754 | } | 759 | } |
755 | 760 | ||
756 | dev = dev_get_by_index(sock_net(sk), ifindex); | ||
757 | if (!dev) | ||
758 | return -ENXIO; | ||
759 | |||
760 | skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv), | 761 | skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv), |
761 | msg->msg_flags & MSG_DONTWAIT, &err); | 762 | msg->msg_flags & MSG_DONTWAIT, &err); |
762 | if (!skb) | 763 | if (!skb) |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 57fcc6b4bf6e..2f126eff275d 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -580,9 +580,15 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | |||
580 | struct bio_vec bvec; | 580 | struct bio_vec bvec; |
581 | int ret; | 581 | int ret; |
582 | 582 | ||
583 | /* sendpage cannot properly handle pages with page_count == 0, | 583 | /* |
584 | * we need to fallback to sendmsg if that's the case */ | 584 | * sendpage cannot properly handle pages with page_count == 0, |
585 | if (page_count(page) >= 1) | 585 | * we need to fall back to sendmsg if that's the case. |
586 | * | ||
587 | * Same goes for slab pages: skb_can_coalesce() allows | ||
588 | * coalescing neighboring slab objects into a single frag which | ||
589 | * triggers one of hardened usercopy checks. | ||
590 | */ | ||
591 | if (page_count(page) >= 1 && !PageSlab(page)) | ||
586 | return __ceph_tcp_sendpage(sock, page, offset, size, more); | 592 | return __ceph_tcp_sendpage(sock, page, offset, size, more); |
587 | 593 | ||
588 | bvec.bv_page = page; | 594 | bvec.bv_page = page; |
diff --git a/net/core/dev.c b/net/core/dev.c index 0ffcbdd55fa9..ddc551f24ba2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5655,6 +5655,10 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
5655 | skb->vlan_tci = 0; | 5655 | skb->vlan_tci = 0; |
5656 | skb->dev = napi->dev; | 5656 | skb->dev = napi->dev; |
5657 | skb->skb_iif = 0; | 5657 | skb->skb_iif = 0; |
5658 | |||
5659 | /* eth_type_trans() assumes pkt_type is PACKET_HOST */ | ||
5660 | skb->pkt_type = PACKET_HOST; | ||
5661 | |||
5658 | skb->encapsulation = 0; | 5662 | skb->encapsulation = 0; |
5659 | skb_shinfo(skb)->gso_type = 0; | 5663 | skb_shinfo(skb)->gso_type = 0; |
5660 | skb->truesize = SKB_TRUESIZE(skb_end_offset(skb)); | 5664 | skb->truesize = SKB_TRUESIZE(skb_end_offset(skb)); |
@@ -5966,11 +5970,14 @@ bool napi_complete_done(struct napi_struct *n, int work_done) | |||
5966 | if (work_done) | 5970 | if (work_done) |
5967 | timeout = n->dev->gro_flush_timeout; | 5971 | timeout = n->dev->gro_flush_timeout; |
5968 | 5972 | ||
5973 | /* When the NAPI instance uses a timeout and keeps postponing | ||
5974 | * it, we need to bound somehow the time packets are kept in | ||
5975 | * the GRO layer | ||
5976 | */ | ||
5977 | napi_gro_flush(n, !!timeout); | ||
5969 | if (timeout) | 5978 | if (timeout) |
5970 | hrtimer_start(&n->timer, ns_to_ktime(timeout), | 5979 | hrtimer_start(&n->timer, ns_to_ktime(timeout), |
5971 | HRTIMER_MODE_REL_PINNED); | 5980 | HRTIMER_MODE_REL_PINNED); |
5972 | else | ||
5973 | napi_gro_flush(n, false); | ||
5974 | } | 5981 | } |
5975 | if (unlikely(!list_empty(&n->poll_list))) { | 5982 | if (unlikely(!list_empty(&n->poll_list))) { |
5976 | /* If n->poll_list is not empty, we need to mask irqs */ | 5983 | /* If n->poll_list is not empty, we need to mask irqs */ |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index b4ee5c8b928f..a8217e221e19 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -4854,6 +4854,11 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
4854 | nf_reset(skb); | 4854 | nf_reset(skb); |
4855 | nf_reset_trace(skb); | 4855 | nf_reset_trace(skb); |
4856 | 4856 | ||
4857 | #ifdef CONFIG_NET_SWITCHDEV | ||
4858 | skb->offload_fwd_mark = 0; | ||
4859 | skb->offload_mr_fwd_mark = 0; | ||
4860 | #endif | ||
4861 | |||
4857 | if (!xnet) | 4862 | if (!xnet) |
4858 | return; | 4863 | return; |
4859 | 4864 | ||
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index dde671e97829..c248e0dccbe1 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
@@ -80,7 +80,7 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, | |||
80 | 80 | ||
81 | iph->version = 4; | 81 | iph->version = 4; |
82 | iph->ihl = sizeof(struct iphdr) >> 2; | 82 | iph->ihl = sizeof(struct iphdr) >> 2; |
83 | iph->frag_off = df; | 83 | iph->frag_off = ip_mtu_locked(&rt->dst) ? 0 : df; |
84 | iph->protocol = proto; | 84 | iph->protocol = proto; |
85 | iph->tos = tos; | 85 | iph->tos = tos; |
86 | iph->daddr = dst; | 86 | iph->daddr = dst; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2868ef28ce52..1e37c1388189 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4268,7 +4268,7 @@ static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq) | |||
4268 | * If the sack array is full, forget about the last one. | 4268 | * If the sack array is full, forget about the last one. |
4269 | */ | 4269 | */ |
4270 | if (this_sack >= TCP_NUM_SACKS) { | 4270 | if (this_sack >= TCP_NUM_SACKS) { |
4271 | if (tp->compressed_ack) | 4271 | if (tp->compressed_ack > TCP_FASTRETRANS_THRESH) |
4272 | tcp_send_ack(sk); | 4272 | tcp_send_ack(sk); |
4273 | this_sack--; | 4273 | this_sack--; |
4274 | tp->rx_opt.num_sacks--; | 4274 | tp->rx_opt.num_sacks--; |
@@ -4363,6 +4363,7 @@ static bool tcp_try_coalesce(struct sock *sk, | |||
4363 | if (TCP_SKB_CB(from)->has_rxtstamp) { | 4363 | if (TCP_SKB_CB(from)->has_rxtstamp) { |
4364 | TCP_SKB_CB(to)->has_rxtstamp = true; | 4364 | TCP_SKB_CB(to)->has_rxtstamp = true; |
4365 | to->tstamp = from->tstamp; | 4365 | to->tstamp = from->tstamp; |
4366 | skb_hwtstamps(to)->hwtstamp = skb_hwtstamps(from)->hwtstamp; | ||
4366 | } | 4367 | } |
4367 | 4368 | ||
4368 | return true; | 4369 | return true; |
@@ -5188,7 +5189,17 @@ send_now: | |||
5188 | if (!tcp_is_sack(tp) || | 5189 | if (!tcp_is_sack(tp) || |
5189 | tp->compressed_ack >= sock_net(sk)->ipv4.sysctl_tcp_comp_sack_nr) | 5190 | tp->compressed_ack >= sock_net(sk)->ipv4.sysctl_tcp_comp_sack_nr) |
5190 | goto send_now; | 5191 | goto send_now; |
5191 | tp->compressed_ack++; | 5192 | |
5193 | if (tp->compressed_ack_rcv_nxt != tp->rcv_nxt) { | ||
5194 | tp->compressed_ack_rcv_nxt = tp->rcv_nxt; | ||
5195 | if (tp->compressed_ack > TCP_FASTRETRANS_THRESH) | ||
5196 | NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, | ||
5197 | tp->compressed_ack - TCP_FASTRETRANS_THRESH); | ||
5198 | tp->compressed_ack = 0; | ||
5199 | } | ||
5200 | |||
5201 | if (++tp->compressed_ack <= TCP_FASTRETRANS_THRESH) | ||
5202 | goto send_now; | ||
5192 | 5203 | ||
5193 | if (hrtimer_is_queued(&tp->compressed_ack_timer)) | 5204 | if (hrtimer_is_queued(&tp->compressed_ack_timer)) |
5194 | return; | 5205 | return; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9c34b97d365d..3f510cad0b3e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -180,10 +180,10 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts, | |||
180 | { | 180 | { |
181 | struct tcp_sock *tp = tcp_sk(sk); | 181 | struct tcp_sock *tp = tcp_sk(sk); |
182 | 182 | ||
183 | if (unlikely(tp->compressed_ack)) { | 183 | if (unlikely(tp->compressed_ack > TCP_FASTRETRANS_THRESH)) { |
184 | NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, | 184 | NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, |
185 | tp->compressed_ack); | 185 | tp->compressed_ack - TCP_FASTRETRANS_THRESH); |
186 | tp->compressed_ack = 0; | 186 | tp->compressed_ack = TCP_FASTRETRANS_THRESH; |
187 | if (hrtimer_try_to_cancel(&tp->compressed_ack_timer) == 1) | 187 | if (hrtimer_try_to_cancel(&tp->compressed_ack_timer) == 1) |
188 | __sock_put(sk); | 188 | __sock_put(sk); |
189 | } | 189 | } |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 676020663ce8..5f8b6d3cd855 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -740,7 +740,7 @@ static enum hrtimer_restart tcp_compressed_ack_kick(struct hrtimer *timer) | |||
740 | 740 | ||
741 | bh_lock_sock(sk); | 741 | bh_lock_sock(sk); |
742 | if (!sock_owned_by_user(sk)) { | 742 | if (!sock_owned_by_user(sk)) { |
743 | if (tp->compressed_ack) | 743 | if (tp->compressed_ack > TCP_FASTRETRANS_THRESH) |
744 | tcp_send_ack(sk); | 744 | tcp_send_ack(sk); |
745 | } else { | 745 | } else { |
746 | if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, | 746 | if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 63a808d5af15..045597b9a7c0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -179,7 +179,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp); | |||
179 | static void addrconf_dad_work(struct work_struct *w); | 179 | static void addrconf_dad_work(struct work_struct *w); |
180 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id, | 180 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id, |
181 | bool send_na); | 181 | bool send_na); |
182 | static void addrconf_dad_run(struct inet6_dev *idev); | 182 | static void addrconf_dad_run(struct inet6_dev *idev, bool restart); |
183 | static void addrconf_rs_timer(struct timer_list *t); | 183 | static void addrconf_rs_timer(struct timer_list *t); |
184 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); | 184 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); |
185 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); | 185 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); |
@@ -3439,6 +3439,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3439 | void *ptr) | 3439 | void *ptr) |
3440 | { | 3440 | { |
3441 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 3441 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
3442 | struct netdev_notifier_change_info *change_info; | ||
3442 | struct netdev_notifier_changeupper_info *info; | 3443 | struct netdev_notifier_changeupper_info *info; |
3443 | struct inet6_dev *idev = __in6_dev_get(dev); | 3444 | struct inet6_dev *idev = __in6_dev_get(dev); |
3444 | struct net *net = dev_net(dev); | 3445 | struct net *net = dev_net(dev); |
@@ -3513,7 +3514,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3513 | break; | 3514 | break; |
3514 | } | 3515 | } |
3515 | 3516 | ||
3516 | if (idev) { | 3517 | if (!IS_ERR_OR_NULL(idev)) { |
3517 | if (idev->if_flags & IF_READY) { | 3518 | if (idev->if_flags & IF_READY) { |
3518 | /* device is already configured - | 3519 | /* device is already configured - |
3519 | * but resend MLD reports, we might | 3520 | * but resend MLD reports, we might |
@@ -3521,6 +3522,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3521 | * multicast snooping switches | 3522 | * multicast snooping switches |
3522 | */ | 3523 | */ |
3523 | ipv6_mc_up(idev); | 3524 | ipv6_mc_up(idev); |
3525 | change_info = ptr; | ||
3526 | if (change_info->flags_changed & IFF_NOARP) | ||
3527 | addrconf_dad_run(idev, true); | ||
3524 | rt6_sync_up(dev, RTNH_F_LINKDOWN); | 3528 | rt6_sync_up(dev, RTNH_F_LINKDOWN); |
3525 | break; | 3529 | break; |
3526 | } | 3530 | } |
@@ -3555,7 +3559,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3555 | 3559 | ||
3556 | if (!IS_ERR_OR_NULL(idev)) { | 3560 | if (!IS_ERR_OR_NULL(idev)) { |
3557 | if (run_pending) | 3561 | if (run_pending) |
3558 | addrconf_dad_run(idev); | 3562 | addrconf_dad_run(idev, false); |
3559 | 3563 | ||
3560 | /* Device has an address by now */ | 3564 | /* Device has an address by now */ |
3561 | rt6_sync_up(dev, RTNH_F_DEAD); | 3565 | rt6_sync_up(dev, RTNH_F_DEAD); |
@@ -4173,16 +4177,19 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id, | |||
4173 | addrconf_verify_rtnl(); | 4177 | addrconf_verify_rtnl(); |
4174 | } | 4178 | } |
4175 | 4179 | ||
4176 | static void addrconf_dad_run(struct inet6_dev *idev) | 4180 | static void addrconf_dad_run(struct inet6_dev *idev, bool restart) |
4177 | { | 4181 | { |
4178 | struct inet6_ifaddr *ifp; | 4182 | struct inet6_ifaddr *ifp; |
4179 | 4183 | ||
4180 | read_lock_bh(&idev->lock); | 4184 | read_lock_bh(&idev->lock); |
4181 | list_for_each_entry(ifp, &idev->addr_list, if_list) { | 4185 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
4182 | spin_lock(&ifp->lock); | 4186 | spin_lock(&ifp->lock); |
4183 | if (ifp->flags & IFA_F_TENTATIVE && | 4187 | if ((ifp->flags & IFA_F_TENTATIVE && |
4184 | ifp->state == INET6_IFADDR_STATE_DAD) | 4188 | ifp->state == INET6_IFADDR_STATE_DAD) || restart) { |
4189 | if (restart) | ||
4190 | ifp->state = INET6_IFADDR_STATE_PREDAD; | ||
4185 | addrconf_dad_kick(ifp); | 4191 | addrconf_dad_kick(ifp); |
4192 | } | ||
4186 | spin_unlock(&ifp->lock); | 4193 | spin_unlock(&ifp->lock); |
4187 | } | 4194 | } |
4188 | read_unlock_bh(&idev->lock); | 4195 | read_unlock_bh(&idev->lock); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 2a7423c39456..059f0531f7c1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2232,8 +2232,7 @@ static void ip6_link_failure(struct sk_buff *skb) | |||
2232 | if (rt) { | 2232 | if (rt) { |
2233 | rcu_read_lock(); | 2233 | rcu_read_lock(); |
2234 | if (rt->rt6i_flags & RTF_CACHE) { | 2234 | if (rt->rt6i_flags & RTF_CACHE) { |
2235 | if (dst_hold_safe(&rt->dst)) | 2235 | rt6_remove_exception_rt(rt); |
2236 | rt6_remove_exception_rt(rt); | ||
2237 | } else { | 2236 | } else { |
2238 | struct fib6_info *from; | 2237 | struct fib6_info *from; |
2239 | struct fib6_node *fn; | 2238 | struct fib6_node *fn; |
@@ -2360,10 +2359,13 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu); | |||
2360 | 2359 | ||
2361 | void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) | 2360 | void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) |
2362 | { | 2361 | { |
2362 | int oif = sk->sk_bound_dev_if; | ||
2363 | struct dst_entry *dst; | 2363 | struct dst_entry *dst; |
2364 | 2364 | ||
2365 | ip6_update_pmtu(skb, sock_net(sk), mtu, | 2365 | if (!oif && skb->dev) |
2366 | sk->sk_bound_dev_if, sk->sk_mark, sk->sk_uid); | 2366 | oif = l3mdev_master_ifindex(skb->dev); |
2367 | |||
2368 | ip6_update_pmtu(skb, sock_net(sk), mtu, oif, sk->sk_mark, sk->sk_uid); | ||
2367 | 2369 | ||
2368 | dst = __sk_dst_get(sk); | 2370 | dst = __sk_dst_get(sk); |
2369 | if (!dst || !dst->obsolete || | 2371 | if (!dst || !dst->obsolete || |
@@ -3214,8 +3216,8 @@ static int ip6_del_cached_rt(struct rt6_info *rt, struct fib6_config *cfg) | |||
3214 | if (cfg->fc_flags & RTF_GATEWAY && | 3216 | if (cfg->fc_flags & RTF_GATEWAY && |
3215 | !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway)) | 3217 | !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway)) |
3216 | goto out; | 3218 | goto out; |
3217 | if (dst_hold_safe(&rt->dst)) | 3219 | |
3218 | rc = rt6_remove_exception_rt(rt); | 3220 | rc = rt6_remove_exception_rt(rt); |
3219 | out: | 3221 | out: |
3220 | return rc; | 3222 | return rc; |
3221 | } | 3223 | } |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 82cdf9020b53..26f1d435696a 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1490,12 +1490,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, | |||
1490 | goto err_sock; | 1490 | goto err_sock; |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | sk = sock->sk; | ||
1494 | |||
1495 | sock_hold(sk); | ||
1496 | tunnel->sock = sk; | ||
1497 | tunnel->l2tp_net = net; | 1493 | tunnel->l2tp_net = net; |
1498 | |||
1499 | pn = l2tp_pernet(net); | 1494 | pn = l2tp_pernet(net); |
1500 | 1495 | ||
1501 | spin_lock_bh(&pn->l2tp_tunnel_list_lock); | 1496 | spin_lock_bh(&pn->l2tp_tunnel_list_lock); |
@@ -1510,6 +1505,10 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, | |||
1510 | list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list); | 1505 | list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list); |
1511 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); | 1506 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); |
1512 | 1507 | ||
1508 | sk = sock->sk; | ||
1509 | sock_hold(sk); | ||
1510 | tunnel->sock = sk; | ||
1511 | |||
1513 | if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { | 1512 | if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { |
1514 | struct udp_tunnel_sock_cfg udp_cfg = { | 1513 | struct udp_tunnel_sock_cfg udp_cfg = { |
1515 | .sk_user_data = tunnel, | 1514 | .sk_user_data = tunnel, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ec3095f13aae..a74650e98f42 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2394,7 +2394,7 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | |||
2394 | void *ph; | 2394 | void *ph; |
2395 | __u32 ts; | 2395 | __u32 ts; |
2396 | 2396 | ||
2397 | ph = skb_shinfo(skb)->destructor_arg; | 2397 | ph = skb_zcopy_get_nouarg(skb); |
2398 | packet_dec_pending(&po->tx_ring); | 2398 | packet_dec_pending(&po->tx_ring); |
2399 | 2399 | ||
2400 | ts = __packet_set_timestamp(po, ph, skb); | 2400 | ts = __packet_set_timestamp(po, ph, skb); |
@@ -2461,7 +2461,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
2461 | skb->mark = po->sk.sk_mark; | 2461 | skb->mark = po->sk.sk_mark; |
2462 | skb->tstamp = sockc->transmit_time; | 2462 | skb->tstamp = sockc->transmit_time; |
2463 | sock_tx_timestamp(&po->sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags); | 2463 | sock_tx_timestamp(&po->sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags); |
2464 | skb_shinfo(skb)->destructor_arg = ph.raw; | 2464 | skb_zcopy_set_nouarg(skb, ph.raw); |
2465 | 2465 | ||
2466 | skb_reserve(skb, hlen); | 2466 | skb_reserve(skb, hlen); |
2467 | skb_reset_network_header(skb); | 2467 | skb_reset_network_header(skb); |
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 64362d078da8..a2522f9d71e2 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -375,17 +375,36 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call); | |||
375 | * getting ACKs from the server. Returns a number representing the life state | 375 | * getting ACKs from the server. Returns a number representing the life state |
376 | * which can be compared to that returned by a previous call. | 376 | * which can be compared to that returned by a previous call. |
377 | * | 377 | * |
378 | * If this is a client call, ping ACKs will be sent to the server to find out | 378 | * If the life state stalls, rxrpc_kernel_probe_life() should be called and |
379 | * whether it's still responsive and whether the call is still alive on the | 379 | * then 2RTT waited. |
380 | * server. | ||
381 | */ | 380 | */ |
382 | u32 rxrpc_kernel_check_life(struct socket *sock, struct rxrpc_call *call) | 381 | u32 rxrpc_kernel_check_life(const struct socket *sock, |
382 | const struct rxrpc_call *call) | ||
383 | { | 383 | { |
384 | return call->acks_latest; | 384 | return call->acks_latest; |
385 | } | 385 | } |
386 | EXPORT_SYMBOL(rxrpc_kernel_check_life); | 386 | EXPORT_SYMBOL(rxrpc_kernel_check_life); |
387 | 387 | ||
388 | /** | 388 | /** |
389 | * rxrpc_kernel_probe_life - Poke the peer to see if it's still alive | ||
390 | * @sock: The socket the call is on | ||
391 | * @call: The call to check | ||
392 | * | ||
393 | * In conjunction with rxrpc_kernel_check_life(), allow a kernel service to | ||
394 | * find out whether a call is still alive by pinging it. This should cause the | ||
395 | * life state to be bumped in about 2*RTT. | ||
396 | * | ||
397 | * The must be called in TASK_RUNNING state on pain of might_sleep() objecting. | ||
398 | */ | ||
399 | void rxrpc_kernel_probe_life(struct socket *sock, struct rxrpc_call *call) | ||
400 | { | ||
401 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, | ||
402 | rxrpc_propose_ack_ping_for_check_life); | ||
403 | rxrpc_send_ack_packet(call, true, NULL); | ||
404 | } | ||
405 | EXPORT_SYMBOL(rxrpc_kernel_probe_life); | ||
406 | |||
407 | /** | ||
389 | * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. | 408 | * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. |
390 | * @sock: The socket the call is on | 409 | * @sock: The socket the call is on |
391 | * @call: The call to query | 410 | * @call: The call to query |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index da3dd0f68cc2..2b372a06b432 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -201,7 +201,8 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
201 | goto out_release; | 201 | goto out_release; |
202 | } | 202 | } |
203 | } else { | 203 | } else { |
204 | return err; | 204 | ret = err; |
205 | goto out_free; | ||
205 | } | 206 | } |
206 | 207 | ||
207 | p = to_pedit(*a); | 208 | p = to_pedit(*a); |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 052855d47354..37c9b8f0e10f 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -27,10 +27,7 @@ struct tcf_police_params { | |||
27 | u32 tcfp_ewma_rate; | 27 | u32 tcfp_ewma_rate; |
28 | s64 tcfp_burst; | 28 | s64 tcfp_burst; |
29 | u32 tcfp_mtu; | 29 | u32 tcfp_mtu; |
30 | s64 tcfp_toks; | ||
31 | s64 tcfp_ptoks; | ||
32 | s64 tcfp_mtu_ptoks; | 30 | s64 tcfp_mtu_ptoks; |
33 | s64 tcfp_t_c; | ||
34 | struct psched_ratecfg rate; | 31 | struct psched_ratecfg rate; |
35 | bool rate_present; | 32 | bool rate_present; |
36 | struct psched_ratecfg peak; | 33 | struct psched_ratecfg peak; |
@@ -41,6 +38,11 @@ struct tcf_police_params { | |||
41 | struct tcf_police { | 38 | struct tcf_police { |
42 | struct tc_action common; | 39 | struct tc_action common; |
43 | struct tcf_police_params __rcu *params; | 40 | struct tcf_police_params __rcu *params; |
41 | |||
42 | spinlock_t tcfp_lock ____cacheline_aligned_in_smp; | ||
43 | s64 tcfp_toks; | ||
44 | s64 tcfp_ptoks; | ||
45 | s64 tcfp_t_c; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | #define to_police(pc) ((struct tcf_police *)pc) | 48 | #define to_police(pc) ((struct tcf_police *)pc) |
@@ -122,6 +124,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, | |||
122 | return ret; | 124 | return ret; |
123 | } | 125 | } |
124 | ret = ACT_P_CREATED; | 126 | ret = ACT_P_CREATED; |
127 | spin_lock_init(&(to_police(*a)->tcfp_lock)); | ||
125 | } else if (!ovr) { | 128 | } else if (!ovr) { |
126 | tcf_idr_release(*a, bind); | 129 | tcf_idr_release(*a, bind); |
127 | return -EEXIST; | 130 | return -EEXIST; |
@@ -186,12 +189,9 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, | |||
186 | } | 189 | } |
187 | 190 | ||
188 | new->tcfp_burst = PSCHED_TICKS2NS(parm->burst); | 191 | new->tcfp_burst = PSCHED_TICKS2NS(parm->burst); |
189 | new->tcfp_toks = new->tcfp_burst; | 192 | if (new->peak_present) |
190 | if (new->peak_present) { | ||
191 | new->tcfp_mtu_ptoks = (s64)psched_l2t_ns(&new->peak, | 193 | new->tcfp_mtu_ptoks = (s64)psched_l2t_ns(&new->peak, |
192 | new->tcfp_mtu); | 194 | new->tcfp_mtu); |
193 | new->tcfp_ptoks = new->tcfp_mtu_ptoks; | ||
194 | } | ||
195 | 195 | ||
196 | if (tb[TCA_POLICE_AVRATE]) | 196 | if (tb[TCA_POLICE_AVRATE]) |
197 | new->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); | 197 | new->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); |
@@ -207,7 +207,12 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, | |||
207 | } | 207 | } |
208 | 208 | ||
209 | spin_lock_bh(&police->tcf_lock); | 209 | spin_lock_bh(&police->tcf_lock); |
210 | new->tcfp_t_c = ktime_get_ns(); | 210 | spin_lock_bh(&police->tcfp_lock); |
211 | police->tcfp_t_c = ktime_get_ns(); | ||
212 | police->tcfp_toks = new->tcfp_burst; | ||
213 | if (new->peak_present) | ||
214 | police->tcfp_ptoks = new->tcfp_mtu_ptoks; | ||
215 | spin_unlock_bh(&police->tcfp_lock); | ||
211 | police->tcf_action = parm->action; | 216 | police->tcf_action = parm->action; |
212 | rcu_swap_protected(police->params, | 217 | rcu_swap_protected(police->params, |
213 | new, | 218 | new, |
@@ -257,25 +262,28 @@ static int tcf_police_act(struct sk_buff *skb, const struct tc_action *a, | |||
257 | } | 262 | } |
258 | 263 | ||
259 | now = ktime_get_ns(); | 264 | now = ktime_get_ns(); |
260 | toks = min_t(s64, now - p->tcfp_t_c, p->tcfp_burst); | 265 | spin_lock_bh(&police->tcfp_lock); |
266 | toks = min_t(s64, now - police->tcfp_t_c, p->tcfp_burst); | ||
261 | if (p->peak_present) { | 267 | if (p->peak_present) { |
262 | ptoks = toks + p->tcfp_ptoks; | 268 | ptoks = toks + police->tcfp_ptoks; |
263 | if (ptoks > p->tcfp_mtu_ptoks) | 269 | if (ptoks > p->tcfp_mtu_ptoks) |
264 | ptoks = p->tcfp_mtu_ptoks; | 270 | ptoks = p->tcfp_mtu_ptoks; |
265 | ptoks -= (s64)psched_l2t_ns(&p->peak, | 271 | ptoks -= (s64)psched_l2t_ns(&p->peak, |
266 | qdisc_pkt_len(skb)); | 272 | qdisc_pkt_len(skb)); |
267 | } | 273 | } |
268 | toks += p->tcfp_toks; | 274 | toks += police->tcfp_toks; |
269 | if (toks > p->tcfp_burst) | 275 | if (toks > p->tcfp_burst) |
270 | toks = p->tcfp_burst; | 276 | toks = p->tcfp_burst; |
271 | toks -= (s64)psched_l2t_ns(&p->rate, qdisc_pkt_len(skb)); | 277 | toks -= (s64)psched_l2t_ns(&p->rate, qdisc_pkt_len(skb)); |
272 | if ((toks|ptoks) >= 0) { | 278 | if ((toks|ptoks) >= 0) { |
273 | p->tcfp_t_c = now; | 279 | police->tcfp_t_c = now; |
274 | p->tcfp_toks = toks; | 280 | police->tcfp_toks = toks; |
275 | p->tcfp_ptoks = ptoks; | 281 | police->tcfp_ptoks = ptoks; |
282 | spin_unlock_bh(&police->tcfp_lock); | ||
276 | ret = p->tcfp_result; | 283 | ret = p->tcfp_result; |
277 | goto inc_drops; | 284 | goto inc_drops; |
278 | } | 285 | } |
286 | spin_unlock_bh(&police->tcfp_lock); | ||
279 | } | 287 | } |
280 | 288 | ||
281 | inc_overlimits: | 289 | inc_overlimits: |
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 4b1af706896c..25a7cf6d380f 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c | |||
@@ -469,22 +469,29 @@ begin: | |||
469 | goto begin; | 469 | goto begin; |
470 | } | 470 | } |
471 | prefetch(&skb->end); | 471 | prefetch(&skb->end); |
472 | f->credit -= qdisc_pkt_len(skb); | 472 | plen = qdisc_pkt_len(skb); |
473 | f->credit -= plen; | ||
473 | 474 | ||
474 | if (ktime_to_ns(skb->tstamp) || !q->rate_enable) | 475 | if (!q->rate_enable) |
475 | goto out; | 476 | goto out; |
476 | 477 | ||
477 | rate = q->flow_max_rate; | 478 | rate = q->flow_max_rate; |
478 | if (skb->sk) | 479 | |
479 | rate = min(skb->sk->sk_pacing_rate, rate); | 480 | /* If EDT time was provided for this skb, we need to |
480 | 481 | * update f->time_next_packet only if this qdisc enforces | |
481 | if (rate <= q->low_rate_threshold) { | 482 | * a flow max rate. |
482 | f->credit = 0; | 483 | */ |
483 | plen = qdisc_pkt_len(skb); | 484 | if (!skb->tstamp) { |
484 | } else { | 485 | if (skb->sk) |
485 | plen = max(qdisc_pkt_len(skb), q->quantum); | 486 | rate = min(skb->sk->sk_pacing_rate, rate); |
486 | if (f->credit > 0) | 487 | |
487 | goto out; | 488 | if (rate <= q->low_rate_threshold) { |
489 | f->credit = 0; | ||
490 | } else { | ||
491 | plen = max(plen, q->quantum); | ||
492 | if (f->credit > 0) | ||
493 | goto out; | ||
494 | } | ||
488 | } | 495 | } |
489 | if (rate != ~0UL) { | 496 | if (rate != ~0UL) { |
490 | u64 len = (u64)plen * NSEC_PER_SEC; | 497 | u64 len = (u64)plen * NSEC_PER_SEC; |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 67939ad99c01..b0e74a3e77ec 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -118,6 +118,9 @@ void sctp_packet_config(struct sctp_packet *packet, __u32 vtag, | |||
118 | sctp_transport_route(tp, NULL, sp); | 118 | sctp_transport_route(tp, NULL, sp); |
119 | if (asoc->param_flags & SPP_PMTUD_ENABLE) | 119 | if (asoc->param_flags & SPP_PMTUD_ENABLE) |
120 | sctp_assoc_sync_pmtu(asoc); | 120 | sctp_assoc_sync_pmtu(asoc); |
121 | } else if (!sctp_transport_pmtu_check(tp)) { | ||
122 | if (asoc->param_flags & SPP_PMTUD_ENABLE) | ||
123 | sctp_assoc_sync_pmtu(asoc); | ||
121 | } | 124 | } |
122 | 125 | ||
123 | if (asoc->pmtu_pending) { | 126 | if (asoc->pmtu_pending) { |
@@ -396,25 +399,6 @@ finish: | |||
396 | return retval; | 399 | return retval; |
397 | } | 400 | } |
398 | 401 | ||
399 | static void sctp_packet_release_owner(struct sk_buff *skb) | ||
400 | { | ||
401 | sk_free(skb->sk); | ||
402 | } | ||
403 | |||
404 | static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk) | ||
405 | { | ||
406 | skb_orphan(skb); | ||
407 | skb->sk = sk; | ||
408 | skb->destructor = sctp_packet_release_owner; | ||
409 | |||
410 | /* | ||
411 | * The data chunks have already been accounted for in sctp_sendmsg(), | ||
412 | * therefore only reserve a single byte to keep socket around until | ||
413 | * the packet has been transmitted. | ||
414 | */ | ||
415 | refcount_inc(&sk->sk_wmem_alloc); | ||
416 | } | ||
417 | |||
418 | static void sctp_packet_gso_append(struct sk_buff *head, struct sk_buff *skb) | 402 | static void sctp_packet_gso_append(struct sk_buff *head, struct sk_buff *skb) |
419 | { | 403 | { |
420 | if (SCTP_OUTPUT_CB(head)->last == head) | 404 | if (SCTP_OUTPUT_CB(head)->last == head) |
@@ -601,7 +585,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
601 | if (!head) | 585 | if (!head) |
602 | goto out; | 586 | goto out; |
603 | skb_reserve(head, packet->overhead + MAX_HEADER); | 587 | skb_reserve(head, packet->overhead + MAX_HEADER); |
604 | sctp_packet_set_owner_w(head, sk); | 588 | skb_set_owner_w(head, sk); |
605 | 589 | ||
606 | /* set sctp header */ | 590 | /* set sctp header */ |
607 | sh = skb_push(head, sizeof(struct sctphdr)); | 591 | sh = skb_push(head, sizeof(struct sctphdr)); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 739f3e50120d..bf618d1b41fd 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3940,32 +3940,16 @@ static int sctp_setsockopt_pr_supported(struct sock *sk, | |||
3940 | unsigned int optlen) | 3940 | unsigned int optlen) |
3941 | { | 3941 | { |
3942 | struct sctp_assoc_value params; | 3942 | struct sctp_assoc_value params; |
3943 | struct sctp_association *asoc; | ||
3944 | int retval = -EINVAL; | ||
3945 | 3943 | ||
3946 | if (optlen != sizeof(params)) | 3944 | if (optlen != sizeof(params)) |
3947 | goto out; | 3945 | return -EINVAL; |
3948 | |||
3949 | if (copy_from_user(¶ms, optval, optlen)) { | ||
3950 | retval = -EFAULT; | ||
3951 | goto out; | ||
3952 | } | ||
3953 | |||
3954 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
3955 | if (asoc) { | ||
3956 | asoc->prsctp_enable = !!params.assoc_value; | ||
3957 | } else if (!params.assoc_id) { | ||
3958 | struct sctp_sock *sp = sctp_sk(sk); | ||
3959 | 3946 | ||
3960 | sp->ep->prsctp_enable = !!params.assoc_value; | 3947 | if (copy_from_user(¶ms, optval, optlen)) |
3961 | } else { | 3948 | return -EFAULT; |
3962 | goto out; | ||
3963 | } | ||
3964 | 3949 | ||
3965 | retval = 0; | 3950 | sctp_sk(sk)->ep->prsctp_enable = !!params.assoc_value; |
3966 | 3951 | ||
3967 | out: | 3952 | return 0; |
3968 | return retval; | ||
3969 | } | 3953 | } |
3970 | 3954 | ||
3971 | static int sctp_setsockopt_default_prinfo(struct sock *sk, | 3955 | static int sctp_setsockopt_default_prinfo(struct sock *sk, |
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index ffb940d3b57c..3892e7630f3a 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
@@ -535,7 +535,6 @@ int sctp_send_add_streams(struct sctp_association *asoc, | |||
535 | goto out; | 535 | goto out; |
536 | } | 536 | } |
537 | 537 | ||
538 | stream->incnt = incnt; | ||
539 | stream->outcnt = outcnt; | 538 | stream->outcnt = outcnt; |
540 | 539 | ||
541 | asoc->strreset_outstanding = !!out + !!in; | 540 | asoc->strreset_outstanding = !!out + !!in; |
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 80e2119f1c70..5fbaf1901571 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
@@ -127,6 +127,8 @@ static int smc_release(struct socket *sock) | |||
127 | smc = smc_sk(sk); | 127 | smc = smc_sk(sk); |
128 | 128 | ||
129 | /* cleanup for a dangling non-blocking connect */ | 129 | /* cleanup for a dangling non-blocking connect */ |
130 | if (smc->connect_info && sk->sk_state == SMC_INIT) | ||
131 | tcp_abort(smc->clcsock->sk, ECONNABORTED); | ||
130 | flush_work(&smc->connect_work); | 132 | flush_work(&smc->connect_work); |
131 | kfree(smc->connect_info); | 133 | kfree(smc->connect_info); |
132 | smc->connect_info = NULL; | 134 | smc->connect_info = NULL; |
@@ -547,7 +549,8 @@ static int smc_connect_rdma(struct smc_sock *smc, | |||
547 | 549 | ||
548 | mutex_lock(&smc_create_lgr_pending); | 550 | mutex_lock(&smc_create_lgr_pending); |
549 | local_contact = smc_conn_create(smc, false, aclc->hdr.flag, ibdev, | 551 | local_contact = smc_conn_create(smc, false, aclc->hdr.flag, ibdev, |
550 | ibport, &aclc->lcl, NULL, 0); | 552 | ibport, ntoh24(aclc->qpn), &aclc->lcl, |
553 | NULL, 0); | ||
551 | if (local_contact < 0) { | 554 | if (local_contact < 0) { |
552 | if (local_contact == -ENOMEM) | 555 | if (local_contact == -ENOMEM) |
553 | reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/ | 556 | reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/ |
@@ -618,7 +621,7 @@ static int smc_connect_ism(struct smc_sock *smc, | |||
618 | int rc = 0; | 621 | int rc = 0; |
619 | 622 | ||
620 | mutex_lock(&smc_create_lgr_pending); | 623 | mutex_lock(&smc_create_lgr_pending); |
621 | local_contact = smc_conn_create(smc, true, aclc->hdr.flag, NULL, 0, | 624 | local_contact = smc_conn_create(smc, true, aclc->hdr.flag, NULL, 0, 0, |
622 | NULL, ismdev, aclc->gid); | 625 | NULL, ismdev, aclc->gid); |
623 | if (local_contact < 0) | 626 | if (local_contact < 0) |
624 | return smc_connect_abort(smc, SMC_CLC_DECL_MEM, 0); | 627 | return smc_connect_abort(smc, SMC_CLC_DECL_MEM, 0); |
@@ -1083,7 +1086,7 @@ static int smc_listen_rdma_init(struct smc_sock *new_smc, | |||
1083 | int *local_contact) | 1086 | int *local_contact) |
1084 | { | 1087 | { |
1085 | /* allocate connection / link group */ | 1088 | /* allocate connection / link group */ |
1086 | *local_contact = smc_conn_create(new_smc, false, 0, ibdev, ibport, | 1089 | *local_contact = smc_conn_create(new_smc, false, 0, ibdev, ibport, 0, |
1087 | &pclc->lcl, NULL, 0); | 1090 | &pclc->lcl, NULL, 0); |
1088 | if (*local_contact < 0) { | 1091 | if (*local_contact < 0) { |
1089 | if (*local_contact == -ENOMEM) | 1092 | if (*local_contact == -ENOMEM) |
@@ -1107,7 +1110,7 @@ static int smc_listen_ism_init(struct smc_sock *new_smc, | |||
1107 | struct smc_clc_msg_smcd *pclc_smcd; | 1110 | struct smc_clc_msg_smcd *pclc_smcd; |
1108 | 1111 | ||
1109 | pclc_smcd = smc_get_clc_msg_smcd(pclc); | 1112 | pclc_smcd = smc_get_clc_msg_smcd(pclc); |
1110 | *local_contact = smc_conn_create(new_smc, true, 0, NULL, 0, NULL, | 1113 | *local_contact = smc_conn_create(new_smc, true, 0, NULL, 0, 0, NULL, |
1111 | ismdev, pclc_smcd->gid); | 1114 | ismdev, pclc_smcd->gid); |
1112 | if (*local_contact < 0) { | 1115 | if (*local_contact < 0) { |
1113 | if (*local_contact == -ENOMEM) | 1116 | if (*local_contact == -ENOMEM) |
diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c index ed5dcf03fe0b..db83332ac1c8 100644 --- a/net/smc/smc_cdc.c +++ b/net/smc/smc_cdc.c | |||
@@ -81,7 +81,7 @@ static inline void smc_cdc_add_pending_send(struct smc_connection *conn, | |||
81 | sizeof(struct smc_cdc_msg) > SMC_WR_BUF_SIZE, | 81 | sizeof(struct smc_cdc_msg) > SMC_WR_BUF_SIZE, |
82 | "must increase SMC_WR_BUF_SIZE to at least sizeof(struct smc_cdc_msg)"); | 82 | "must increase SMC_WR_BUF_SIZE to at least sizeof(struct smc_cdc_msg)"); |
83 | BUILD_BUG_ON_MSG( | 83 | BUILD_BUG_ON_MSG( |
84 | sizeof(struct smc_cdc_msg) != SMC_WR_TX_SIZE, | 84 | offsetofend(struct smc_cdc_msg, reserved) > SMC_WR_TX_SIZE, |
85 | "must adapt SMC_WR_TX_SIZE to sizeof(struct smc_cdc_msg); if not all smc_wr upper layer protocols use the same message size any more, must start to set link->wr_tx_sges[i].length on each individual smc_wr_tx_send()"); | 85 | "must adapt SMC_WR_TX_SIZE to sizeof(struct smc_cdc_msg); if not all smc_wr upper layer protocols use the same message size any more, must start to set link->wr_tx_sges[i].length on each individual smc_wr_tx_send()"); |
86 | BUILD_BUG_ON_MSG( | 86 | BUILD_BUG_ON_MSG( |
87 | sizeof(struct smc_cdc_tx_pend) > SMC_WR_TX_PEND_PRIV_SIZE, | 87 | sizeof(struct smc_cdc_tx_pend) > SMC_WR_TX_PEND_PRIV_SIZE, |
@@ -177,23 +177,24 @@ void smc_cdc_tx_dismiss_slots(struct smc_connection *conn) | |||
177 | int smcd_cdc_msg_send(struct smc_connection *conn) | 177 | int smcd_cdc_msg_send(struct smc_connection *conn) |
178 | { | 178 | { |
179 | struct smc_sock *smc = container_of(conn, struct smc_sock, conn); | 179 | struct smc_sock *smc = container_of(conn, struct smc_sock, conn); |
180 | union smc_host_cursor curs; | ||
180 | struct smcd_cdc_msg cdc; | 181 | struct smcd_cdc_msg cdc; |
181 | int rc, diff; | 182 | int rc, diff; |
182 | 183 | ||
183 | memset(&cdc, 0, sizeof(cdc)); | 184 | memset(&cdc, 0, sizeof(cdc)); |
184 | cdc.common.type = SMC_CDC_MSG_TYPE; | 185 | cdc.common.type = SMC_CDC_MSG_TYPE; |
185 | cdc.prod_wrap = conn->local_tx_ctrl.prod.wrap; | 186 | curs.acurs.counter = atomic64_read(&conn->local_tx_ctrl.prod.acurs); |
186 | cdc.prod_count = conn->local_tx_ctrl.prod.count; | 187 | cdc.prod.wrap = curs.wrap; |
187 | 188 | cdc.prod.count = curs.count; | |
188 | cdc.cons_wrap = conn->local_tx_ctrl.cons.wrap; | 189 | curs.acurs.counter = atomic64_read(&conn->local_tx_ctrl.cons.acurs); |
189 | cdc.cons_count = conn->local_tx_ctrl.cons.count; | 190 | cdc.cons.wrap = curs.wrap; |
190 | cdc.prod_flags = conn->local_tx_ctrl.prod_flags; | 191 | cdc.cons.count = curs.count; |
191 | cdc.conn_state_flags = conn->local_tx_ctrl.conn_state_flags; | 192 | cdc.cons.prod_flags = conn->local_tx_ctrl.prod_flags; |
193 | cdc.cons.conn_state_flags = conn->local_tx_ctrl.conn_state_flags; | ||
192 | rc = smcd_tx_ism_write(conn, &cdc, sizeof(cdc), 0, 1); | 194 | rc = smcd_tx_ism_write(conn, &cdc, sizeof(cdc), 0, 1); |
193 | if (rc) | 195 | if (rc) |
194 | return rc; | 196 | return rc; |
195 | smc_curs_copy(&conn->rx_curs_confirmed, &conn->local_tx_ctrl.cons, | 197 | smc_curs_copy(&conn->rx_curs_confirmed, &curs, conn); |
196 | conn); | ||
197 | /* Calculate transmitted data and increment free send buffer space */ | 198 | /* Calculate transmitted data and increment free send buffer space */ |
198 | diff = smc_curs_diff(conn->sndbuf_desc->len, &conn->tx_curs_fin, | 199 | diff = smc_curs_diff(conn->sndbuf_desc->len, &conn->tx_curs_fin, |
199 | &conn->tx_curs_sent); | 200 | &conn->tx_curs_sent); |
@@ -331,13 +332,16 @@ static void smc_cdc_msg_recv(struct smc_sock *smc, struct smc_cdc_msg *cdc) | |||
331 | static void smcd_cdc_rx_tsklet(unsigned long data) | 332 | static void smcd_cdc_rx_tsklet(unsigned long data) |
332 | { | 333 | { |
333 | struct smc_connection *conn = (struct smc_connection *)data; | 334 | struct smc_connection *conn = (struct smc_connection *)data; |
335 | struct smcd_cdc_msg *data_cdc; | ||
334 | struct smcd_cdc_msg cdc; | 336 | struct smcd_cdc_msg cdc; |
335 | struct smc_sock *smc; | 337 | struct smc_sock *smc; |
336 | 338 | ||
337 | if (!conn) | 339 | if (!conn) |
338 | return; | 340 | return; |
339 | 341 | ||
340 | memcpy(&cdc, conn->rmb_desc->cpu_addr, sizeof(cdc)); | 342 | data_cdc = (struct smcd_cdc_msg *)conn->rmb_desc->cpu_addr; |
343 | smcd_curs_copy(&cdc.prod, &data_cdc->prod, conn); | ||
344 | smcd_curs_copy(&cdc.cons, &data_cdc->cons, conn); | ||
341 | smc = container_of(conn, struct smc_sock, conn); | 345 | smc = container_of(conn, struct smc_sock, conn); |
342 | smc_cdc_msg_recv(smc, (struct smc_cdc_msg *)&cdc); | 346 | smc_cdc_msg_recv(smc, (struct smc_cdc_msg *)&cdc); |
343 | } | 347 | } |
diff --git a/net/smc/smc_cdc.h b/net/smc/smc_cdc.h index 934df4473a7c..b5bfe38c7f9b 100644 --- a/net/smc/smc_cdc.h +++ b/net/smc/smc_cdc.h | |||
@@ -48,21 +48,31 @@ struct smc_cdc_msg { | |||
48 | struct smc_cdc_producer_flags prod_flags; | 48 | struct smc_cdc_producer_flags prod_flags; |
49 | struct smc_cdc_conn_state_flags conn_state_flags; | 49 | struct smc_cdc_conn_state_flags conn_state_flags; |
50 | u8 reserved[18]; | 50 | u8 reserved[18]; |
51 | } __packed; /* format defined in RFC7609 */ | 51 | }; |
52 | |||
53 | /* SMC-D cursor format */ | ||
54 | union smcd_cdc_cursor { | ||
55 | struct { | ||
56 | u16 wrap; | ||
57 | u32 count; | ||
58 | struct smc_cdc_producer_flags prod_flags; | ||
59 | struct smc_cdc_conn_state_flags conn_state_flags; | ||
60 | } __packed; | ||
61 | #ifdef KERNEL_HAS_ATOMIC64 | ||
62 | atomic64_t acurs; /* for atomic processing */ | ||
63 | #else | ||
64 | u64 acurs; /* for atomic processing */ | ||
65 | #endif | ||
66 | } __aligned(8); | ||
52 | 67 | ||
53 | /* CDC message for SMC-D */ | 68 | /* CDC message for SMC-D */ |
54 | struct smcd_cdc_msg { | 69 | struct smcd_cdc_msg { |
55 | struct smc_wr_rx_hdr common; /* Type = 0xFE */ | 70 | struct smc_wr_rx_hdr common; /* Type = 0xFE */ |
56 | u8 res1[7]; | 71 | u8 res1[7]; |
57 | u16 prod_wrap; | 72 | union smcd_cdc_cursor prod; |
58 | u32 prod_count; | 73 | union smcd_cdc_cursor cons; |
59 | u8 res2[2]; | ||
60 | u16 cons_wrap; | ||
61 | u32 cons_count; | ||
62 | struct smc_cdc_producer_flags prod_flags; | ||
63 | struct smc_cdc_conn_state_flags conn_state_flags; | ||
64 | u8 res3[8]; | 74 | u8 res3[8]; |
65 | } __packed; | 75 | } __aligned(8); |
66 | 76 | ||
67 | static inline bool smc_cdc_rxed_any_close(struct smc_connection *conn) | 77 | static inline bool smc_cdc_rxed_any_close(struct smc_connection *conn) |
68 | { | 78 | { |
@@ -135,6 +145,21 @@ static inline void smc_curs_copy_net(union smc_cdc_cursor *tgt, | |||
135 | #endif | 145 | #endif |
136 | } | 146 | } |
137 | 147 | ||
148 | static inline void smcd_curs_copy(union smcd_cdc_cursor *tgt, | ||
149 | union smcd_cdc_cursor *src, | ||
150 | struct smc_connection *conn) | ||
151 | { | ||
152 | #ifndef KERNEL_HAS_ATOMIC64 | ||
153 | unsigned long flags; | ||
154 | |||
155 | spin_lock_irqsave(&conn->acurs_lock, flags); | ||
156 | tgt->acurs = src->acurs; | ||
157 | spin_unlock_irqrestore(&conn->acurs_lock, flags); | ||
158 | #else | ||
159 | atomic64_set(&tgt->acurs, atomic64_read(&src->acurs)); | ||
160 | #endif | ||
161 | } | ||
162 | |||
138 | /* calculate cursor difference between old and new, where old <= new */ | 163 | /* calculate cursor difference between old and new, where old <= new */ |
139 | static inline int smc_curs_diff(unsigned int size, | 164 | static inline int smc_curs_diff(unsigned int size, |
140 | union smc_host_cursor *old, | 165 | union smc_host_cursor *old, |
@@ -222,12 +247,17 @@ static inline void smcr_cdc_msg_to_host(struct smc_host_cdc_msg *local, | |||
222 | static inline void smcd_cdc_msg_to_host(struct smc_host_cdc_msg *local, | 247 | static inline void smcd_cdc_msg_to_host(struct smc_host_cdc_msg *local, |
223 | struct smcd_cdc_msg *peer) | 248 | struct smcd_cdc_msg *peer) |
224 | { | 249 | { |
225 | local->prod.wrap = peer->prod_wrap; | 250 | union smc_host_cursor temp; |
226 | local->prod.count = peer->prod_count; | 251 | |
227 | local->cons.wrap = peer->cons_wrap; | 252 | temp.wrap = peer->prod.wrap; |
228 | local->cons.count = peer->cons_count; | 253 | temp.count = peer->prod.count; |
229 | local->prod_flags = peer->prod_flags; | 254 | atomic64_set(&local->prod.acurs, atomic64_read(&temp.acurs)); |
230 | local->conn_state_flags = peer->conn_state_flags; | 255 | |
256 | temp.wrap = peer->cons.wrap; | ||
257 | temp.count = peer->cons.count; | ||
258 | atomic64_set(&local->cons.acurs, atomic64_read(&temp.acurs)); | ||
259 | local->prod_flags = peer->cons.prod_flags; | ||
260 | local->conn_state_flags = peer->cons.conn_state_flags; | ||
231 | } | 261 | } |
232 | 262 | ||
233 | static inline void smc_cdc_msg_to_host(struct smc_host_cdc_msg *local, | 263 | static inline void smc_cdc_msg_to_host(struct smc_host_cdc_msg *local, |
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 18daebcef181..1c9fa7f0261a 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c | |||
@@ -184,6 +184,8 @@ free: | |||
184 | 184 | ||
185 | if (!lgr->is_smcd && lnk->state != SMC_LNK_INACTIVE) | 185 | if (!lgr->is_smcd && lnk->state != SMC_LNK_INACTIVE) |
186 | smc_llc_link_inactive(lnk); | 186 | smc_llc_link_inactive(lnk); |
187 | if (lgr->is_smcd) | ||
188 | smc_ism_signal_shutdown(lgr); | ||
187 | smc_lgr_free(lgr); | 189 | smc_lgr_free(lgr); |
188 | } | 190 | } |
189 | } | 191 | } |
@@ -485,7 +487,7 @@ void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport) | |||
485 | } | 487 | } |
486 | 488 | ||
487 | /* Called when SMC-D device is terminated or peer is lost */ | 489 | /* Called when SMC-D device is terminated or peer is lost */ |
488 | void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid) | 490 | void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan) |
489 | { | 491 | { |
490 | struct smc_link_group *lgr, *l; | 492 | struct smc_link_group *lgr, *l; |
491 | LIST_HEAD(lgr_free_list); | 493 | LIST_HEAD(lgr_free_list); |
@@ -495,7 +497,7 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid) | |||
495 | list_for_each_entry_safe(lgr, l, &smc_lgr_list.list, list) { | 497 | list_for_each_entry_safe(lgr, l, &smc_lgr_list.list, list) { |
496 | if (lgr->is_smcd && lgr->smcd == dev && | 498 | if (lgr->is_smcd && lgr->smcd == dev && |
497 | (!peer_gid || lgr->peer_gid == peer_gid) && | 499 | (!peer_gid || lgr->peer_gid == peer_gid) && |
498 | !list_empty(&lgr->list)) { | 500 | (vlan == VLAN_VID_MASK || lgr->vlan_id == vlan)) { |
499 | __smc_lgr_terminate(lgr); | 501 | __smc_lgr_terminate(lgr); |
500 | list_move(&lgr->list, &lgr_free_list); | 502 | list_move(&lgr->list, &lgr_free_list); |
501 | } | 503 | } |
@@ -506,6 +508,8 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid) | |||
506 | list_for_each_entry_safe(lgr, l, &lgr_free_list, list) { | 508 | list_for_each_entry_safe(lgr, l, &lgr_free_list, list) { |
507 | list_del_init(&lgr->list); | 509 | list_del_init(&lgr->list); |
508 | cancel_delayed_work_sync(&lgr->free_work); | 510 | cancel_delayed_work_sync(&lgr->free_work); |
511 | if (!peer_gid && vlan == VLAN_VID_MASK) /* dev terminated? */ | ||
512 | smc_ism_signal_shutdown(lgr); | ||
509 | smc_lgr_free(lgr); | 513 | smc_lgr_free(lgr); |
510 | } | 514 | } |
511 | } | 515 | } |
@@ -559,7 +563,7 @@ out: | |||
559 | 563 | ||
560 | static bool smcr_lgr_match(struct smc_link_group *lgr, | 564 | static bool smcr_lgr_match(struct smc_link_group *lgr, |
561 | struct smc_clc_msg_local *lcl, | 565 | struct smc_clc_msg_local *lcl, |
562 | enum smc_lgr_role role) | 566 | enum smc_lgr_role role, u32 clcqpn) |
563 | { | 567 | { |
564 | return !memcmp(lgr->peer_systemid, lcl->id_for_peer, | 568 | return !memcmp(lgr->peer_systemid, lcl->id_for_peer, |
565 | SMC_SYSTEMID_LEN) && | 569 | SMC_SYSTEMID_LEN) && |
@@ -567,7 +571,9 @@ static bool smcr_lgr_match(struct smc_link_group *lgr, | |||
567 | SMC_GID_SIZE) && | 571 | SMC_GID_SIZE) && |
568 | !memcmp(lgr->lnk[SMC_SINGLE_LINK].peer_mac, lcl->mac, | 572 | !memcmp(lgr->lnk[SMC_SINGLE_LINK].peer_mac, lcl->mac, |
569 | sizeof(lcl->mac)) && | 573 | sizeof(lcl->mac)) && |
570 | lgr->role == role; | 574 | lgr->role == role && |
575 | (lgr->role == SMC_SERV || | ||
576 | lgr->lnk[SMC_SINGLE_LINK].peer_qpn == clcqpn); | ||
571 | } | 577 | } |
572 | 578 | ||
573 | static bool smcd_lgr_match(struct smc_link_group *lgr, | 579 | static bool smcd_lgr_match(struct smc_link_group *lgr, |
@@ -578,7 +584,7 @@ static bool smcd_lgr_match(struct smc_link_group *lgr, | |||
578 | 584 | ||
579 | /* create a new SMC connection (and a new link group if necessary) */ | 585 | /* create a new SMC connection (and a new link group if necessary) */ |
580 | int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, | 586 | int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, |
581 | struct smc_ib_device *smcibdev, u8 ibport, | 587 | struct smc_ib_device *smcibdev, u8 ibport, u32 clcqpn, |
582 | struct smc_clc_msg_local *lcl, struct smcd_dev *smcd, | 588 | struct smc_clc_msg_local *lcl, struct smcd_dev *smcd, |
583 | u64 peer_gid) | 589 | u64 peer_gid) |
584 | { | 590 | { |
@@ -603,7 +609,7 @@ int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, | |||
603 | list_for_each_entry(lgr, &smc_lgr_list.list, list) { | 609 | list_for_each_entry(lgr, &smc_lgr_list.list, list) { |
604 | write_lock_bh(&lgr->conns_lock); | 610 | write_lock_bh(&lgr->conns_lock); |
605 | if ((is_smcd ? smcd_lgr_match(lgr, smcd, peer_gid) : | 611 | if ((is_smcd ? smcd_lgr_match(lgr, smcd, peer_gid) : |
606 | smcr_lgr_match(lgr, lcl, role)) && | 612 | smcr_lgr_match(lgr, lcl, role, clcqpn)) && |
607 | !lgr->sync_err && | 613 | !lgr->sync_err && |
608 | lgr->vlan_id == vlan_id && | 614 | lgr->vlan_id == vlan_id && |
609 | (role == SMC_CLNT || | 615 | (role == SMC_CLNT || |
@@ -1024,6 +1030,8 @@ void smc_core_exit(void) | |||
1024 | smc_llc_link_inactive(lnk); | 1030 | smc_llc_link_inactive(lnk); |
1025 | } | 1031 | } |
1026 | cancel_delayed_work_sync(&lgr->free_work); | 1032 | cancel_delayed_work_sync(&lgr->free_work); |
1033 | if (lgr->is_smcd) | ||
1034 | smc_ism_signal_shutdown(lgr); | ||
1027 | smc_lgr_free(lgr); /* free link group */ | 1035 | smc_lgr_free(lgr); /* free link group */ |
1028 | } | 1036 | } |
1029 | } | 1037 | } |
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index c156674733c9..cf98f4d6093e 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h | |||
@@ -247,7 +247,8 @@ void smc_lgr_free(struct smc_link_group *lgr); | |||
247 | void smc_lgr_forget(struct smc_link_group *lgr); | 247 | void smc_lgr_forget(struct smc_link_group *lgr); |
248 | void smc_lgr_terminate(struct smc_link_group *lgr); | 248 | void smc_lgr_terminate(struct smc_link_group *lgr); |
249 | void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport); | 249 | void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport); |
250 | void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid); | 250 | void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, |
251 | unsigned short vlan); | ||
251 | int smc_buf_create(struct smc_sock *smc, bool is_smcd); | 252 | int smc_buf_create(struct smc_sock *smc, bool is_smcd); |
252 | int smc_uncompress_bufsize(u8 compressed); | 253 | int smc_uncompress_bufsize(u8 compressed); |
253 | int smc_rmb_rtoken_handling(struct smc_connection *conn, | 254 | int smc_rmb_rtoken_handling(struct smc_connection *conn, |
@@ -262,7 +263,7 @@ int smc_vlan_by_tcpsk(struct socket *clcsock, unsigned short *vlan_id); | |||
262 | 263 | ||
263 | void smc_conn_free(struct smc_connection *conn); | 264 | void smc_conn_free(struct smc_connection *conn); |
264 | int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, | 265 | int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, |
265 | struct smc_ib_device *smcibdev, u8 ibport, | 266 | struct smc_ib_device *smcibdev, u8 ibport, u32 clcqpn, |
266 | struct smc_clc_msg_local *lcl, struct smcd_dev *smcd, | 267 | struct smc_clc_msg_local *lcl, struct smcd_dev *smcd, |
267 | u64 peer_gid); | 268 | u64 peer_gid); |
268 | void smcd_conn_free(struct smc_connection *conn); | 269 | void smcd_conn_free(struct smc_connection *conn); |
diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c index e36f21ce7252..2fff79db1a59 100644 --- a/net/smc/smc_ism.c +++ b/net/smc/smc_ism.c | |||
@@ -187,22 +187,28 @@ struct smc_ism_event_work { | |||
187 | #define ISM_EVENT_REQUEST 0x0001 | 187 | #define ISM_EVENT_REQUEST 0x0001 |
188 | #define ISM_EVENT_RESPONSE 0x0002 | 188 | #define ISM_EVENT_RESPONSE 0x0002 |
189 | #define ISM_EVENT_REQUEST_IR 0x00000001 | 189 | #define ISM_EVENT_REQUEST_IR 0x00000001 |
190 | #define ISM_EVENT_CODE_SHUTDOWN 0x80 | ||
190 | #define ISM_EVENT_CODE_TESTLINK 0x83 | 191 | #define ISM_EVENT_CODE_TESTLINK 0x83 |
191 | 192 | ||
193 | union smcd_sw_event_info { | ||
194 | u64 info; | ||
195 | struct { | ||
196 | u8 uid[SMC_LGR_ID_SIZE]; | ||
197 | unsigned short vlan_id; | ||
198 | u16 code; | ||
199 | }; | ||
200 | }; | ||
201 | |||
192 | static void smcd_handle_sw_event(struct smc_ism_event_work *wrk) | 202 | static void smcd_handle_sw_event(struct smc_ism_event_work *wrk) |
193 | { | 203 | { |
194 | union { | 204 | union smcd_sw_event_info ev_info; |
195 | u64 info; | ||
196 | struct { | ||
197 | u32 uid; | ||
198 | unsigned short vlanid; | ||
199 | u16 code; | ||
200 | }; | ||
201 | } ev_info; | ||
202 | 205 | ||
206 | ev_info.info = wrk->event.info; | ||
203 | switch (wrk->event.code) { | 207 | switch (wrk->event.code) { |
208 | case ISM_EVENT_CODE_SHUTDOWN: /* Peer shut down DMBs */ | ||
209 | smc_smcd_terminate(wrk->smcd, wrk->event.tok, ev_info.vlan_id); | ||
210 | break; | ||
204 | case ISM_EVENT_CODE_TESTLINK: /* Activity timer */ | 211 | case ISM_EVENT_CODE_TESTLINK: /* Activity timer */ |
205 | ev_info.info = wrk->event.info; | ||
206 | if (ev_info.code == ISM_EVENT_REQUEST) { | 212 | if (ev_info.code == ISM_EVENT_REQUEST) { |
207 | ev_info.code = ISM_EVENT_RESPONSE; | 213 | ev_info.code = ISM_EVENT_RESPONSE; |
208 | wrk->smcd->ops->signal_event(wrk->smcd, | 214 | wrk->smcd->ops->signal_event(wrk->smcd, |
@@ -215,6 +221,21 @@ static void smcd_handle_sw_event(struct smc_ism_event_work *wrk) | |||
215 | } | 221 | } |
216 | } | 222 | } |
217 | 223 | ||
224 | int smc_ism_signal_shutdown(struct smc_link_group *lgr) | ||
225 | { | ||
226 | int rc; | ||
227 | union smcd_sw_event_info ev_info; | ||
228 | |||
229 | memcpy(ev_info.uid, lgr->id, SMC_LGR_ID_SIZE); | ||
230 | ev_info.vlan_id = lgr->vlan_id; | ||
231 | ev_info.code = ISM_EVENT_REQUEST; | ||
232 | rc = lgr->smcd->ops->signal_event(lgr->smcd, lgr->peer_gid, | ||
233 | ISM_EVENT_REQUEST_IR, | ||
234 | ISM_EVENT_CODE_SHUTDOWN, | ||
235 | ev_info.info); | ||
236 | return rc; | ||
237 | } | ||
238 | |||
218 | /* worker for SMC-D events */ | 239 | /* worker for SMC-D events */ |
219 | static void smc_ism_event_work(struct work_struct *work) | 240 | static void smc_ism_event_work(struct work_struct *work) |
220 | { | 241 | { |
@@ -223,7 +244,7 @@ static void smc_ism_event_work(struct work_struct *work) | |||
223 | 244 | ||
224 | switch (wrk->event.type) { | 245 | switch (wrk->event.type) { |
225 | case ISM_EVENT_GID: /* GID event, token is peer GID */ | 246 | case ISM_EVENT_GID: /* GID event, token is peer GID */ |
226 | smc_smcd_terminate(wrk->smcd, wrk->event.tok); | 247 | smc_smcd_terminate(wrk->smcd, wrk->event.tok, VLAN_VID_MASK); |
227 | break; | 248 | break; |
228 | case ISM_EVENT_DMB: | 249 | case ISM_EVENT_DMB: |
229 | break; | 250 | break; |
@@ -289,7 +310,7 @@ void smcd_unregister_dev(struct smcd_dev *smcd) | |||
289 | spin_unlock(&smcd_dev_list.lock); | 310 | spin_unlock(&smcd_dev_list.lock); |
290 | flush_workqueue(smcd->event_wq); | 311 | flush_workqueue(smcd->event_wq); |
291 | destroy_workqueue(smcd->event_wq); | 312 | destroy_workqueue(smcd->event_wq); |
292 | smc_smcd_terminate(smcd, 0); | 313 | smc_smcd_terminate(smcd, 0, VLAN_VID_MASK); |
293 | 314 | ||
294 | device_del(&smcd->dev); | 315 | device_del(&smcd->dev); |
295 | } | 316 | } |
diff --git a/net/smc/smc_ism.h b/net/smc/smc_ism.h index aee45b860b79..4da946cbfa29 100644 --- a/net/smc/smc_ism.h +++ b/net/smc/smc_ism.h | |||
@@ -45,4 +45,5 @@ int smc_ism_register_dmb(struct smc_link_group *lgr, int buf_size, | |||
45 | int smc_ism_unregister_dmb(struct smcd_dev *dev, struct smc_buf_desc *dmb_desc); | 45 | int smc_ism_unregister_dmb(struct smcd_dev *dev, struct smc_buf_desc *dmb_desc); |
46 | int smc_ism_write(struct smcd_dev *dev, const struct smc_ism_position *pos, | 46 | int smc_ism_write(struct smcd_dev *dev, const struct smc_ism_position *pos, |
47 | void *data, size_t len); | 47 | void *data, size_t len); |
48 | int smc_ism_signal_shutdown(struct smc_link_group *lgr); | ||
48 | #endif | 49 | #endif |
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index 3c458d279855..c2694750a6a8 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c | |||
@@ -215,12 +215,14 @@ int smc_wr_tx_put_slot(struct smc_link *link, | |||
215 | 215 | ||
216 | pend = container_of(wr_pend_priv, struct smc_wr_tx_pend, priv); | 216 | pend = container_of(wr_pend_priv, struct smc_wr_tx_pend, priv); |
217 | if (pend->idx < link->wr_tx_cnt) { | 217 | if (pend->idx < link->wr_tx_cnt) { |
218 | u32 idx = pend->idx; | ||
219 | |||
218 | /* clear the full struct smc_wr_tx_pend including .priv */ | 220 | /* clear the full struct smc_wr_tx_pend including .priv */ |
219 | memset(&link->wr_tx_pends[pend->idx], 0, | 221 | memset(&link->wr_tx_pends[pend->idx], 0, |
220 | sizeof(link->wr_tx_pends[pend->idx])); | 222 | sizeof(link->wr_tx_pends[pend->idx])); |
221 | memset(&link->wr_tx_bufs[pend->idx], 0, | 223 | memset(&link->wr_tx_bufs[pend->idx], 0, |
222 | sizeof(link->wr_tx_bufs[pend->idx])); | 224 | sizeof(link->wr_tx_bufs[pend->idx])); |
223 | test_and_clear_bit(pend->idx, link->wr_tx_mask); | 225 | test_and_clear_bit(idx, link->wr_tx_mask); |
224 | return 1; | 226 | return 1; |
225 | } | 227 | } |
226 | 228 | ||
diff --git a/net/socket.c b/net/socket.c index 593826e11a53..334fcc617ef2 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -853,7 +853,7 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
853 | struct socket *sock = file->private_data; | 853 | struct socket *sock = file->private_data; |
854 | 854 | ||
855 | if (unlikely(!sock->ops->splice_read)) | 855 | if (unlikely(!sock->ops->splice_read)) |
856 | return -EINVAL; | 856 | return generic_file_splice_read(file, ppos, pipe, len, flags); |
857 | 857 | ||
858 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 858 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
859 | } | 859 | } |
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 2830709957bd..c138d68e8a69 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
@@ -166,7 +166,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d, | |||
166 | 166 | ||
167 | /* Apply trial address if we just left trial period */ | 167 | /* Apply trial address if we just left trial period */ |
168 | if (!trial && !self) { | 168 | if (!trial && !self) { |
169 | tipc_net_finalize(net, tn->trial_addr); | 169 | tipc_sched_net_finalize(net, tn->trial_addr); |
170 | msg_set_prevnode(buf_msg(d->skb), tn->trial_addr); | ||
170 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); | 171 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); |
171 | } | 172 | } |
172 | 173 | ||
@@ -300,14 +301,12 @@ static void tipc_disc_timeout(struct timer_list *t) | |||
300 | goto exit; | 301 | goto exit; |
301 | } | 302 | } |
302 | 303 | ||
303 | /* Trial period over ? */ | 304 | /* Did we just leave trial period ? */ |
304 | if (!time_before(jiffies, tn->addr_trial_end)) { | 305 | if (!time_before(jiffies, tn->addr_trial_end) && !tipc_own_addr(net)) { |
305 | /* Did we just leave it ? */ | 306 | mod_timer(&d->timer, jiffies + TIPC_DISC_INIT); |
306 | if (!tipc_own_addr(net)) | 307 | spin_unlock_bh(&d->lock); |
307 | tipc_net_finalize(net, tn->trial_addr); | 308 | tipc_sched_net_finalize(net, tn->trial_addr); |
308 | 309 | return; | |
309 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); | ||
310 | msg_set_prevnode(buf_msg(d->skb), tipc_own_addr(net)); | ||
311 | } | 310 | } |
312 | 311 | ||
313 | /* Adjust timeout interval according to discovery phase */ | 312 | /* Adjust timeout interval according to discovery phase */ |
@@ -319,6 +318,8 @@ static void tipc_disc_timeout(struct timer_list *t) | |||
319 | d->timer_intv = TIPC_DISC_SLOW; | 318 | d->timer_intv = TIPC_DISC_SLOW; |
320 | else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST) | 319 | else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST) |
321 | d->timer_intv = TIPC_DISC_FAST; | 320 | d->timer_intv = TIPC_DISC_FAST; |
321 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); | ||
322 | msg_set_prevnode(buf_msg(d->skb), tn->trial_addr); | ||
322 | } | 323 | } |
323 | 324 | ||
324 | mod_timer(&d->timer, jiffies + d->timer_intv); | 325 | mod_timer(&d->timer, jiffies + d->timer_intv); |
diff --git a/net/tipc/net.c b/net/tipc/net.c index 62199cf5a56c..f076edb74338 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
@@ -104,6 +104,14 @@ | |||
104 | * - A local spin_lock protecting the queue of subscriber events. | 104 | * - A local spin_lock protecting the queue of subscriber events. |
105 | */ | 105 | */ |
106 | 106 | ||
107 | struct tipc_net_work { | ||
108 | struct work_struct work; | ||
109 | struct net *net; | ||
110 | u32 addr; | ||
111 | }; | ||
112 | |||
113 | static void tipc_net_finalize(struct net *net, u32 addr); | ||
114 | |||
107 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr) | 115 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr) |
108 | { | 116 | { |
109 | if (tipc_own_id(net)) { | 117 | if (tipc_own_id(net)) { |
@@ -119,17 +127,38 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr) | |||
119 | return 0; | 127 | return 0; |
120 | } | 128 | } |
121 | 129 | ||
122 | void tipc_net_finalize(struct net *net, u32 addr) | 130 | static void tipc_net_finalize(struct net *net, u32 addr) |
123 | { | 131 | { |
124 | struct tipc_net *tn = tipc_net(net); | 132 | struct tipc_net *tn = tipc_net(net); |
125 | 133 | ||
126 | if (!cmpxchg(&tn->node_addr, 0, addr)) { | 134 | if (cmpxchg(&tn->node_addr, 0, addr)) |
127 | tipc_set_node_addr(net, addr); | 135 | return; |
128 | tipc_named_reinit(net); | 136 | tipc_set_node_addr(net, addr); |
129 | tipc_sk_reinit(net); | 137 | tipc_named_reinit(net); |
130 | tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, | 138 | tipc_sk_reinit(net); |
131 | TIPC_CLUSTER_SCOPE, 0, addr); | 139 | tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, |
132 | } | 140 | TIPC_CLUSTER_SCOPE, 0, addr); |
141 | } | ||
142 | |||
143 | static void tipc_net_finalize_work(struct work_struct *work) | ||
144 | { | ||
145 | struct tipc_net_work *fwork; | ||
146 | |||
147 | fwork = container_of(work, struct tipc_net_work, work); | ||
148 | tipc_net_finalize(fwork->net, fwork->addr); | ||
149 | kfree(fwork); | ||
150 | } | ||
151 | |||
152 | void tipc_sched_net_finalize(struct net *net, u32 addr) | ||
153 | { | ||
154 | struct tipc_net_work *fwork = kzalloc(sizeof(*fwork), GFP_ATOMIC); | ||
155 | |||
156 | if (!fwork) | ||
157 | return; | ||
158 | INIT_WORK(&fwork->work, tipc_net_finalize_work); | ||
159 | fwork->net = net; | ||
160 | fwork->addr = addr; | ||
161 | schedule_work(&fwork->work); | ||
133 | } | 162 | } |
134 | 163 | ||
135 | void tipc_net_stop(struct net *net) | 164 | void tipc_net_stop(struct net *net) |
diff --git a/net/tipc/net.h b/net/tipc/net.h index 09ad02b50bb1..b7f2e364eb99 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h | |||
@@ -42,7 +42,7 @@ | |||
42 | extern const struct nla_policy tipc_nl_net_policy[]; | 42 | extern const struct nla_policy tipc_nl_net_policy[]; |
43 | 43 | ||
44 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr); | 44 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr); |
45 | void tipc_net_finalize(struct net *net, u32 addr); | 45 | void tipc_sched_net_finalize(struct net *net, u32 addr); |
46 | void tipc_net_stop(struct net *net); | 46 | void tipc_net_stop(struct net *net); |
47 | int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); | 47 | int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); |
48 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); | 48 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 636e6131769d..b57b1be7252b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1555,16 +1555,17 @@ static void tipc_sk_set_orig_addr(struct msghdr *m, struct sk_buff *skb) | |||
1555 | /** | 1555 | /** |
1556 | * tipc_sk_anc_data_recv - optionally capture ancillary data for received message | 1556 | * tipc_sk_anc_data_recv - optionally capture ancillary data for received message |
1557 | * @m: descriptor for message info | 1557 | * @m: descriptor for message info |
1558 | * @msg: received message header | 1558 | * @skb: received message buffer |
1559 | * @tsk: TIPC port associated with message | 1559 | * @tsk: TIPC port associated with message |
1560 | * | 1560 | * |
1561 | * Note: Ancillary data is not captured if not requested by receiver. | 1561 | * Note: Ancillary data is not captured if not requested by receiver. |
1562 | * | 1562 | * |
1563 | * Returns 0 if successful, otherwise errno | 1563 | * Returns 0 if successful, otherwise errno |
1564 | */ | 1564 | */ |
1565 | static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | 1565 | static int tipc_sk_anc_data_recv(struct msghdr *m, struct sk_buff *skb, |
1566 | struct tipc_sock *tsk) | 1566 | struct tipc_sock *tsk) |
1567 | { | 1567 | { |
1568 | struct tipc_msg *msg; | ||
1568 | u32 anc_data[3]; | 1569 | u32 anc_data[3]; |
1569 | u32 err; | 1570 | u32 err; |
1570 | u32 dest_type; | 1571 | u32 dest_type; |
@@ -1573,6 +1574,7 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
1573 | 1574 | ||
1574 | if (likely(m->msg_controllen == 0)) | 1575 | if (likely(m->msg_controllen == 0)) |
1575 | return 0; | 1576 | return 0; |
1577 | msg = buf_msg(skb); | ||
1576 | 1578 | ||
1577 | /* Optionally capture errored message object(s) */ | 1579 | /* Optionally capture errored message object(s) */ |
1578 | err = msg ? msg_errcode(msg) : 0; | 1580 | err = msg ? msg_errcode(msg) : 0; |
@@ -1583,6 +1585,9 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
1583 | if (res) | 1585 | if (res) |
1584 | return res; | 1586 | return res; |
1585 | if (anc_data[1]) { | 1587 | if (anc_data[1]) { |
1588 | if (skb_linearize(skb)) | ||
1589 | return -ENOMEM; | ||
1590 | msg = buf_msg(skb); | ||
1586 | res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], | 1591 | res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], |
1587 | msg_data(msg)); | 1592 | msg_data(msg)); |
1588 | if (res) | 1593 | if (res) |
@@ -1744,9 +1749,10 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, | |||
1744 | 1749 | ||
1745 | /* Collect msg meta data, including error code and rejected data */ | 1750 | /* Collect msg meta data, including error code and rejected data */ |
1746 | tipc_sk_set_orig_addr(m, skb); | 1751 | tipc_sk_set_orig_addr(m, skb); |
1747 | rc = tipc_sk_anc_data_recv(m, hdr, tsk); | 1752 | rc = tipc_sk_anc_data_recv(m, skb, tsk); |
1748 | if (unlikely(rc)) | 1753 | if (unlikely(rc)) |
1749 | goto exit; | 1754 | goto exit; |
1755 | hdr = buf_msg(skb); | ||
1750 | 1756 | ||
1751 | /* Capture data if non-error msg, otherwise just set return value */ | 1757 | /* Capture data if non-error msg, otherwise just set return value */ |
1752 | if (likely(!err)) { | 1758 | if (likely(!err)) { |
@@ -1856,9 +1862,10 @@ static int tipc_recvstream(struct socket *sock, struct msghdr *m, | |||
1856 | /* Collect msg meta data, incl. error code and rejected data */ | 1862 | /* Collect msg meta data, incl. error code and rejected data */ |
1857 | if (!copied) { | 1863 | if (!copied) { |
1858 | tipc_sk_set_orig_addr(m, skb); | 1864 | tipc_sk_set_orig_addr(m, skb); |
1859 | rc = tipc_sk_anc_data_recv(m, hdr, tsk); | 1865 | rc = tipc_sk_anc_data_recv(m, skb, tsk); |
1860 | if (rc) | 1866 | if (rc) |
1861 | break; | 1867 | break; |
1868 | hdr = buf_msg(skb); | ||
1862 | } | 1869 | } |
1863 | 1870 | ||
1864 | /* Copy data if msg ok, otherwise return error/partial data */ | 1871 | /* Copy data if msg ok, otherwise return error/partial data */ |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index f8d4a419f3af..467039b342b5 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -1062,8 +1062,8 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) | |||
1062 | runtime->oss.channels = params_channels(params); | 1062 | runtime->oss.channels = params_channels(params); |
1063 | runtime->oss.rate = params_rate(params); | 1063 | runtime->oss.rate = params_rate(params); |
1064 | 1064 | ||
1065 | vfree(runtime->oss.buffer); | 1065 | kvfree(runtime->oss.buffer); |
1066 | runtime->oss.buffer = vmalloc(runtime->oss.period_bytes); | 1066 | runtime->oss.buffer = kvzalloc(runtime->oss.period_bytes, GFP_KERNEL); |
1067 | if (!runtime->oss.buffer) { | 1067 | if (!runtime->oss.buffer) { |
1068 | err = -ENOMEM; | 1068 | err = -ENOMEM; |
1069 | goto failure; | 1069 | goto failure; |
@@ -2328,7 +2328,7 @@ static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) | |||
2328 | { | 2328 | { |
2329 | struct snd_pcm_runtime *runtime; | 2329 | struct snd_pcm_runtime *runtime; |
2330 | runtime = substream->runtime; | 2330 | runtime = substream->runtime; |
2331 | vfree(runtime->oss.buffer); | 2331 | kvfree(runtime->oss.buffer); |
2332 | runtime->oss.buffer = NULL; | 2332 | runtime->oss.buffer = NULL; |
2333 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | 2333 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS |
2334 | snd_pcm_oss_plugin_clear(substream); | 2334 | snd_pcm_oss_plugin_clear(substream); |
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 141c5f3a9575..31cb2acf8afc 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c | |||
@@ -66,8 +66,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t | |||
66 | return -ENXIO; | 66 | return -ENXIO; |
67 | size /= 8; | 67 | size /= 8; |
68 | if (plugin->buf_frames < frames) { | 68 | if (plugin->buf_frames < frames) { |
69 | vfree(plugin->buf); | 69 | kvfree(plugin->buf); |
70 | plugin->buf = vmalloc(size); | 70 | plugin->buf = kvzalloc(size, GFP_KERNEL); |
71 | plugin->buf_frames = frames; | 71 | plugin->buf_frames = frames; |
72 | } | 72 | } |
73 | if (!plugin->buf) { | 73 | if (!plugin->buf) { |
@@ -191,7 +191,7 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin) | |||
191 | if (plugin->private_free) | 191 | if (plugin->private_free) |
192 | plugin->private_free(plugin); | 192 | plugin->private_free(plugin); |
193 | kfree(plugin->buf_channels); | 193 | kfree(plugin->buf_channels); |
194 | vfree(plugin->buf); | 194 | kvfree(plugin->buf); |
195 | kfree(plugin); | 195 | kfree(plugin); |
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 0a24037184c3..0a567634e5fa 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -1177,6 +1177,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = { | |||
1177 | SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), | 1177 | SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), |
1178 | SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), | 1178 | SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), |
1179 | SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), | 1179 | SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), |
1180 | SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ), | ||
1180 | SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), | 1181 | SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), |
1181 | SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), | 1182 | SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), |
1182 | SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI), | 1183 | SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI), |
@@ -8413,7 +8414,7 @@ static void ca0132_free(struct hda_codec *codec) | |||
8413 | 8414 | ||
8414 | snd_hda_power_down(codec); | 8415 | snd_hda_power_down(codec); |
8415 | if (spec->mem_base) | 8416 | if (spec->mem_base) |
8416 | iounmap(spec->mem_base); | 8417 | pci_iounmap(codec->bus->pci, spec->mem_base); |
8417 | kfree(spec->spec_init_verbs); | 8418 | kfree(spec->spec_init_verbs); |
8418 | kfree(codec->spec); | 8419 | kfree(codec->spec); |
8419 | } | 8420 | } |
@@ -8488,7 +8489,7 @@ static void ca0132_config(struct hda_codec *codec) | |||
8488 | break; | 8489 | break; |
8489 | case QUIRK_AE5: | 8490 | case QUIRK_AE5: |
8490 | codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__); | 8491 | codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__); |
8491 | snd_hda_apply_pincfgs(codec, r3di_pincfgs); | 8492 | snd_hda_apply_pincfgs(codec, ae5_pincfgs); |
8492 | break; | 8493 | break; |
8493 | } | 8494 | } |
8494 | 8495 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fa61674a5605..970bc44a378b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -6481,6 +6481,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6481 | SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 6481 | SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
6482 | SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 6482 | SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
6483 | SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), | 6483 | SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), |
6484 | SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), | ||
6484 | SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), | 6485 | SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), |
6485 | SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), | 6486 | SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), |
6486 | SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), | 6487 | SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), |
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 1dd5f4fcffd5..db66a952c173 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile | |||
@@ -129,7 +129,7 @@ WARNINGS += $(call cc-supports,-Wno-pointer-sign) | |||
129 | WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) | 129 | WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) |
130 | WARNINGS += -Wshadow | 130 | WARNINGS += -Wshadow |
131 | 131 | ||
132 | CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \ | 132 | override CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \ |
133 | -DPACKAGE_BUGREPORT=\"$(PACKAGE_BUGREPORT)\" -D_GNU_SOURCE | 133 | -DPACKAGE_BUGREPORT=\"$(PACKAGE_BUGREPORT)\" -D_GNU_SOURCE |
134 | 134 | ||
135 | UTIL_OBJS = utils/helpers/amd.o utils/helpers/msr.o \ | 135 | UTIL_OBJS = utils/helpers/amd.o utils/helpers/msr.o \ |
@@ -156,12 +156,12 @@ LIB_SRC = lib/cpufreq.c lib/cpupower.c lib/cpuidle.c | |||
156 | LIB_OBJS = lib/cpufreq.o lib/cpupower.o lib/cpuidle.o | 156 | LIB_OBJS = lib/cpufreq.o lib/cpupower.o lib/cpuidle.o |
157 | LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS)) | 157 | LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS)) |
158 | 158 | ||
159 | CFLAGS += -pipe | 159 | override CFLAGS += -pipe |
160 | 160 | ||
161 | ifeq ($(strip $(NLS)),true) | 161 | ifeq ($(strip $(NLS)),true) |
162 | INSTALL_NLS += install-gmo | 162 | INSTALL_NLS += install-gmo |
163 | COMPILE_NLS += create-gmo | 163 | COMPILE_NLS += create-gmo |
164 | CFLAGS += -DNLS | 164 | override CFLAGS += -DNLS |
165 | endif | 165 | endif |
166 | 166 | ||
167 | ifeq ($(strip $(CPUFREQ_BENCH)),true) | 167 | ifeq ($(strip $(CPUFREQ_BENCH)),true) |
@@ -175,7 +175,7 @@ ifeq ($(strip $(STATIC)),true) | |||
175 | UTIL_SRC += $(LIB_SRC) | 175 | UTIL_SRC += $(LIB_SRC) |
176 | endif | 176 | endif |
177 | 177 | ||
178 | CFLAGS += $(WARNINGS) | 178 | override CFLAGS += $(WARNINGS) |
179 | 179 | ||
180 | ifeq ($(strip $(V)),false) | 180 | ifeq ($(strip $(V)),false) |
181 | QUIET=@ | 181 | QUIET=@ |
@@ -188,10 +188,10 @@ export QUIET ECHO | |||
188 | 188 | ||
189 | # if DEBUG is enabled, then we do not strip or optimize | 189 | # if DEBUG is enabled, then we do not strip or optimize |
190 | ifeq ($(strip $(DEBUG)),true) | 190 | ifeq ($(strip $(DEBUG)),true) |
191 | CFLAGS += -O1 -g -DDEBUG | 191 | override CFLAGS += -O1 -g -DDEBUG |
192 | STRIPCMD = /bin/true -Since_we_are_debugging | 192 | STRIPCMD = /bin/true -Since_we_are_debugging |
193 | else | 193 | else |
194 | CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer | 194 | override CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer |
195 | STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment | 195 | STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment |
196 | endif | 196 | endif |
197 | 197 | ||
diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile index d79ab161cc75..f68b4bc55273 100644 --- a/tools/power/cpupower/bench/Makefile +++ b/tools/power/cpupower/bench/Makefile | |||
@@ -9,7 +9,7 @@ endif | |||
9 | ifeq ($(strip $(STATIC)),true) | 9 | ifeq ($(strip $(STATIC)),true) |
10 | LIBS = -L../ -L$(OUTPUT) -lm | 10 | LIBS = -L../ -L$(OUTPUT) -lm |
11 | OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o \ | 11 | OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o \ |
12 | $(OUTPUT)../lib/cpufreq.o $(OUTPUT)../lib/sysfs.o | 12 | $(OUTPUT)../lib/cpufreq.o $(OUTPUT)../lib/cpupower.o |
13 | else | 13 | else |
14 | LIBS = -L../ -L$(OUTPUT) -lm -lcpupower | 14 | LIBS = -L../ -L$(OUTPUT) -lm -lcpupower |
15 | OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o | 15 | OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o |
diff --git a/tools/power/cpupower/debug/x86_64/Makefile b/tools/power/cpupower/debug/x86_64/Makefile index 59af84b8ef45..b1b6c43644e7 100644 --- a/tools/power/cpupower/debug/x86_64/Makefile +++ b/tools/power/cpupower/debug/x86_64/Makefile | |||
@@ -13,10 +13,10 @@ INSTALL = /usr/bin/install | |||
13 | default: all | 13 | default: all |
14 | 14 | ||
15 | $(OUTPUT)centrino-decode: ../i386/centrino-decode.c | 15 | $(OUTPUT)centrino-decode: ../i386/centrino-decode.c |
16 | $(CC) $(CFLAGS) -o $@ $< | 16 | $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< |
17 | 17 | ||
18 | $(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c | 18 | $(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c |
19 | $(CC) $(CFLAGS) -o $@ $< | 19 | $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< |
20 | 20 | ||
21 | all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode | 21 | all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode |
22 | 22 | ||
diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c index 1b993fe1ce23..0c0f3e3f0d80 100644 --- a/tools/power/cpupower/lib/cpufreq.c +++ b/tools/power/cpupower/lib/cpufreq.c | |||
@@ -28,7 +28,7 @@ static unsigned int sysfs_cpufreq_read_file(unsigned int cpu, const char *fname, | |||
28 | 28 | ||
29 | snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", | 29 | snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", |
30 | cpu, fname); | 30 | cpu, fname); |
31 | return sysfs_read_file(path, buf, buflen); | 31 | return cpupower_read_sysfs(path, buf, buflen); |
32 | } | 32 | } |
33 | 33 | ||
34 | /* helper function to write a new value to a /sys file */ | 34 | /* helper function to write a new value to a /sys file */ |
diff --git a/tools/power/cpupower/lib/cpuidle.c b/tools/power/cpupower/lib/cpuidle.c index 9bd4c7655fdb..852d25462388 100644 --- a/tools/power/cpupower/lib/cpuidle.c +++ b/tools/power/cpupower/lib/cpuidle.c | |||
@@ -319,7 +319,7 @@ static unsigned int sysfs_cpuidle_read_file(const char *fname, char *buf, | |||
319 | 319 | ||
320 | snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname); | 320 | snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname); |
321 | 321 | ||
322 | return sysfs_read_file(path, buf, buflen); | 322 | return cpupower_read_sysfs(path, buf, buflen); |
323 | } | 323 | } |
324 | 324 | ||
325 | 325 | ||
diff --git a/tools/power/cpupower/lib/cpupower.c b/tools/power/cpupower/lib/cpupower.c index 9c395ec924de..9711d628b0f4 100644 --- a/tools/power/cpupower/lib/cpupower.c +++ b/tools/power/cpupower/lib/cpupower.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "cpupower.h" | 15 | #include "cpupower.h" |
16 | #include "cpupower_intern.h" | 16 | #include "cpupower_intern.h" |
17 | 17 | ||
18 | unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) | 18 | unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen) |
19 | { | 19 | { |
20 | int fd; | 20 | int fd; |
21 | ssize_t numread; | 21 | ssize_t numread; |
@@ -95,7 +95,7 @@ static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *re | |||
95 | 95 | ||
96 | snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", | 96 | snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", |
97 | cpu, fname); | 97 | cpu, fname); |
98 | if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) | 98 | if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) |
99 | return -1; | 99 | return -1; |
100 | *result = strtol(linebuf, &endp, 0); | 100 | *result = strtol(linebuf, &endp, 0); |
101 | if (endp == linebuf || errno == ERANGE) | 101 | if (endp == linebuf || errno == ERANGE) |
diff --git a/tools/power/cpupower/lib/cpupower_intern.h b/tools/power/cpupower/lib/cpupower_intern.h index 92affdfbe417..4887c76d23f8 100644 --- a/tools/power/cpupower/lib/cpupower_intern.h +++ b/tools/power/cpupower/lib/cpupower_intern.h | |||
@@ -3,4 +3,4 @@ | |||
3 | #define MAX_LINE_LEN 4096 | 3 | #define MAX_LINE_LEN 4096 |
4 | #define SYSFS_PATH_MAX 255 | 4 | #define SYSFS_PATH_MAX 255 |
5 | 5 | ||
6 | unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); | 6 | unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen); |
diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py index 87a04a8a5945..7607ba3e3cbe 100755 --- a/tools/testing/selftests/tc-testing/tdc.py +++ b/tools/testing/selftests/tc-testing/tdc.py | |||
@@ -134,9 +134,9 @@ def exec_cmd(args, pm, stage, command): | |||
134 | (rawout, serr) = proc.communicate() | 134 | (rawout, serr) = proc.communicate() |
135 | 135 | ||
136 | if proc.returncode != 0 and len(serr) > 0: | 136 | if proc.returncode != 0 and len(serr) > 0: |
137 | foutput = serr.decode("utf-8") | 137 | foutput = serr.decode("utf-8", errors="ignore") |
138 | else: | 138 | else: |
139 | foutput = rawout.decode("utf-8") | 139 | foutput = rawout.decode("utf-8", errors="ignore") |
140 | 140 | ||
141 | proc.stdout.close() | 141 | proc.stdout.close() |
142 | proc.stderr.close() | 142 | proc.stderr.close() |
@@ -169,6 +169,8 @@ def prepare_env(args, pm, stage, prefix, cmdlist, output = None): | |||
169 | file=sys.stderr) | 169 | file=sys.stderr) |
170 | print("\n{} *** Error message: \"{}\"".format(prefix, foutput), | 170 | print("\n{} *** Error message: \"{}\"".format(prefix, foutput), |
171 | file=sys.stderr) | 171 | file=sys.stderr) |
172 | print("returncode {}; expected {}".format(proc.returncode, | ||
173 | exit_codes)) | ||
172 | print("\n{} *** Aborting test run.".format(prefix), file=sys.stderr) | 174 | print("\n{} *** Aborting test run.".format(prefix), file=sys.stderr) |
173 | print("\n\n{} *** stdout ***".format(proc.stdout), file=sys.stderr) | 175 | print("\n\n{} *** stdout ***".format(proc.stdout), file=sys.stderr) |
174 | print("\n\n{} *** stderr ***".format(proc.stderr), file=sys.stderr) | 176 | print("\n\n{} *** stderr ***".format(proc.stderr), file=sys.stderr) |
@@ -195,12 +197,18 @@ def run_one_test(pm, args, index, tidx): | |||
195 | print('-----> execute stage') | 197 | print('-----> execute stage') |
196 | pm.call_pre_execute() | 198 | pm.call_pre_execute() |
197 | (p, procout) = exec_cmd(args, pm, 'execute', tidx["cmdUnderTest"]) | 199 | (p, procout) = exec_cmd(args, pm, 'execute', tidx["cmdUnderTest"]) |
198 | exit_code = p.returncode | 200 | if p: |
201 | exit_code = p.returncode | ||
202 | else: | ||
203 | exit_code = None | ||
204 | |||
199 | pm.call_post_execute() | 205 | pm.call_post_execute() |
200 | 206 | ||
201 | if (exit_code != int(tidx["expExitCode"])): | 207 | if (exit_code is None or exit_code != int(tidx["expExitCode"])): |
202 | result = False | 208 | result = False |
203 | print("exit:", exit_code, int(tidx["expExitCode"])) | 209 | print("exit: {!r}".format(exit_code)) |
210 | print("exit: {}".format(int(tidx["expExitCode"]))) | ||
211 | #print("exit: {!r} {}".format(exit_code, int(tidx["expExitCode"]))) | ||
204 | print(procout) | 212 | print(procout) |
205 | else: | 213 | else: |
206 | if args.verbose > 0: | 214 | if args.verbose > 0: |