diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-12-08 05:33:24 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-12-08 05:33:24 -0500 |
commit | 77de61c3975da6f2200935c341e84018ece6ce36 (patch) | |
tree | 36508cf93ef62a80c988fa18c86eda1274e03877 | |
parent | 66139a48cee1530c91f37c145384b4ee7043f0b7 (diff) | |
parent | 048184540171672a724ab8f8bada7fcc0762f5c6 (diff) |
Merge branch 'for-next' into for-linus
511 files changed, 9959 insertions, 6809 deletions
diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl index 0230a96f0564..71f9246127ec 100644 --- a/Documentation/DocBook/alsa-driver-api.tmpl +++ b/Documentation/DocBook/alsa-driver-api.tmpl | |||
@@ -57,6 +57,7 @@ | |||
57 | !Esound/core/pcm.c | 57 | !Esound/core/pcm.c |
58 | !Esound/core/pcm_lib.c | 58 | !Esound/core/pcm_lib.c |
59 | !Esound/core/pcm_native.c | 59 | !Esound/core/pcm_native.c |
60 | !Iinclude/sound/pcm.h | ||
60 | </sect1> | 61 | </sect1> |
61 | <sect1><title>PCM Format Helpers</title> | 62 | <sect1><title>PCM Format Helpers</title> |
62 | !Esound/core/pcm_misc.c | 63 | !Esound/core/pcm_misc.c |
@@ -64,6 +65,10 @@ | |||
64 | <sect1><title>PCM Memory Management</title> | 65 | <sect1><title>PCM Memory Management</title> |
65 | !Esound/core/pcm_memory.c | 66 | !Esound/core/pcm_memory.c |
66 | </sect1> | 67 | </sect1> |
68 | <sect1><title>PCM DMA Engine API</title> | ||
69 | !Esound/core/pcm_dmaengine.c | ||
70 | !Iinclude/sound/dmaengine_pcm.h | ||
71 | </sect1> | ||
67 | </chapter> | 72 | </chapter> |
68 | <chapter><title>Control/Mixer API</title> | 73 | <chapter><title>Control/Mixer API</title> |
69 | <sect1><title>General Control Interface</title> | 74 | <sect1><title>General Control Interface</title> |
@@ -91,12 +96,38 @@ | |||
91 | !Esound/core/info.c | 96 | !Esound/core/info.c |
92 | </sect1> | 97 | </sect1> |
93 | </chapter> | 98 | </chapter> |
99 | <chapter><title>Compress Offload</title> | ||
100 | <sect1><title>Compress Offload API</title> | ||
101 | !Esound/core/compress_offload.c | ||
102 | !Iinclude/uapi/sound/compress_offload.h | ||
103 | !Iinclude/uapi/sound/compress_params.h | ||
104 | !Iinclude/sound/compress_driver.h | ||
105 | </sect1> | ||
106 | </chapter> | ||
107 | <chapter><title>ASoC</title> | ||
108 | <sect1><title>ASoC Core API</title> | ||
109 | !Iinclude/sound/soc.h | ||
110 | !Esound/soc/soc-core.c | ||
111 | !Esound/soc/soc-cache.c | ||
112 | !Esound/soc/soc-devres.c | ||
113 | !Esound/soc/soc-io.c | ||
114 | !Esound/soc/soc-pcm.c | ||
115 | </sect1> | ||
116 | <sect1><title>ASoC DAPM API</title> | ||
117 | !Esound/soc/soc-dapm.c | ||
118 | </sect1> | ||
119 | <sect1><title>ASoC DMA Engine API</title> | ||
120 | !Esound/soc/soc-generic-dmaengine-pcm.c | ||
121 | </sect1> | ||
122 | </chapter> | ||
94 | <chapter><title>Miscellaneous Functions</title> | 123 | <chapter><title>Miscellaneous Functions</title> |
95 | <sect1><title>Hardware-Dependent Devices API</title> | 124 | <sect1><title>Hardware-Dependent Devices API</title> |
96 | !Esound/core/hwdep.c | 125 | !Esound/core/hwdep.c |
97 | </sect1> | 126 | </sect1> |
98 | <sect1><title>Jack Abstraction Layer API</title> | 127 | <sect1><title>Jack Abstraction Layer API</title> |
128 | !Iinclude/sound/jack.h | ||
99 | !Esound/core/jack.c | 129 | !Esound/core/jack.c |
130 | !Esound/soc/soc-jack.c | ||
100 | </sect1> | 131 | </sect1> |
101 | <sect1><title>ISA DMA Helpers</title> | 132 | <sect1><title>ISA DMA Helpers</title> |
102 | !Esound/core/isadma.c | 133 | !Esound/core/isadma.c |
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl index 784793df81ed..84ef6a90131c 100644 --- a/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl | |||
@@ -3658,6 +3658,29 @@ struct _snd_pcm_runtime { | |||
3658 | </para> | 3658 | </para> |
3659 | 3659 | ||
3660 | <para> | 3660 | <para> |
3661 | The above callback can be simplified with a helper function, | ||
3662 | <function>snd_ctl_enum_info</function>. The final code | ||
3663 | looks like below. | ||
3664 | (You can pass ARRAY_SIZE(texts) instead of 4 in the third | ||
3665 | argument; it's a matter of taste.) | ||
3666 | |||
3667 | <informalexample> | ||
3668 | <programlisting> | ||
3669 | <![CDATA[ | ||
3670 | static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol, | ||
3671 | struct snd_ctl_elem_info *uinfo) | ||
3672 | { | ||
3673 | static char *texts[4] = { | ||
3674 | "First", "Second", "Third", "Fourth" | ||
3675 | }; | ||
3676 | return snd_ctl_enum_info(uinfo, 1, 4, texts); | ||
3677 | } | ||
3678 | ]]> | ||
3679 | </programlisting> | ||
3680 | </informalexample> | ||
3681 | </para> | ||
3682 | |||
3683 | <para> | ||
3661 | Some common info callbacks are available for your convenience: | 3684 | Some common info callbacks are available for your convenience: |
3662 | <function>snd_ctl_boolean_mono_info()</function> and | 3685 | <function>snd_ctl_boolean_mono_info()</function> and |
3663 | <function>snd_ctl_boolean_stereo_info()</function>. | 3686 | <function>snd_ctl_boolean_stereo_info()</function>. |
diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt index ce6a1a072028..8a3c40829899 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | |||
@@ -30,10 +30,6 @@ should only be used when a device has multiple interrupt parents. | |||
30 | Example: | 30 | Example: |
31 | interrupts-extended = <&intc1 5 1>, <&intc2 1 0>; | 31 | interrupts-extended = <&intc1 5 1>, <&intc2 1 0>; |
32 | 32 | ||
33 | A device node may contain either "interrupts" or "interrupts-extended", but not | ||
34 | both. If both properties are present, then the operating system should log an | ||
35 | error and use only the data in "interrupts". | ||
36 | |||
37 | 2) Interrupt controller nodes | 33 | 2) Interrupt controller nodes |
38 | ----------------------------- | 34 | ----------------------------- |
39 | 35 | ||
diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt index 41aeed38926d..f8fbe9af7b2f 100644 --- a/Documentation/devicetree/bindings/pci/pci.txt +++ b/Documentation/devicetree/bindings/pci/pci.txt | |||
@@ -7,3 +7,14 @@ And for the interrupt mapping part: | |||
7 | 7 | ||
8 | Open Firmware Recommended Practice: Interrupt Mapping | 8 | Open Firmware Recommended Practice: Interrupt Mapping |
9 | http://www.openfirmware.org/1275/practice/imap/imap0_9d.pdf | 9 | http://www.openfirmware.org/1275/practice/imap/imap0_9d.pdf |
10 | |||
11 | Additionally to the properties specified in the above standards a host bridge | ||
12 | driver implementation may support the following properties: | ||
13 | |||
14 | - linux,pci-domain: | ||
15 | If present this property assigns a fixed PCI domain number to a host bridge, | ||
16 | otherwise an unstable (across boots) unique number will be assigned. | ||
17 | It is required to either not set this property at all or set it for all | ||
18 | host bridges in the system, otherwise potentially conflicting domain numbers | ||
19 | may be assigned to root buses behind different host bridges. The domain | ||
20 | number for each host bridge in the system must be unique. | ||
diff --git a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt index a186181c402b..51b943cc9770 100644 --- a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt | |||
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
9 | common pinctrl bindings used by client devices, including the meaning of the | 9 | common pinctrl bindings used by client devices, including the meaning of the |
10 | phrase "pin configuration node". | 10 | phrase "pin configuration node". |
11 | 11 | ||
12 | TZ1090-PDC's pin configuration nodes act as a container for an abitrary number | 12 | TZ1090-PDC's pin configuration nodes act as a container for an arbitrary number |
13 | of subnodes. Each of these subnodes represents some desired configuration for a | 13 | of subnodes. Each of these subnodes represents some desired configuration for a |
14 | pin, a group, or a list of pins or groups. This configuration can include the | 14 | pin, a group, or a list of pins or groups. This configuration can include the |
15 | mux function to select on those pin(s)/group(s), and various pin configuration | 15 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt index 4b27c99f7f9d..49d0e6050940 100644 --- a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt | |||
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
9 | common pinctrl bindings used by client devices, including the meaning of the | 9 | common pinctrl bindings used by client devices, including the meaning of the |
10 | phrase "pin configuration node". | 10 | phrase "pin configuration node". |
11 | 11 | ||
12 | TZ1090's pin configuration nodes act as a container for an abitrary number of | 12 | TZ1090's pin configuration nodes act as a container for an arbitrary number of |
13 | subnodes. Each of these subnodes represents some desired configuration for a | 13 | subnodes. Each of these subnodes represents some desired configuration for a |
14 | pin, a group, or a list of pins or groups. This configuration can include the | 14 | pin, a group, or a list of pins or groups. This configuration can include the |
15 | mux function to select on those pin(s)/group(s), and various pin configuration | 15 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt index daa768956069..ac4da9fe07bd 100644 --- a/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt +++ b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt | |||
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
9 | common pinctrl bindings used by client devices, including the meaning of the | 9 | common pinctrl bindings used by client devices, including the meaning of the |
10 | phrase "pin configuration node". | 10 | phrase "pin configuration node". |
11 | 11 | ||
12 | Lantiq's pin configuration nodes act as a container for an abitrary number of | 12 | Lantiq's pin configuration nodes act as a container for an arbitrary number of |
13 | subnodes. Each of these subnodes represents some desired configuration for a | 13 | subnodes. Each of these subnodes represents some desired configuration for a |
14 | pin, a group, or a list of pins or groups. This configuration can include the | 14 | pin, a group, or a list of pins or groups. This configuration can include the |
15 | mux function to select on those group(s), and two pin configuration parameters: | 15 | mux function to select on those group(s), and two pin configuration parameters: |
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt index b5469db1d7ad..e89b4677567d 100644 --- a/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt +++ b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt | |||
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
9 | common pinctrl bindings used by client devices, including the meaning of the | 9 | common pinctrl bindings used by client devices, including the meaning of the |
10 | phrase "pin configuration node". | 10 | phrase "pin configuration node". |
11 | 11 | ||
12 | Lantiq's pin configuration nodes act as a container for an abitrary number of | 12 | Lantiq's pin configuration nodes act as a container for an arbitrary number of |
13 | subnodes. Each of these subnodes represents some desired configuration for a | 13 | subnodes. Each of these subnodes represents some desired configuration for a |
14 | pin, a group, or a list of pins or groups. This configuration can include the | 14 | pin, a group, or a list of pins or groups. This configuration can include the |
15 | mux function to select on those group(s), and two pin configuration parameters: | 15 | mux function to select on those group(s), and two pin configuration parameters: |
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt index 61e73cde9ae9..3c8ce28baad6 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt | |||
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
9 | common pinctrl bindings used by client devices, including the meaning of the | 9 | common pinctrl bindings used by client devices, including the meaning of the |
10 | phrase "pin configuration node". | 10 | phrase "pin configuration node". |
11 | 11 | ||
12 | Tegra's pin configuration nodes act as a container for an abitrary number of | 12 | Tegra's pin configuration nodes act as a container for an arbitrary number of |
13 | subnodes. Each of these subnodes represents some desired configuration for a | 13 | subnodes. Each of these subnodes represents some desired configuration for a |
14 | pin, a group, or a list of pins or groups. This configuration can include the | 14 | pin, a group, or a list of pins or groups. This configuration can include the |
15 | mux function to select on those pin(s)/group(s), and various pin configuration | 15 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-sirf.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-sirf.txt index c596a6ad3285..5f55be59d914 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-sirf.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-sirf.txt | |||
@@ -13,7 +13,7 @@ Optional properties: | |||
13 | Please refer to pinctrl-bindings.txt in this directory for details of the common | 13 | Please refer to pinctrl-bindings.txt in this directory for details of the common |
14 | pinctrl bindings used by client devices. | 14 | pinctrl bindings used by client devices. |
15 | 15 | ||
16 | SiRFprimaII's pinmux nodes act as a container for an abitrary number of subnodes. | 16 | SiRFprimaII's pinmux nodes act as a container for an arbitrary number of subnodes. |
17 | Each of these subnodes represents some desired configuration for a group of pins. | 17 | Each of these subnodes represents some desired configuration for a group of pins. |
18 | 18 | ||
19 | Required subnode-properties: | 19 | Required subnode-properties: |
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt index b4480d5c3aca..458615596946 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt | |||
@@ -32,7 +32,7 @@ Required properties: | |||
32 | Please refer to pinctrl-bindings.txt in this directory for details of the common | 32 | Please refer to pinctrl-bindings.txt in this directory for details of the common |
33 | pinctrl bindings used by client devices. | 33 | pinctrl bindings used by client devices. |
34 | 34 | ||
35 | SPEAr's pinmux nodes act as a container for an abitrary number of subnodes. Each | 35 | SPEAr's pinmux nodes act as a container for an arbitrary number of subnodes. Each |
36 | of these subnodes represents muxing for a pin, a group, or a list of pins or | 36 | of these subnodes represents muxing for a pin, a group, or a list of pins or |
37 | groups. | 37 | groups. |
38 | 38 | ||
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt index 2fb90b37aa09..a7bde64798c7 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt | |||
@@ -18,7 +18,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
18 | common pinctrl bindings used by client devices, including the meaning of the | 18 | common pinctrl bindings used by client devices, including the meaning of the |
19 | phrase "pin configuration node". | 19 | phrase "pin configuration node". |
20 | 20 | ||
21 | Qualcomm's pin configuration nodes act as a container for an abitrary number of | 21 | Qualcomm's pin configuration nodes act as a container for an arbitrary number of |
22 | subnodes. Each of these subnodes represents some desired configuration for a | 22 | subnodes. Each of these subnodes represents some desired configuration for a |
23 | pin, a group, or a list of pins or groups. This configuration can include the | 23 | pin, a group, or a list of pins or groups. This configuration can include the |
24 | mux function to select on those pin(s)/group(s), and various pin configuration | 24 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,apq8084-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,apq8084-pinctrl.txt index ffafa1990a30..c4ea61ac56f2 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,apq8084-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,apq8084-pinctrl.txt | |||
@@ -47,7 +47,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
47 | common pinctrl bindings used by client devices, including the meaning of the | 47 | common pinctrl bindings used by client devices, including the meaning of the |
48 | phrase "pin configuration node". | 48 | phrase "pin configuration node". |
49 | 49 | ||
50 | The pin configuration nodes act as a container for an abitrary number of | 50 | The pin configuration nodes act as a container for an arbitrary number of |
51 | subnodes. Each of these subnodes represents some desired configuration for a | 51 | subnodes. Each of these subnodes represents some desired configuration for a |
52 | pin, a group, or a list of pins or groups. This configuration can include the | 52 | pin, a group, or a list of pins or groups. This configuration can include the |
53 | mux function to select on those pin(s)/group(s), and various pin configuration | 53 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt index e33e4dcdce79..6e88e91feb11 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt | |||
@@ -18,7 +18,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
18 | common pinctrl bindings used by client devices, including the meaning of the | 18 | common pinctrl bindings used by client devices, including the meaning of the |
19 | phrase "pin configuration node". | 19 | phrase "pin configuration node". |
20 | 20 | ||
21 | Qualcomm's pin configuration nodes act as a container for an abitrary number of | 21 | Qualcomm's pin configuration nodes act as a container for an arbitrary number of |
22 | subnodes. Each of these subnodes represents some desired configuration for a | 22 | subnodes. Each of these subnodes represents some desired configuration for a |
23 | pin, a group, or a list of pins or groups. This configuration can include the | 23 | pin, a group, or a list of pins or groups. This configuration can include the |
24 | mux function to select on those pin(s)/group(s), and various pin configuration | 24 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt index 93b7de91b9f6..eb8d8aa41f20 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt | |||
@@ -47,7 +47,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
47 | common pinctrl bindings used by client devices, including the meaning of the | 47 | common pinctrl bindings used by client devices, including the meaning of the |
48 | phrase "pin configuration node". | 48 | phrase "pin configuration node". |
49 | 49 | ||
50 | The pin configuration nodes act as a container for an abitrary number of | 50 | The pin configuration nodes act as a container for an arbitrary number of |
51 | subnodes. Each of these subnodes represents some desired configuration for a | 51 | subnodes. Each of these subnodes represents some desired configuration for a |
52 | pin, a group, or a list of pins or groups. This configuration can include the | 52 | pin, a group, or a list of pins or groups. This configuration can include the |
53 | mux function to select on those pin(s)/group(s), and various pin configuration | 53 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt index d2ea80dc43eb..e4d6a9d20f7d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt | |||
@@ -18,7 +18,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the | |||
18 | common pinctrl bindings used by client devices, including the meaning of the | 18 | common pinctrl bindings used by client devices, including the meaning of the |
19 | phrase "pin configuration node". | 19 | phrase "pin configuration node". |
20 | 20 | ||
21 | Qualcomm's pin configuration nodes act as a container for an abitrary number of | 21 | Qualcomm's pin configuration nodes act as a container for an arbitrary number of |
22 | subnodes. Each of these subnodes represents some desired configuration for a | 22 | subnodes. Each of these subnodes represents some desired configuration for a |
23 | pin, a group, or a list of pins or groups. This configuration can include the | 23 | pin, a group, or a list of pins or groups. This configuration can include the |
24 | mux function to select on those pin(s)/group(s), and various pin configuration | 24 | mux function to select on those pin(s)/group(s), and various pin configuration |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 723999d73744..a344ec2713a5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -34,6 +34,7 @@ chipidea Chipidea, Inc | |||
34 | chrp Common Hardware Reference Platform | 34 | chrp Common Hardware Reference Platform |
35 | chunghwa Chunghwa Picture Tubes Ltd. | 35 | chunghwa Chunghwa Picture Tubes Ltd. |
36 | cirrus Cirrus Logic, Inc. | 36 | cirrus Cirrus Logic, Inc. |
37 | cnm Chips&Media, Inc. | ||
37 | cortina Cortina Systems, Inc. | 38 | cortina Cortina Systems, Inc. |
38 | crystalfontz Crystalfontz America, Inc. | 39 | crystalfontz Crystalfontz America, Inc. |
39 | dallas Maxim Integrated Products (formerly Dallas Semiconductor) | 40 | dallas Maxim Integrated Products (formerly Dallas Semiconductor) |
@@ -92,6 +93,7 @@ maxim Maxim Integrated Products | |||
92 | mediatek MediaTek Inc. | 93 | mediatek MediaTek Inc. |
93 | micrel Micrel Inc. | 94 | micrel Micrel Inc. |
94 | microchip Microchip Technology Inc. | 95 | microchip Microchip Technology Inc. |
96 | micron Micron Technology Inc. | ||
95 | mitsubishi Mitsubishi Electric Corporation | 97 | mitsubishi Mitsubishi Electric Corporation |
96 | mosaixtech Mosaix Technologies, Inc. | 98 | mosaixtech Mosaix Technologies, Inc. |
97 | moxa Moxa | 99 | moxa Moxa |
@@ -127,6 +129,7 @@ renesas Renesas Electronics Corporation | |||
127 | ricoh Ricoh Co. Ltd. | 129 | ricoh Ricoh Co. Ltd. |
128 | rockchip Fuzhou Rockchip Electronics Co., Ltd | 130 | rockchip Fuzhou Rockchip Electronics Co., Ltd |
129 | samsung Samsung Semiconductor | 131 | samsung Samsung Semiconductor |
132 | sandisk Sandisk Corporation | ||
130 | sbs Smart Battery System | 133 | sbs Smart Battery System |
131 | schindler Schindler | 134 | schindler Schindler |
132 | seagate Seagate Technology PLC | 135 | seagate Seagate Technology PLC |
@@ -138,7 +141,7 @@ silergy Silergy Corp. | |||
138 | sirf SiRF Technology, Inc. | 141 | sirf SiRF Technology, Inc. |
139 | sitronix Sitronix Technology Corporation | 142 | sitronix Sitronix Technology Corporation |
140 | smsc Standard Microsystems Corporation | 143 | smsc Standard Microsystems Corporation |
141 | snps Synopsys, Inc. | 144 | snps Synopsys, Inc. |
142 | solidrun SolidRun | 145 | solidrun SolidRun |
143 | sony Sony Corporation | 146 | sony Sony Corporation |
144 | spansion Spansion Inc. | 147 | spansion Spansion Inc. |
diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt index 530850a72735..a27c950ece61 100644 --- a/Documentation/filesystems/overlayfs.txt +++ b/Documentation/filesystems/overlayfs.txt | |||
@@ -64,7 +64,7 @@ is formed. | |||
64 | At mount time, the two directories given as mount options "lowerdir" and | 64 | At mount time, the two directories given as mount options "lowerdir" and |
65 | "upperdir" are combined into a merged directory: | 65 | "upperdir" are combined into a merged directory: |
66 | 66 | ||
67 | mount -t overlayfs overlayfs -olowerdir=/lower,upperdir=/upper,\ | 67 | mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\ |
68 | workdir=/work /merged | 68 | workdir=/work /merged |
69 | 69 | ||
70 | The "workdir" needs to be an empty directory on the same filesystem | 70 | The "workdir" needs to be an empty directory on the same filesystem |
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt index 412f45ca2d73..1d6d02d6ba52 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt | |||
@@ -136,7 +136,7 @@ SOF_TIMESTAMPING_OPT_ID: | |||
136 | 136 | ||
137 | This option is implemented only for transmit timestamps. There, the | 137 | This option is implemented only for transmit timestamps. There, the |
138 | timestamp is always looped along with a struct sock_extended_err. | 138 | timestamp is always looped along with a struct sock_extended_err. |
139 | The option modifies field ee_info to pass an id that is unique | 139 | The option modifies field ee_data to pass an id that is unique |
140 | among all possibly concurrently outstanding timestamp requests for | 140 | among all possibly concurrently outstanding timestamp requests for |
141 | that socket. In practice, it is a monotonically increasing u32 | 141 | that socket. In practice, it is a monotonically increasing u32 |
142 | (that wraps). | 142 | (that wraps). |
diff --git a/Documentation/sound/alsa/ControlNames.txt b/Documentation/sound/alsa/ControlNames.txt index fea65bb6269e..79a6127863ca 100644 --- a/Documentation/sound/alsa/ControlNames.txt +++ b/Documentation/sound/alsa/ControlNames.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | This document describes standard names of mixer controls. | 1 | This document describes standard names of mixer controls. |
2 | 2 | ||
3 | Syntax: SOURCE [DIRECTION] FUNCTION | 3 | Syntax: [LOCATION] SOURCE [CHANNEL] [DIRECTION] FUNCTION |
4 | 4 | ||
5 | DIRECTION: | 5 | DIRECTION: |
6 | <nothing> (both directions) | 6 | <nothing> (both directions) |
@@ -14,12 +14,29 @@ FUNCTION: | |||
14 | Volume | 14 | Volume |
15 | Route (route control, hardware specific) | 15 | Route (route control, hardware specific) |
16 | 16 | ||
17 | CHANNEL: | ||
18 | <nothing> (channel independent, or applies to all channels) | ||
19 | Front | ||
20 | Surround (rear left/right in 4.0/5.1 surround) | ||
21 | CLFE | ||
22 | Center | ||
23 | LFE | ||
24 | Side (side left/right for 7.1 surround) | ||
25 | |||
26 | LOCATION: (physical location of source) | ||
27 | Front | ||
28 | Rear | ||
29 | Dock (docking station) | ||
30 | Internal | ||
31 | |||
17 | SOURCE: | 32 | SOURCE: |
18 | Master | 33 | Master |
19 | Master Mono | 34 | Master Mono |
20 | Hardware Master | 35 | Hardware Master |
21 | Speaker (internal speaker) | 36 | Speaker (internal speaker) |
37 | Bass Speaker (internal LFE speaker) | ||
22 | Headphone | 38 | Headphone |
39 | Line Out | ||
23 | Beep (beep generator) | 40 | Beep (beep generator) |
24 | Phone | 41 | Phone |
25 | Phone Input | 42 | Phone Input |
@@ -27,14 +44,14 @@ SOURCE: | |||
27 | Synth | 44 | Synth |
28 | FM | 45 | FM |
29 | Mic | 46 | Mic |
30 | Line | 47 | Headset Mic (mic part of combined headset jack - 4-pin headphone + mic) |
48 | Headphone Mic (mic part of either/or - 3-pin headphone or mic) | ||
49 | Line (input only, use "Line Out" for output) | ||
31 | CD | 50 | CD |
32 | Video | 51 | Video |
33 | Zoom Video | 52 | Zoom Video |
34 | Aux | 53 | Aux |
35 | PCM | 54 | PCM |
36 | PCM Front | ||
37 | PCM Rear | ||
38 | PCM Pan | 55 | PCM Pan |
39 | Loopback | 56 | Loopback |
40 | Analog Loopback (D/A -> A/D loopback) | 57 | Analog Loopback (D/A -> A/D loopback) |
@@ -47,8 +64,13 @@ SOURCE: | |||
47 | Music | 64 | Music |
48 | I2S | 65 | I2S |
49 | IEC958 | 66 | IEC958 |
67 | HDMI | ||
68 | SPDIF (output only) | ||
69 | SPDIF In | ||
70 | Digital In | ||
71 | HDMI/DP (either HDMI or DisplayPort) | ||
50 | 72 | ||
51 | Exceptions: | 73 | Exceptions (deprecated): |
52 | [Digital] Capture Source | 74 | [Digital] Capture Source |
53 | [Digital] Capture Switch (aka input gain switch) | 75 | [Digital] Capture Switch (aka input gain switch) |
54 | [Digital] Capture Volume (aka input gain volume) | 76 | [Digital] Capture Volume (aka input gain volume) |
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt index 7fcd1ad96fcc..7f8a0d325905 100644 --- a/Documentation/sound/alsa/Procfile.txt +++ b/Documentation/sound/alsa/Procfile.txt | |||
@@ -101,10 +101,6 @@ card*/pcm*/xrun_debug | |||
101 | bit 0 = Enable XRUN/jiffies debug messages | 101 | bit 0 = Enable XRUN/jiffies debug messages |
102 | bit 1 = Show stack trace at XRUN / jiffies check | 102 | bit 1 = Show stack trace at XRUN / jiffies check |
103 | bit 2 = Enable additional jiffies check | 103 | bit 2 = Enable additional jiffies check |
104 | bit 3 = Log hwptr update at each period interrupt | ||
105 | bit 4 = Log hwptr update at each snd_pcm_update_hw_ptr() | ||
106 | bit 5 = Show last 10 positions on error | ||
107 | bit 6 = Do above only once | ||
108 | 104 | ||
109 | When the bit 0 is set, the driver will show the messages to | 105 | When the bit 0 is set, the driver will show the messages to |
110 | kernel log when an xrun is detected. The debug message is | 106 | kernel log when an xrun is detected. The debug message is |
@@ -121,15 +117,6 @@ card*/pcm*/xrun_debug | |||
121 | buggy) hardware that doesn't give smooth pointer updates. | 117 | buggy) hardware that doesn't give smooth pointer updates. |
122 | This feature is enabled via the bit 2. | 118 | This feature is enabled via the bit 2. |
123 | 119 | ||
124 | Bits 3 and 4 are for logging the hwptr records. Note that | ||
125 | these will give flood of kernel messages. | ||
126 | |||
127 | When bit 5 is set, the driver logs the last 10 xrun errors and | ||
128 | the proc file shows each jiffies, position, period_size, | ||
129 | buffer_size, old_hw_ptr, and hw_ptr_base values. | ||
130 | |||
131 | When bit 6 is set, the full xrun log is shown only once. | ||
132 | |||
133 | card*/pcm*/sub*/info | 120 | card*/pcm*/sub*/info |
134 | The general information of this PCM sub-stream. | 121 | The general information of this PCM sub-stream. |
135 | 122 | ||
@@ -146,6 +133,10 @@ card*/pcm*/sub*/sw_params | |||
146 | card*/pcm*/sub*/prealloc | 133 | card*/pcm*/sub*/prealloc |
147 | The buffer pre-allocation information. | 134 | The buffer pre-allocation information. |
148 | 135 | ||
136 | card*/pcm*/sub*/xrun_injection | ||
137 | Triggers an XRUN to the running stream when any value is | ||
138 | written to this proc file. Used for fault injection. | ||
139 | This entry is write-only. | ||
149 | 140 | ||
150 | AC97 Codec Information | 141 | AC97 Codec Information |
151 | ---------------------- | 142 | ---------------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index c444907ccd69..0ff630de8a6d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6888,11 +6888,12 @@ F: drivers/scsi/osd/ | |||
6888 | F: include/scsi/osd_* | 6888 | F: include/scsi/osd_* |
6889 | F: fs/exofs/ | 6889 | F: fs/exofs/ |
6890 | 6890 | ||
6891 | OVERLAYFS FILESYSTEM | 6891 | OVERLAY FILESYSTEM |
6892 | M: Miklos Szeredi <miklos@szeredi.hu> | 6892 | M: Miklos Szeredi <miklos@szeredi.hu> |
6893 | L: linux-fsdevel@vger.kernel.org | 6893 | L: linux-unionfs@vger.kernel.org |
6894 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git | ||
6894 | S: Supported | 6895 | S: Supported |
6895 | F: fs/overlayfs/* | 6896 | F: fs/overlayfs/ |
6896 | F: Documentation/filesystems/overlayfs.txt | 6897 | F: Documentation/filesystems/overlayfs.txt |
6897 | 6898 | ||
6898 | P54 WIRELESS DRIVER | 6899 | P54 WIRELESS DRIVER |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 18 | 2 | PATCHLEVEL = 18 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc5 | 4 | EXTRAVERSION = -rc7 |
5 | NAME = Diseased Newt | 5 | NAME = Diseased Newt |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index e51fcef884a4..60429ad1c5d8 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts | |||
@@ -624,4 +624,8 @@ | |||
624 | num-cs = <1>; | 624 | num-cs = <1>; |
625 | }; | 625 | }; |
626 | 626 | ||
627 | &usbdrd_dwc3 { | ||
628 | dr_mode = "host"; | ||
629 | }; | ||
630 | |||
627 | #include "cros-ec-keyboard.dtsi" | 631 | #include "cros-ec-keyboard.dtsi" |
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index f21b9aa00fbb..d55c1a2eb798 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi | |||
@@ -555,7 +555,7 @@ | |||
555 | #size-cells = <1>; | 555 | #size-cells = <1>; |
556 | ranges; | 556 | ranges; |
557 | 557 | ||
558 | dwc3 { | 558 | usbdrd_dwc3: dwc3 { |
559 | compatible = "synopsys,dwc3"; | 559 | compatible = "synopsys,dwc3"; |
560 | reg = <0x12000000 0x10000>; | 560 | reg = <0x12000000 0x10000>; |
561 | interrupts = <0 72 0>; | 561 | interrupts = <0 72 0>; |
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index d46c213a17ad..eed697a6bd6b 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi | |||
@@ -433,7 +433,7 @@ | |||
433 | clocks = <&cpg_clocks R8A7740_CLK_S>, | 433 | clocks = <&cpg_clocks R8A7740_CLK_S>, |
434 | <&cpg_clocks R8A7740_CLK_S>, <&sub_clk>, | 434 | <&cpg_clocks R8A7740_CLK_S>, <&sub_clk>, |
435 | <&cpg_clocks R8A7740_CLK_B>, | 435 | <&cpg_clocks R8A7740_CLK_B>, |
436 | <&sub_clk>, <&sub_clk>, | 436 | <&cpg_clocks R8A7740_CLK_HPP>, <&sub_clk>, |
437 | <&cpg_clocks R8A7740_CLK_B>; | 437 | <&cpg_clocks R8A7740_CLK_B>; |
438 | #clock-cells = <1>; | 438 | #clock-cells = <1>; |
439 | renesas,clock-indices = < | 439 | renesas,clock-indices = < |
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index d0e17733dc1a..e20affe156c1 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi | |||
@@ -666,9 +666,9 @@ | |||
666 | #clock-cells = <0>; | 666 | #clock-cells = <0>; |
667 | clock-output-names = "sd2"; | 667 | clock-output-names = "sd2"; |
668 | }; | 668 | }; |
669 | sd3_clk: sd3_clk@e615007c { | 669 | sd3_clk: sd3_clk@e615026c { |
670 | compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; | 670 | compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; |
671 | reg = <0 0xe615007c 0 4>; | 671 | reg = <0 0xe615026c 0 4>; |
672 | clocks = <&pll1_div2_clk>; | 672 | clocks = <&pll1_div2_clk>; |
673 | #clock-cells = <0>; | 673 | #clock-cells = <0>; |
674 | clock-output-names = "sd3"; | 674 | clock-output-names = "sd3"; |
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 543f895d18d3..2e652e2339e9 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi | |||
@@ -361,6 +361,10 @@ | |||
361 | clocks = <&ahb1_gates 6>; | 361 | clocks = <&ahb1_gates 6>; |
362 | resets = <&ahb1_rst 6>; | 362 | resets = <&ahb1_rst 6>; |
363 | #dma-cells = <1>; | 363 | #dma-cells = <1>; |
364 | |||
365 | /* DMA controller requires AHB1 clocked from PLL6 */ | ||
366 | assigned-clocks = <&ahb1_mux>; | ||
367 | assigned-clock-parents = <&pll6>; | ||
364 | }; | 368 | }; |
365 | 369 | ||
366 | mmc0: mmc@01c0f000 { | 370 | mmc0: mmc@01c0f000 { |
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index 5c21d216515a..8b7aa0dcdc6e 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts | |||
@@ -15,6 +15,7 @@ | |||
15 | aliases { | 15 | aliases { |
16 | rtc0 = "/i2c@7000d000/tps65913@58"; | 16 | rtc0 = "/i2c@7000d000/tps65913@58"; |
17 | rtc1 = "/rtc@7000e000"; | 17 | rtc1 = "/rtc@7000e000"; |
18 | serial0 = &uartd; | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | memory { | 21 | memory { |
diff --git a/arch/arm/boot/dts/tegra114-roth.dts b/arch/arm/boot/dts/tegra114-roth.dts index c7c6825f11fb..38acf78d7815 100644 --- a/arch/arm/boot/dts/tegra114-roth.dts +++ b/arch/arm/boot/dts/tegra114-roth.dts | |||
@@ -15,6 +15,10 @@ | |||
15 | linux,initrd-end = <0x82800000>; | 15 | linux,initrd-end = <0x82800000>; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | aliases { | ||
19 | serial0 = &uartd; | ||
20 | }; | ||
21 | |||
18 | firmware { | 22 | firmware { |
19 | trusted-foundations { | 23 | trusted-foundations { |
20 | compatible = "tlm,trusted-foundations"; | 24 | compatible = "tlm,trusted-foundations"; |
@@ -916,8 +920,6 @@ | |||
916 | regulator-name = "vddio-sdmmc3"; | 920 | regulator-name = "vddio-sdmmc3"; |
917 | regulator-min-microvolt = <1800000>; | 921 | regulator-min-microvolt = <1800000>; |
918 | regulator-max-microvolt = <3300000>; | 922 | regulator-max-microvolt = <3300000>; |
919 | regulator-always-on; | ||
920 | regulator-boot-on; | ||
921 | }; | 923 | }; |
922 | 924 | ||
923 | ldousb { | 925 | ldousb { |
@@ -962,7 +964,7 @@ | |||
962 | sdhci@78000400 { | 964 | sdhci@78000400 { |
963 | status = "okay"; | 965 | status = "okay"; |
964 | bus-width = <4>; | 966 | bus-width = <4>; |
965 | vmmc-supply = <&vddio_sdmmc3>; | 967 | vqmmc-supply = <&vddio_sdmmc3>; |
966 | cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; | 968 | cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; |
967 | power-gpios = <&gpio TEGRA_GPIO(H, 0) GPIO_ACTIVE_HIGH>; | 969 | power-gpios = <&gpio TEGRA_GPIO(H, 0) GPIO_ACTIVE_HIGH>; |
968 | }; | 970 | }; |
@@ -971,7 +973,6 @@ | |||
971 | sdhci@78000600 { | 973 | sdhci@78000600 { |
972 | status = "okay"; | 974 | status = "okay"; |
973 | bus-width = <8>; | 975 | bus-width = <8>; |
974 | vmmc-supply = <&vdd_1v8>; | ||
975 | non-removable; | 976 | non-removable; |
976 | }; | 977 | }; |
977 | 978 | ||
diff --git a/arch/arm/boot/dts/tegra114-tn7.dts b/arch/arm/boot/dts/tegra114-tn7.dts index 963662145635..f91c2c9b2f94 100644 --- a/arch/arm/boot/dts/tegra114-tn7.dts +++ b/arch/arm/boot/dts/tegra114-tn7.dts | |||
@@ -15,6 +15,10 @@ | |||
15 | linux,initrd-end = <0x82800000>; | 15 | linux,initrd-end = <0x82800000>; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | aliases { | ||
19 | serial0 = &uartd; | ||
20 | }; | ||
21 | |||
18 | firmware { | 22 | firmware { |
19 | trusted-foundations { | 23 | trusted-foundations { |
20 | compatible = "tlm,trusted-foundations"; | 24 | compatible = "tlm,trusted-foundations"; |
@@ -240,7 +244,6 @@ | |||
240 | sdhci@78000600 { | 244 | sdhci@78000600 { |
241 | status = "okay"; | 245 | status = "okay"; |
242 | bus-width = <8>; | 246 | bus-width = <8>; |
243 | vmmc-supply = <&vdd_1v8>; | ||
244 | non-removable; | 247 | non-removable; |
245 | }; | 248 | }; |
246 | 249 | ||
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 2ca9c1807f72..222f3b3f4dd5 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi | |||
@@ -9,13 +9,6 @@ | |||
9 | compatible = "nvidia,tegra114"; | 9 | compatible = "nvidia,tegra114"; |
10 | interrupt-parent = <&gic>; | 10 | interrupt-parent = <&gic>; |
11 | 11 | ||
12 | aliases { | ||
13 | serial0 = &uarta; | ||
14 | serial1 = &uartb; | ||
15 | serial2 = &uartc; | ||
16 | serial3 = &uartd; | ||
17 | }; | ||
18 | |||
19 | host1x@50000000 { | 12 | host1x@50000000 { |
20 | compatible = "nvidia,tegra114-host1x", "simple-bus"; | 13 | compatible = "nvidia,tegra114-host1x", "simple-bus"; |
21 | reg = <0x50000000 0x00028000>; | 14 | reg = <0x50000000 0x00028000>; |
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 029c9a021541..51b373ff1065 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@0,7000d000/pmic@40"; | 11 | rtc0 = "/i2c@0,7000d000/pmic@40"; |
12 | rtc1 = "/rtc@0,7000e000"; | 12 | rtc1 = "/rtc@0,7000e000"; |
13 | serial0 = &uartd; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts index 7d0784ce4c74..53181d310247 100644 --- a/arch/arm/boot/dts/tegra124-nyan-big.dts +++ b/arch/arm/boot/dts/tegra124-nyan-big.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@0,7000d000/pmic@40"; | 11 | rtc0 = "/i2c@0,7000d000/pmic@40"; |
12 | rtc1 = "/rtc@0,7000e000"; | 12 | rtc1 = "/rtc@0,7000e000"; |
13 | serial0 = &uarta; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts index 13008858e967..5c3f7813360d 100644 --- a/arch/arm/boot/dts/tegra124-venice2.dts +++ b/arch/arm/boot/dts/tegra124-venice2.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@0,7000d000/pmic@40"; | 11 | rtc0 = "/i2c@0,7000d000/pmic@40"; |
12 | rtc1 = "/rtc@0,7000e000"; | 12 | rtc1 = "/rtc@0,7000e000"; |
13 | serial0 = &uarta; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 478c555ebd96..df2b06b29985 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi | |||
@@ -286,7 +286,7 @@ | |||
286 | * the APB DMA based serial driver, the comptible is | 286 | * the APB DMA based serial driver, the comptible is |
287 | * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart". | 287 | * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart". |
288 | */ | 288 | */ |
289 | serial@0,70006000 { | 289 | uarta: serial@0,70006000 { |
290 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; | 290 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; |
291 | reg = <0x0 0x70006000 0x0 0x40>; | 291 | reg = <0x0 0x70006000 0x0 0x40>; |
292 | reg-shift = <2>; | 292 | reg-shift = <2>; |
@@ -299,7 +299,7 @@ | |||
299 | status = "disabled"; | 299 | status = "disabled"; |
300 | }; | 300 | }; |
301 | 301 | ||
302 | serial@0,70006040 { | 302 | uartb: serial@0,70006040 { |
303 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; | 303 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; |
304 | reg = <0x0 0x70006040 0x0 0x40>; | 304 | reg = <0x0 0x70006040 0x0 0x40>; |
305 | reg-shift = <2>; | 305 | reg-shift = <2>; |
@@ -312,7 +312,7 @@ | |||
312 | status = "disabled"; | 312 | status = "disabled"; |
313 | }; | 313 | }; |
314 | 314 | ||
315 | serial@0,70006200 { | 315 | uartc: serial@0,70006200 { |
316 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; | 316 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; |
317 | reg = <0x0 0x70006200 0x0 0x40>; | 317 | reg = <0x0 0x70006200 0x0 0x40>; |
318 | reg-shift = <2>; | 318 | reg-shift = <2>; |
@@ -325,7 +325,7 @@ | |||
325 | status = "disabled"; | 325 | status = "disabled"; |
326 | }; | 326 | }; |
327 | 327 | ||
328 | serial@0,70006300 { | 328 | uartd: serial@0,70006300 { |
329 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; | 329 | compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; |
330 | reg = <0x0 0x70006300 0x0 0x40>; | 330 | reg = <0x0 0x70006300 0x0 0x40>; |
331 | reg-shift = <2>; | 331 | reg-shift = <2>; |
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts index a37279af687c..b926a07b9443 100644 --- a/arch/arm/boot/dts/tegra20-harmony.dts +++ b/arch/arm/boot/dts/tegra20-harmony.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@7000d000/tps6586x@34"; | 11 | rtc0 = "/i2c@7000d000/tps6586x@34"; |
12 | rtc1 = "/rtc@7000e000"; | 12 | rtc1 = "/rtc@7000e000"; |
13 | serial0 = &uartd; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra20-iris-512.dts b/arch/arm/boot/dts/tegra20-iris-512.dts index 8cfb83f42e1f..1dd7d7bfdfcc 100644 --- a/arch/arm/boot/dts/tegra20-iris-512.dts +++ b/arch/arm/boot/dts/tegra20-iris-512.dts | |||
@@ -6,6 +6,11 @@ | |||
6 | model = "Toradex Colibri T20 512MB on Iris"; | 6 | model = "Toradex Colibri T20 512MB on Iris"; |
7 | compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20"; | 7 | compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20"; |
8 | 8 | ||
9 | aliases { | ||
10 | serial0 = &uarta; | ||
11 | serial1 = &uartd; | ||
12 | }; | ||
13 | |||
9 | host1x@50000000 { | 14 | host1x@50000000 { |
10 | hdmi@54280000 { | 15 | hdmi@54280000 { |
11 | status = "okay"; | 16 | status = "okay"; |
diff --git a/arch/arm/boot/dts/tegra20-medcom-wide.dts b/arch/arm/boot/dts/tegra20-medcom-wide.dts index 1b7c56b33aca..9b87526ab0b7 100644 --- a/arch/arm/boot/dts/tegra20-medcom-wide.dts +++ b/arch/arm/boot/dts/tegra20-medcom-wide.dts | |||
@@ -6,6 +6,10 @@ | |||
6 | model = "Avionic Design Medcom-Wide board"; | 6 | model = "Avionic Design Medcom-Wide board"; |
7 | compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20"; | 7 | compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20"; |
8 | 8 | ||
9 | aliases { | ||
10 | serial0 = &uartd; | ||
11 | }; | ||
12 | |||
9 | pwm@7000a000 { | 13 | pwm@7000a000 { |
10 | status = "okay"; | 14 | status = "okay"; |
11 | }; | 15 | }; |
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index d4438e30de45..ed7e1009326c 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts | |||
@@ -10,6 +10,8 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@7000d000/tps6586x@34"; | 11 | rtc0 = "/i2c@7000d000/tps6586x@34"; |
12 | rtc1 = "/rtc@7000e000"; | 12 | rtc1 = "/rtc@7000e000"; |
13 | serial0 = &uarta; | ||
14 | serial1 = &uartc; | ||
13 | }; | 15 | }; |
14 | 16 | ||
15 | memory { | 17 | memory { |
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index a1d4bf9895d7..ea282c7c0ca5 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@7000d000/tps6586x@34"; | 11 | rtc0 = "/i2c@7000d000/tps6586x@34"; |
12 | rtc1 = "/rtc@7000e000"; | 12 | rtc1 = "/rtc@7000e000"; |
13 | serial0 = &uartd; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi index 80e7d386ce34..13d4e6185275 100644 --- a/arch/arm/boot/dts/tegra20-tamonten.dtsi +++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi | |||
@@ -7,6 +7,7 @@ | |||
7 | aliases { | 7 | aliases { |
8 | rtc0 = "/i2c@7000d000/tps6586x@34"; | 8 | rtc0 = "/i2c@7000d000/tps6586x@34"; |
9 | rtc1 = "/rtc@7000e000"; | 9 | rtc1 = "/rtc@7000e000"; |
10 | serial0 = &uartd; | ||
10 | }; | 11 | }; |
11 | 12 | ||
12 | memory { | 13 | memory { |
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts index 5ad87979ab13..d99af4ef9c64 100644 --- a/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/arch/arm/boot/dts/tegra20-trimslice.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@7000c500/rtc@56"; | 11 | rtc0 = "/i2c@7000c500/rtc@56"; |
12 | rtc1 = "/rtc@7000e000"; | 12 | rtc1 = "/rtc@7000e000"; |
13 | serial0 = &uarta; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts index ca8484cccddc..04c58e9ca490 100644 --- a/arch/arm/boot/dts/tegra20-ventana.dts +++ b/arch/arm/boot/dts/tegra20-ventana.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@7000d000/tps6586x@34"; | 11 | rtc0 = "/i2c@7000d000/tps6586x@34"; |
12 | rtc1 = "/rtc@7000e000"; | 12 | rtc1 = "/rtc@7000e000"; |
13 | serial0 = &uartd; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts index 1843725785c9..340d81108df1 100644 --- a/arch/arm/boot/dts/tegra20-whistler.dts +++ b/arch/arm/boot/dts/tegra20-whistler.dts | |||
@@ -10,6 +10,7 @@ | |||
10 | aliases { | 10 | aliases { |
11 | rtc0 = "/i2c@7000d000/max8907@3c"; | 11 | rtc0 = "/i2c@7000d000/max8907@3c"; |
12 | rtc1 = "/rtc@7000e000"; | 12 | rtc1 = "/rtc@7000e000"; |
13 | serial0 = &uarta; | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | memory { | 16 | memory { |
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 3b374c49d04d..8acf5d85c99d 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
@@ -9,14 +9,6 @@ | |||
9 | compatible = "nvidia,tegra20"; | 9 | compatible = "nvidia,tegra20"; |
10 | interrupt-parent = <&intc>; | 10 | interrupt-parent = <&intc>; |
11 | 11 | ||
12 | aliases { | ||
13 | serial0 = &uarta; | ||
14 | serial1 = &uartb; | ||
15 | serial2 = &uartc; | ||
16 | serial3 = &uartd; | ||
17 | serial4 = &uarte; | ||
18 | }; | ||
19 | |||
20 | host1x@50000000 { | 12 | host1x@50000000 { |
21 | compatible = "nvidia,tegra20-host1x", "simple-bus"; | 13 | compatible = "nvidia,tegra20-host1x", "simple-bus"; |
22 | reg = <0x50000000 0x00024000>; | 14 | reg = <0x50000000 0x00024000>; |
diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts index 45d40f024585..6236bdecb48b 100644 --- a/arch/arm/boot/dts/tegra30-apalis-eval.dts +++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts | |||
@@ -11,6 +11,10 @@ | |||
11 | rtc0 = "/i2c@7000c000/rtc@68"; | 11 | rtc0 = "/i2c@7000c000/rtc@68"; |
12 | rtc1 = "/i2c@7000d000/tps65911@2d"; | 12 | rtc1 = "/i2c@7000d000/tps65911@2d"; |
13 | rtc2 = "/rtc@7000e000"; | 13 | rtc2 = "/rtc@7000e000"; |
14 | serial0 = &uarta; | ||
15 | serial1 = &uartb; | ||
16 | serial2 = &uartc; | ||
17 | serial3 = &uartd; | ||
14 | }; | 18 | }; |
15 | 19 | ||
16 | pcie-controller@00003000 { | 20 | pcie-controller@00003000 { |
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts index cee8f2246fdb..6b157eeabcc5 100644 --- a/arch/arm/boot/dts/tegra30-beaver.dts +++ b/arch/arm/boot/dts/tegra30-beaver.dts | |||
@@ -9,6 +9,7 @@ | |||
9 | aliases { | 9 | aliases { |
10 | rtc0 = "/i2c@7000d000/tps65911@2d"; | 10 | rtc0 = "/i2c@7000d000/tps65911@2d"; |
11 | rtc1 = "/rtc@7000e000"; | 11 | rtc1 = "/rtc@7000e000"; |
12 | serial0 = &uarta; | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | memory { | 15 | memory { |
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index 206379546244..a1b682ea01bd 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi | |||
@@ -30,6 +30,8 @@ | |||
30 | aliases { | 30 | aliases { |
31 | rtc0 = "/i2c@7000d000/tps65911@2d"; | 31 | rtc0 = "/i2c@7000d000/tps65911@2d"; |
32 | rtc1 = "/rtc@7000e000"; | 32 | rtc1 = "/rtc@7000e000"; |
33 | serial0 = &uarta; | ||
34 | serial1 = &uartc; | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | memory { | 37 | memory { |
diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts index 7793abd5bef1..4d3ddc585641 100644 --- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts | |||
@@ -10,6 +10,9 @@ | |||
10 | rtc0 = "/i2c@7000c000/rtc@68"; | 10 | rtc0 = "/i2c@7000c000/rtc@68"; |
11 | rtc1 = "/i2c@7000d000/tps65911@2d"; | 11 | rtc1 = "/i2c@7000d000/tps65911@2d"; |
12 | rtc2 = "/rtc@7000e000"; | 12 | rtc2 = "/rtc@7000e000"; |
13 | serial0 = &uarta; | ||
14 | serial1 = &uartb; | ||
15 | serial2 = &uartd; | ||
13 | }; | 16 | }; |
14 | 17 | ||
15 | host1x@50000000 { | 18 | host1x@50000000 { |
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index aa6ccea13d30..b270b9e3d455 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi | |||
@@ -9,14 +9,6 @@ | |||
9 | compatible = "nvidia,tegra30"; | 9 | compatible = "nvidia,tegra30"; |
10 | interrupt-parent = <&intc>; | 10 | interrupt-parent = <&intc>; |
11 | 11 | ||
12 | aliases { | ||
13 | serial0 = &uarta; | ||
14 | serial1 = &uartb; | ||
15 | serial2 = &uartc; | ||
16 | serial3 = &uartd; | ||
17 | serial4 = &uarte; | ||
18 | }; | ||
19 | |||
20 | pcie-controller@00003000 { | 12 | pcie-controller@00003000 { |
21 | compatible = "nvidia,tegra30-pcie"; | 13 | compatible = "nvidia,tegra30-pcie"; |
22 | device_type = "pci"; | 14 | device_type = "pci"; |
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 72058b8a6f4d..e21ef830a483 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig | |||
@@ -142,11 +142,13 @@ CONFIG_MMC_DW_IDMAC=y | |||
142 | CONFIG_MMC_DW_EXYNOS=y | 142 | CONFIG_MMC_DW_EXYNOS=y |
143 | CONFIG_RTC_CLASS=y | 143 | CONFIG_RTC_CLASS=y |
144 | CONFIG_RTC_DRV_MAX77686=y | 144 | CONFIG_RTC_DRV_MAX77686=y |
145 | CONFIG_RTC_DRV_MAX77802=y | ||
145 | CONFIG_RTC_DRV_S5M=y | 146 | CONFIG_RTC_DRV_S5M=y |
146 | CONFIG_RTC_DRV_S3C=y | 147 | CONFIG_RTC_DRV_S3C=y |
147 | CONFIG_DMADEVICES=y | 148 | CONFIG_DMADEVICES=y |
148 | CONFIG_PL330_DMA=y | 149 | CONFIG_PL330_DMA=y |
149 | CONFIG_COMMON_CLK_MAX77686=y | 150 | CONFIG_COMMON_CLK_MAX77686=y |
151 | CONFIG_COMMON_CLK_MAX77802=y | ||
150 | CONFIG_COMMON_CLK_S2MPS11=y | 152 | CONFIG_COMMON_CLK_S2MPS11=y |
151 | CONFIG_EXYNOS_IOMMU=y | 153 | CONFIG_EXYNOS_IOMMU=y |
152 | CONFIG_IIO=y | 154 | CONFIG_IIO=y |
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 3487046d8a78..9d7a32f93fcf 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig | |||
@@ -217,6 +217,7 @@ CONFIG_I2C_CADENCE=y | |||
217 | CONFIG_I2C_DESIGNWARE_PLATFORM=y | 217 | CONFIG_I2C_DESIGNWARE_PLATFORM=y |
218 | CONFIG_I2C_EXYNOS5=y | 218 | CONFIG_I2C_EXYNOS5=y |
219 | CONFIG_I2C_MV64XXX=y | 219 | CONFIG_I2C_MV64XXX=y |
220 | CONFIG_I2C_S3C2410=y | ||
220 | CONFIG_I2C_SIRF=y | 221 | CONFIG_I2C_SIRF=y |
221 | CONFIG_I2C_TEGRA=y | 222 | CONFIG_I2C_TEGRA=y |
222 | CONFIG_I2C_ST=y | 223 | CONFIG_I2C_ST=y |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index fc44d3761f9e..ce73ab635414 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -44,16 +44,6 @@ struct cpu_context_save { | |||
44 | __u32 extra[2]; /* Xscale 'acc' register, etc */ | 44 | __u32 extra[2]; /* Xscale 'acc' register, etc */ |
45 | }; | 45 | }; |
46 | 46 | ||
47 | struct arm_restart_block { | ||
48 | union { | ||
49 | /* For user cache flushing */ | ||
50 | struct { | ||
51 | unsigned long start; | ||
52 | unsigned long end; | ||
53 | } cache; | ||
54 | }; | ||
55 | }; | ||
56 | |||
57 | /* | 47 | /* |
58 | * low level task data that entry.S needs immediate access to. | 48 | * low level task data that entry.S needs immediate access to. |
59 | * __switch_to() assumes cpu_context follows immediately after cpu_domain. | 49 | * __switch_to() assumes cpu_context follows immediately after cpu_domain. |
@@ -79,7 +69,6 @@ struct thread_info { | |||
79 | unsigned long thumbee_state; /* ThumbEE Handler Base register */ | 69 | unsigned long thumbee_state; /* ThumbEE Handler Base register */ |
80 | #endif | 70 | #endif |
81 | struct restart_block restart_block; | 71 | struct restart_block restart_block; |
82 | struct arm_restart_block arm_restart_block; | ||
83 | }; | 72 | }; |
84 | 73 | ||
85 | #define INIT_THREAD_INFO(tsk) \ | 74 | #define INIT_THREAD_INFO(tsk) \ |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 0c8b10801d36..9f5d81881eb6 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -533,8 +533,6 @@ static int bad_syscall(int n, struct pt_regs *regs) | |||
533 | return regs->ARM_r0; | 533 | return regs->ARM_r0; |
534 | } | 534 | } |
535 | 535 | ||
536 | static long do_cache_op_restart(struct restart_block *); | ||
537 | |||
538 | static inline int | 536 | static inline int |
539 | __do_cache_op(unsigned long start, unsigned long end) | 537 | __do_cache_op(unsigned long start, unsigned long end) |
540 | { | 538 | { |
@@ -543,24 +541,8 @@ __do_cache_op(unsigned long start, unsigned long end) | |||
543 | do { | 541 | do { |
544 | unsigned long chunk = min(PAGE_SIZE, end - start); | 542 | unsigned long chunk = min(PAGE_SIZE, end - start); |
545 | 543 | ||
546 | if (signal_pending(current)) { | 544 | if (fatal_signal_pending(current)) |
547 | struct thread_info *ti = current_thread_info(); | 545 | return 0; |
548 | |||
549 | ti->restart_block = (struct restart_block) { | ||
550 | .fn = do_cache_op_restart, | ||
551 | }; | ||
552 | |||
553 | ti->arm_restart_block = (struct arm_restart_block) { | ||
554 | { | ||
555 | .cache = { | ||
556 | .start = start, | ||
557 | .end = end, | ||
558 | }, | ||
559 | }, | ||
560 | }; | ||
561 | |||
562 | return -ERESTART_RESTARTBLOCK; | ||
563 | } | ||
564 | 546 | ||
565 | ret = flush_cache_user_range(start, start + chunk); | 547 | ret = flush_cache_user_range(start, start + chunk); |
566 | if (ret) | 548 | if (ret) |
@@ -573,15 +555,6 @@ __do_cache_op(unsigned long start, unsigned long end) | |||
573 | return 0; | 555 | return 0; |
574 | } | 556 | } |
575 | 557 | ||
576 | static long do_cache_op_restart(struct restart_block *unused) | ||
577 | { | ||
578 | struct arm_restart_block *restart_block; | ||
579 | |||
580 | restart_block = ¤t_thread_info()->arm_restart_block; | ||
581 | return __do_cache_op(restart_block->cache.start, | ||
582 | restart_block->cache.end); | ||
583 | } | ||
584 | |||
585 | static inline int | 558 | static inline int |
586 | do_cache_op(unsigned long start, unsigned long end, int flags) | 559 | do_cache_op(unsigned long start, unsigned long end, int flags) |
587 | { | 560 | { |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 57a403a5c22b..8664ff17cbbe 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -197,7 +197,8 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | |||
197 | pgd = pgdp + pgd_index(addr); | 197 | pgd = pgdp + pgd_index(addr); |
198 | do { | 198 | do { |
199 | next = kvm_pgd_addr_end(addr, end); | 199 | next = kvm_pgd_addr_end(addr, end); |
200 | unmap_puds(kvm, pgd, addr, next); | 200 | if (!pgd_none(*pgd)) |
201 | unmap_puds(kvm, pgd, addr, next); | ||
201 | } while (pgd++, addr = next, addr != end); | 202 | } while (pgd++, addr = next, addr != end); |
202 | } | 203 | } |
203 | 204 | ||
@@ -834,6 +835,11 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | |||
834 | return kvm_vcpu_dabt_iswrite(vcpu); | 835 | return kvm_vcpu_dabt_iswrite(vcpu); |
835 | } | 836 | } |
836 | 837 | ||
838 | static bool kvm_is_device_pfn(unsigned long pfn) | ||
839 | { | ||
840 | return !pfn_valid(pfn); | ||
841 | } | ||
842 | |||
837 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | 843 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, |
838 | struct kvm_memory_slot *memslot, unsigned long hva, | 844 | struct kvm_memory_slot *memslot, unsigned long hva, |
839 | unsigned long fault_status) | 845 | unsigned long fault_status) |
@@ -904,7 +910,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
904 | if (is_error_pfn(pfn)) | 910 | if (is_error_pfn(pfn)) |
905 | return -EFAULT; | 911 | return -EFAULT; |
906 | 912 | ||
907 | if (kvm_is_mmio_pfn(pfn)) | 913 | if (kvm_is_device_pfn(pfn)) |
908 | mem_type = PAGE_S2_DEVICE; | 914 | mem_type = PAGE_S2_DEVICE; |
909 | 915 | ||
910 | spin_lock(&kvm->mmu_lock); | 916 | spin_lock(&kvm->mmu_lock); |
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 2bdc3233abe2..044b51185fcc 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c | |||
@@ -400,6 +400,8 @@ int __init coherency_init(void) | |||
400 | type == COHERENCY_FABRIC_TYPE_ARMADA_380) | 400 | type == COHERENCY_FABRIC_TYPE_ARMADA_380) |
401 | armada_375_380_coherency_init(np); | 401 | armada_375_380_coherency_init(np); |
402 | 402 | ||
403 | of_node_put(np); | ||
404 | |||
403 | return 0; | 405 | return 0; |
404 | } | 406 | } |
405 | 407 | ||
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index 0794f0426e70..19df9cb30495 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c | |||
@@ -455,7 +455,7 @@ enum { | |||
455 | MSTP128, MSTP127, MSTP125, | 455 | MSTP128, MSTP127, MSTP125, |
456 | MSTP116, MSTP111, MSTP100, MSTP117, | 456 | MSTP116, MSTP111, MSTP100, MSTP117, |
457 | 457 | ||
458 | MSTP230, | 458 | MSTP230, MSTP229, |
459 | MSTP222, | 459 | MSTP222, |
460 | MSTP218, MSTP217, MSTP216, MSTP214, | 460 | MSTP218, MSTP217, MSTP216, MSTP214, |
461 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 461 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
@@ -474,11 +474,12 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
474 | [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */ | 474 | [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */ |
475 | [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ | 475 | [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ |
476 | [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ | 476 | [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ |
477 | [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ | 477 | [MSTP116] = SH_CLK_MSTP32(&div4_clks[DIV4_HPP], SMSTPCR1, 16, 0), /* IIC0 */ |
478 | [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */ | 478 | [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */ |
479 | [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ | 479 | [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ |
480 | 480 | ||
481 | [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ | 481 | [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ |
482 | [MSTP229] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 29, 0), /* INTCA */ | ||
482 | [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ | 483 | [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ |
483 | [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ | 484 | [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ |
484 | [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ | 485 | [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ |
@@ -575,6 +576,10 @@ static struct clk_lookup lookups[] = { | |||
575 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), | 576 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), |
576 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), | 577 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), |
577 | CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP222]), | 578 | CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP222]), |
579 | CLKDEV_DEV_ID("renesas_intc_irqpin.0", &mstp_clks[MSTP229]), | ||
580 | CLKDEV_DEV_ID("renesas_intc_irqpin.1", &mstp_clks[MSTP229]), | ||
581 | CLKDEV_DEV_ID("renesas_intc_irqpin.2", &mstp_clks[MSTP229]), | ||
582 | CLKDEV_DEV_ID("renesas_intc_irqpin.3", &mstp_clks[MSTP229]), | ||
578 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), | 583 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), |
579 | CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP230]), | 584 | CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP230]), |
580 | 585 | ||
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 126ddafad526..f62265200592 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c | |||
@@ -68,7 +68,7 @@ | |||
68 | 68 | ||
69 | #define SDCKCR 0xE6150074 | 69 | #define SDCKCR 0xE6150074 |
70 | #define SD2CKCR 0xE6150078 | 70 | #define SD2CKCR 0xE6150078 |
71 | #define SD3CKCR 0xE615007C | 71 | #define SD3CKCR 0xE615026C |
72 | #define MMC0CKCR 0xE6150240 | 72 | #define MMC0CKCR 0xE6150240 |
73 | #define MMC1CKCR 0xE6150244 | 73 | #define MMC1CKCR 0xE6150244 |
74 | #define SSPCKCR 0xE6150248 | 74 | #define SSPCKCR 0xE6150248 |
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index b7bd8e509668..328657d011d5 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/i2c/i2c-sh_mobile.h> | ||
29 | #include <linux/io.h> | 30 | #include <linux/io.h> |
30 | #include <linux/serial_sci.h> | 31 | #include <linux/serial_sci.h> |
31 | #include <linux/sh_dma.h> | 32 | #include <linux/sh_dma.h> |
@@ -192,11 +193,18 @@ static struct resource i2c4_resources[] = { | |||
192 | }, | 193 | }, |
193 | }; | 194 | }; |
194 | 195 | ||
196 | static struct i2c_sh_mobile_platform_data i2c_platform_data = { | ||
197 | .clks_per_count = 2, | ||
198 | }; | ||
199 | |||
195 | static struct platform_device i2c0_device = { | 200 | static struct platform_device i2c0_device = { |
196 | .name = "i2c-sh_mobile", | 201 | .name = "i2c-sh_mobile", |
197 | .id = 0, | 202 | .id = 0, |
198 | .resource = i2c0_resources, | 203 | .resource = i2c0_resources, |
199 | .num_resources = ARRAY_SIZE(i2c0_resources), | 204 | .num_resources = ARRAY_SIZE(i2c0_resources), |
205 | .dev = { | ||
206 | .platform_data = &i2c_platform_data, | ||
207 | }, | ||
200 | }; | 208 | }; |
201 | 209 | ||
202 | static struct platform_device i2c1_device = { | 210 | static struct platform_device i2c1_device = { |
@@ -204,6 +212,9 @@ static struct platform_device i2c1_device = { | |||
204 | .id = 1, | 212 | .id = 1, |
205 | .resource = i2c1_resources, | 213 | .resource = i2c1_resources, |
206 | .num_resources = ARRAY_SIZE(i2c1_resources), | 214 | .num_resources = ARRAY_SIZE(i2c1_resources), |
215 | .dev = { | ||
216 | .platform_data = &i2c_platform_data, | ||
217 | }, | ||
207 | }; | 218 | }; |
208 | 219 | ||
209 | static struct platform_device i2c2_device = { | 220 | static struct platform_device i2c2_device = { |
@@ -211,6 +222,9 @@ static struct platform_device i2c2_device = { | |||
211 | .id = 2, | 222 | .id = 2, |
212 | .resource = i2c2_resources, | 223 | .resource = i2c2_resources, |
213 | .num_resources = ARRAY_SIZE(i2c2_resources), | 224 | .num_resources = ARRAY_SIZE(i2c2_resources), |
225 | .dev = { | ||
226 | .platform_data = &i2c_platform_data, | ||
227 | }, | ||
214 | }; | 228 | }; |
215 | 229 | ||
216 | static struct platform_device i2c3_device = { | 230 | static struct platform_device i2c3_device = { |
@@ -218,6 +232,9 @@ static struct platform_device i2c3_device = { | |||
218 | .id = 3, | 232 | .id = 3, |
219 | .resource = i2c3_resources, | 233 | .resource = i2c3_resources, |
220 | .num_resources = ARRAY_SIZE(i2c3_resources), | 234 | .num_resources = ARRAY_SIZE(i2c3_resources), |
235 | .dev = { | ||
236 | .platform_data = &i2c_platform_data, | ||
237 | }, | ||
221 | }; | 238 | }; |
222 | 239 | ||
223 | static struct platform_device i2c4_device = { | 240 | static struct platform_device i2c4_device = { |
@@ -225,6 +242,9 @@ static struct platform_device i2c4_device = { | |||
225 | .id = 4, | 242 | .id = 4, |
226 | .resource = i2c4_resources, | 243 | .resource = i2c4_resources, |
227 | .num_resources = ARRAY_SIZE(i2c4_resources), | 244 | .num_resources = ARRAY_SIZE(i2c4_resources), |
245 | .dev = { | ||
246 | .platform_data = &i2c_platform_data, | ||
247 | }, | ||
228 | }; | 248 | }; |
229 | 249 | ||
230 | static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = { | 250 | static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = { |
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index da7be13aecce..ab95f5391a2b 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c | |||
@@ -99,42 +99,42 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) | |||
99 | 99 | ||
100 | static void tegra_mask(struct irq_data *d) | 100 | static void tegra_mask(struct irq_data *d) |
101 | { | 101 | { |
102 | if (d->irq < FIRST_LEGACY_IRQ) | 102 | if (d->hwirq < FIRST_LEGACY_IRQ) |
103 | return; | 103 | return; |
104 | 104 | ||
105 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR); | 105 | tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_CLR); |
106 | } | 106 | } |
107 | 107 | ||
108 | static void tegra_unmask(struct irq_data *d) | 108 | static void tegra_unmask(struct irq_data *d) |
109 | { | 109 | { |
110 | if (d->irq < FIRST_LEGACY_IRQ) | 110 | if (d->hwirq < FIRST_LEGACY_IRQ) |
111 | return; | 111 | return; |
112 | 112 | ||
113 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET); | 113 | tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_SET); |
114 | } | 114 | } |
115 | 115 | ||
116 | static void tegra_ack(struct irq_data *d) | 116 | static void tegra_ack(struct irq_data *d) |
117 | { | 117 | { |
118 | if (d->irq < FIRST_LEGACY_IRQ) | 118 | if (d->hwirq < FIRST_LEGACY_IRQ) |
119 | return; | 119 | return; |
120 | 120 | ||
121 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); | 121 | tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR); |
122 | } | 122 | } |
123 | 123 | ||
124 | static void tegra_eoi(struct irq_data *d) | 124 | static void tegra_eoi(struct irq_data *d) |
125 | { | 125 | { |
126 | if (d->irq < FIRST_LEGACY_IRQ) | 126 | if (d->hwirq < FIRST_LEGACY_IRQ) |
127 | return; | 127 | return; |
128 | 128 | ||
129 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); | 129 | tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR); |
130 | } | 130 | } |
131 | 131 | ||
132 | static int tegra_retrigger(struct irq_data *d) | 132 | static int tegra_retrigger(struct irq_data *d) |
133 | { | 133 | { |
134 | if (d->irq < FIRST_LEGACY_IRQ) | 134 | if (d->hwirq < FIRST_LEGACY_IRQ) |
135 | return 0; | 135 | return 0; |
136 | 136 | ||
137 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET); | 137 | tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_SET); |
138 | 138 | ||
139 | return 1; | 139 | return 1; |
140 | } | 140 | } |
@@ -142,7 +142,7 @@ static int tegra_retrigger(struct irq_data *d) | |||
142 | #ifdef CONFIG_PM_SLEEP | 142 | #ifdef CONFIG_PM_SLEEP |
143 | static int tegra_set_wake(struct irq_data *d, unsigned int enable) | 143 | static int tegra_set_wake(struct irq_data *d, unsigned int enable) |
144 | { | 144 | { |
145 | u32 irq = d->irq; | 145 | u32 irq = d->hwirq; |
146 | u32 index, mask; | 146 | u32 index, mask; |
147 | 147 | ||
148 | if (irq < FIRST_LEGACY_IRQ || | 148 | if (irq < FIRST_LEGACY_IRQ || |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index b3a947863ac7..22ac2a6fbfe3 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -270,7 +270,6 @@ __v7_pj4b_setup: | |||
270 | /* Auxiliary Debug Modes Control 1 Register */ | 270 | /* Auxiliary Debug Modes Control 1 Register */ |
271 | #define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */ | 271 | #define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */ |
272 | #define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */ | 272 | #define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */ |
273 | #define PJ4B_BCK_OFF_STREX (1 << 5) /* Enable the back off of STREX instr */ | ||
274 | #define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */ | 273 | #define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */ |
275 | 274 | ||
276 | /* Auxiliary Debug Modes Control 2 Register */ | 275 | /* Auxiliary Debug Modes Control 2 Register */ |
@@ -293,7 +292,6 @@ __v7_pj4b_setup: | |||
293 | /* Auxiliary Debug Modes Control 1 Register */ | 292 | /* Auxiliary Debug Modes Control 1 Register */ |
294 | mrc p15, 1, r0, c15, c1, 1 | 293 | mrc p15, 1, r0, c15, c1, 1 |
295 | orr r0, r0, #PJ4B_CLEAN_LINE | 294 | orr r0, r0, #PJ4B_CLEAN_LINE |
296 | orr r0, r0, #PJ4B_BCK_OFF_STREX | ||
297 | orr r0, r0, #PJ4B_INTER_PARITY | 295 | orr r0, r0, #PJ4B_INTER_PARITY |
298 | bic r0, r0, #PJ4B_STATIC_BP | 296 | bic r0, r0, #PJ4B_STATIC_BP |
299 | mcr p15, 1, r0, c15, c1, 1 | 297 | mcr p15, 1, r0, c15, c1, 1 |
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 23259f104c66..afa2b3c4df4a 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S | |||
@@ -535,7 +535,7 @@ ENTRY(cpu_xscale_do_suspend) | |||
535 | mrc p15, 0, r5, c15, c1, 0 @ CP access reg | 535 | mrc p15, 0, r5, c15, c1, 0 @ CP access reg |
536 | mrc p15, 0, r6, c13, c0, 0 @ PID | 536 | mrc p15, 0, r6, c13, c0, 0 @ PID |
537 | mrc p15, 0, r7, c3, c0, 0 @ domain ID | 537 | mrc p15, 0, r7, c3, c0, 0 @ domain ID |
538 | mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg | 538 | mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg |
539 | mrc p15, 0, r9, c1, c0, 0 @ control reg | 539 | mrc p15, 0, r9, c1, c0, 0 @ control reg |
540 | bic r4, r4, #2 @ clear frequency change bit | 540 | bic r4, r4, #2 @ clear frequency change bit |
541 | stmia r0, {r4 - r9} @ store cp regs | 541 | stmia r0, {r4 - r9} @ store cp regs |
@@ -552,7 +552,7 @@ ENTRY(cpu_xscale_do_resume) | |||
552 | mcr p15, 0, r6, c13, c0, 0 @ PID | 552 | mcr p15, 0, r6, c13, c0, 0 @ PID |
553 | mcr p15, 0, r7, c3, c0, 0 @ domain ID | 553 | mcr p15, 0, r7, c3, c0, 0 @ domain ID |
554 | mcr p15, 0, r1, c2, c0, 0 @ translation table base addr | 554 | mcr p15, 0, r1, c2, c0, 0 @ translation table base addr |
555 | mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg | 555 | mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg |
556 | mov r0, r9 @ control register | 556 | mov r0, r9 @ control register |
557 | b cpu_resume_mmu | 557 | b cpu_resume_mmu |
558 | ENDPROC(cpu_xscale_do_resume) | 558 | ENDPROC(cpu_xscale_do_resume) |
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 4cc3b719208e..3d7c2df89946 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c | |||
@@ -424,6 +424,11 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
424 | /* VBAR_EL1 */ | 424 | /* VBAR_EL1 */ |
425 | { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b0000), Op2(0b000), | 425 | { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b0000), Op2(0b000), |
426 | NULL, reset_val, VBAR_EL1, 0 }, | 426 | NULL, reset_val, VBAR_EL1, 0 }, |
427 | |||
428 | /* ICC_SRE_EL1 */ | ||
429 | { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101), | ||
430 | trap_raz_wi }, | ||
431 | |||
427 | /* CONTEXTIDR_EL1 */ | 432 | /* CONTEXTIDR_EL1 */ |
428 | { Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001), | 433 | { Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001), |
429 | access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 }, | 434 | access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 }, |
@@ -690,6 +695,10 @@ static const struct sys_reg_desc cp15_regs[] = { | |||
690 | { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, | 695 | { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, |
691 | { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, | 696 | { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, |
692 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, | 697 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, |
698 | |||
699 | /* ICC_SRE */ | ||
700 | { Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi }, | ||
701 | |||
693 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, | 702 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, |
694 | }; | 703 | }; |
695 | 704 | ||
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index ec6b9acb6bea..dbe46f43884d 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1563,7 +1563,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
1563 | 1563 | ||
1564 | for (i = 0; i < npages; i++) { | 1564 | for (i = 0; i < npages; i++) { |
1565 | pfn = gfn_to_pfn(kvm, base_gfn + i); | 1565 | pfn = gfn_to_pfn(kvm, base_gfn + i); |
1566 | if (!kvm_is_mmio_pfn(pfn)) { | 1566 | if (!kvm_is_reserved_pfn(pfn)) { |
1567 | kvm_set_pmt_entry(kvm, base_gfn + i, | 1567 | kvm_set_pmt_entry(kvm, base_gfn + i, |
1568 | pfn << PAGE_SHIFT, | 1568 | pfn << PAGE_SHIFT, |
1569 | _PAGE_AR_RWX | _PAGE_MA_WB); | 1569 | _PAGE_AR_RWX | _PAGE_MA_WB); |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f43aa536c517..9536ef912f59 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -2101,9 +2101,17 @@ config 64BIT_PHYS_ADDR | |||
2101 | config ARCH_PHYS_ADDR_T_64BIT | 2101 | config ARCH_PHYS_ADDR_T_64BIT |
2102 | def_bool 64BIT_PHYS_ADDR | 2102 | def_bool 64BIT_PHYS_ADDR |
2103 | 2103 | ||
2104 | choice | ||
2105 | prompt "SmartMIPS or microMIPS ASE support" | ||
2106 | |||
2107 | config CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS | ||
2108 | bool "None" | ||
2109 | help | ||
2110 | Select this if you want neither microMIPS nor SmartMIPS support | ||
2111 | |||
2104 | config CPU_HAS_SMARTMIPS | 2112 | config CPU_HAS_SMARTMIPS |
2105 | depends on SYS_SUPPORTS_SMARTMIPS | 2113 | depends on SYS_SUPPORTS_SMARTMIPS |
2106 | bool "Support for the SmartMIPS ASE" | 2114 | bool "SmartMIPS" |
2107 | help | 2115 | help |
2108 | SmartMIPS is a extension of the MIPS32 architecture aimed at | 2116 | SmartMIPS is a extension of the MIPS32 architecture aimed at |
2109 | increased security at both hardware and software level for | 2117 | increased security at both hardware and software level for |
@@ -2115,11 +2123,13 @@ config CPU_HAS_SMARTMIPS | |||
2115 | 2123 | ||
2116 | config CPU_MICROMIPS | 2124 | config CPU_MICROMIPS |
2117 | depends on SYS_SUPPORTS_MICROMIPS | 2125 | depends on SYS_SUPPORTS_MICROMIPS |
2118 | bool "Build kernel using microMIPS ISA" | 2126 | bool "microMIPS" |
2119 | help | 2127 | help |
2120 | When this option is enabled the kernel will be built using the | 2128 | When this option is enabled the kernel will be built using the |
2121 | microMIPS ISA | 2129 | microMIPS ISA |
2122 | 2130 | ||
2131 | endchoice | ||
2132 | |||
2123 | config CPU_HAS_MSA | 2133 | config CPU_HAS_MSA |
2124 | bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)" | 2134 | bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)" |
2125 | depends on CPU_SUPPORTS_MSA | 2135 | depends on CPU_SUPPORTS_MSA |
diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h index e194f957ca8c..fdbff44e5482 100644 --- a/arch/mips/include/asm/jump_label.h +++ b/arch/mips/include/asm/jump_label.h | |||
@@ -20,9 +20,15 @@ | |||
20 | #define WORD_INSN ".word" | 20 | #define WORD_INSN ".word" |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #ifdef CONFIG_CPU_MICROMIPS | ||
24 | #define NOP_INSN "nop32" | ||
25 | #else | ||
26 | #define NOP_INSN "nop" | ||
27 | #endif | ||
28 | |||
23 | static __always_inline bool arch_static_branch(struct static_key *key) | 29 | static __always_inline bool arch_static_branch(struct static_key *key) |
24 | { | 30 | { |
25 | asm_volatile_goto("1:\tnop\n\t" | 31 | asm_volatile_goto("1:\t" NOP_INSN "\n\t" |
26 | "nop\n\t" | 32 | "nop\n\t" |
27 | ".pushsection __jump_table, \"aw\"\n\t" | 33 | ".pushsection __jump_table, \"aw\"\n\t" |
28 | WORD_INSN " 1b, %l[l_yes], %0\n\t" | 34 | WORD_INSN " 1b, %l[l_yes], %0\n\t" |
diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h index 7d28f95b0512..6d69332f21ec 100644 --- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h | |||
@@ -41,10 +41,8 @@ | |||
41 | #define cpu_has_mcheck 0 | 41 | #define cpu_has_mcheck 0 |
42 | #define cpu_has_mdmx 0 | 42 | #define cpu_has_mdmx 0 |
43 | #define cpu_has_mips16 0 | 43 | #define cpu_has_mips16 0 |
44 | #define cpu_has_mips32r1 0 | ||
45 | #define cpu_has_mips32r2 0 | 44 | #define cpu_has_mips32r2 0 |
46 | #define cpu_has_mips3d 0 | 45 | #define cpu_has_mips3d 0 |
47 | #define cpu_has_mips64r1 0 | ||
48 | #define cpu_has_mips64r2 0 | 46 | #define cpu_has_mips64r2 0 |
49 | #define cpu_has_mipsmt 0 | 47 | #define cpu_has_mipsmt 0 |
50 | #define cpu_has_prefetch 0 | 48 | #define cpu_has_prefetch 0 |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index b46cd220a018..22a135ac91de 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -661,6 +661,8 @@ | |||
661 | #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) | 661 | #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) |
662 | /* proAptiv FTLB on/off bit */ | 662 | /* proAptiv FTLB on/off bit */ |
663 | #define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15) | 663 | #define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15) |
664 | /* FTLB probability bits */ | ||
665 | #define MIPS_CONF6_FTLBP_SHIFT (16) | ||
664 | 666 | ||
665 | #define MIPS_CONF7_WII (_ULCAST_(1) << 31) | 667 | #define MIPS_CONF7_WII (_ULCAST_(1) << 31) |
666 | 668 | ||
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 4520adc8699b..cd6e0afc6833 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h | |||
@@ -257,7 +257,11 @@ static inline void protected_flush_icache_line(unsigned long addr) | |||
257 | */ | 257 | */ |
258 | static inline void protected_writeback_dcache_line(unsigned long addr) | 258 | static inline void protected_writeback_dcache_line(unsigned long addr) |
259 | { | 259 | { |
260 | #ifdef CONFIG_EVA | ||
261 | protected_cachee_op(Hit_Writeback_Inv_D, addr); | ||
262 | #else | ||
260 | protected_cache_op(Hit_Writeback_Inv_D, addr); | 263 | protected_cache_op(Hit_Writeback_Inv_D, addr); |
264 | #endif | ||
261 | } | 265 | } |
262 | 266 | ||
263 | static inline void protected_writeback_scache_line(unsigned long addr) | 267 | static inline void protected_writeback_scache_line(unsigned long addr) |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index a10951090234..22a5624e2fd2 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
@@ -301,7 +301,8 @@ do { \ | |||
301 | __get_kernel_common((x), size, __gu_ptr); \ | 301 | __get_kernel_common((x), size, __gu_ptr); \ |
302 | else \ | 302 | else \ |
303 | __get_user_common((x), size, __gu_ptr); \ | 303 | __get_user_common((x), size, __gu_ptr); \ |
304 | } \ | 304 | } else \ |
305 | (x) = 0; \ | ||
305 | \ | 306 | \ |
306 | __gu_err; \ | 307 | __gu_err; \ |
307 | }) | 308 | }) |
@@ -316,6 +317,7 @@ do { \ | |||
316 | " .insn \n" \ | 317 | " .insn \n" \ |
317 | " .section .fixup,\"ax\" \n" \ | 318 | " .section .fixup,\"ax\" \n" \ |
318 | "3: li %0, %4 \n" \ | 319 | "3: li %0, %4 \n" \ |
320 | " move %1, $0 \n" \ | ||
319 | " j 2b \n" \ | 321 | " j 2b \n" \ |
320 | " .previous \n" \ | 322 | " .previous \n" \ |
321 | " .section __ex_table,\"a\" \n" \ | 323 | " .section __ex_table,\"a\" \n" \ |
@@ -630,6 +632,7 @@ do { \ | |||
630 | " .insn \n" \ | 632 | " .insn \n" \ |
631 | " .section .fixup,\"ax\" \n" \ | 633 | " .section .fixup,\"ax\" \n" \ |
632 | "3: li %0, %4 \n" \ | 634 | "3: li %0, %4 \n" \ |
635 | " move %1, $0 \n" \ | ||
633 | " j 2b \n" \ | 636 | " j 2b \n" \ |
634 | " .previous \n" \ | 637 | " .previous \n" \ |
635 | " .section __ex_table,\"a\" \n" \ | 638 | " .section __ex_table,\"a\" \n" \ |
@@ -773,10 +776,11 @@ extern void __put_user_unaligned_unknown(void); | |||
773 | "jal\t" #destination "\n\t" | 776 | "jal\t" #destination "\n\t" |
774 | #endif | 777 | #endif |
775 | 778 | ||
776 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | 779 | #if defined(CONFIG_CPU_DADDI_WORKAROUNDS) || (defined(CONFIG_EVA) && \ |
777 | #define DADDI_SCRATCH "$0" | 780 | defined(CONFIG_CPU_HAS_PREFETCH)) |
778 | #else | ||
779 | #define DADDI_SCRATCH "$3" | 781 | #define DADDI_SCRATCH "$3" |
782 | #else | ||
783 | #define DADDI_SCRATCH "$0" | ||
780 | #endif | 784 | #endif |
781 | 785 | ||
782 | extern size_t __copy_user(void *__to, const void *__from, size_t __n); | 786 | extern size_t __copy_user(void *__to, const void *__from, size_t __n); |
@@ -1418,7 +1422,7 @@ static inline long __strnlen_user(const char __user *s, long n) | |||
1418 | } | 1422 | } |
1419 | 1423 | ||
1420 | /* | 1424 | /* |
1421 | * strlen_user: - Get the size of a string in user space. | 1425 | * strnlen_user: - Get the size of a string in user space. |
1422 | * @str: The string to measure. | 1426 | * @str: The string to measure. |
1423 | * | 1427 | * |
1424 | * Context: User context only. This function may sleep. | 1428 | * Context: User context only. This function may sleep. |
@@ -1427,9 +1431,7 @@ static inline long __strnlen_user(const char __user *s, long n) | |||
1427 | * | 1431 | * |
1428 | * Returns the size of the string INCLUDING the terminating NUL. | 1432 | * Returns the size of the string INCLUDING the terminating NUL. |
1429 | * On exception, returns 0. | 1433 | * On exception, returns 0. |
1430 | * | 1434 | * If the string is too long, returns a value greater than @n. |
1431 | * If there is a limit on the length of a valid string, you may wish to | ||
1432 | * consider using strnlen_user() instead. | ||
1433 | */ | 1435 | */ |
1434 | static inline long strnlen_user(const char __user *s, long n) | 1436 | static inline long strnlen_user(const char __user *s, long n) |
1435 | { | 1437 | { |
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h index 9dc58568f230..d001bb1ad177 100644 --- a/arch/mips/include/uapi/asm/unistd.h +++ b/arch/mips/include/uapi/asm/unistd.h | |||
@@ -1045,7 +1045,7 @@ | |||
1045 | #define __NR_seccomp (__NR_Linux + 316) | 1045 | #define __NR_seccomp (__NR_Linux + 316) |
1046 | #define __NR_getrandom (__NR_Linux + 317) | 1046 | #define __NR_getrandom (__NR_Linux + 317) |
1047 | #define __NR_memfd_create (__NR_Linux + 318) | 1047 | #define __NR_memfd_create (__NR_Linux + 318) |
1048 | #define __NR_memfd_create (__NR_Linux + 319) | 1048 | #define __NR_bpf (__NR_Linux + 319) |
1049 | 1049 | ||
1050 | /* | 1050 | /* |
1051 | * Offset of the last N32 flavoured syscall | 1051 | * Offset of the last N32 flavoured syscall |
diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S index 290c23b51678..86495072a922 100644 --- a/arch/mips/kernel/bmips_vec.S +++ b/arch/mips/kernel/bmips_vec.S | |||
@@ -208,7 +208,6 @@ bmips_reset_nmi_vec_end: | |||
208 | END(bmips_reset_nmi_vec) | 208 | END(bmips_reset_nmi_vec) |
209 | 209 | ||
210 | .set pop | 210 | .set pop |
211 | .previous | ||
212 | 211 | ||
213 | /*********************************************************************** | 212 | /*********************************************************************** |
214 | * CPU1 warm restart vector (used for second and subsequent boots). | 213 | * CPU1 warm restart vector (used for second and subsequent boots). |
@@ -281,5 +280,3 @@ LEAF(bmips_enable_xks01) | |||
281 | jr ra | 280 | jr ra |
282 | 281 | ||
283 | END(bmips_enable_xks01) | 282 | END(bmips_enable_xks01) |
284 | |||
285 | .previous | ||
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index e6e97d2a5c9e..0384b05ab5a0 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S | |||
@@ -229,6 +229,7 @@ LEAF(mips_cps_core_init) | |||
229 | nop | 229 | nop |
230 | 230 | ||
231 | .set push | 231 | .set push |
232 | .set mips32r2 | ||
232 | .set mt | 233 | .set mt |
233 | 234 | ||
234 | /* Only allow 1 TC per VPE to execute... */ | 235 | /* Only allow 1 TC per VPE to execute... */ |
@@ -345,6 +346,7 @@ LEAF(mips_cps_boot_vpes) | |||
345 | nop | 346 | nop |
346 | 347 | ||
347 | .set push | 348 | .set push |
349 | .set mips32r2 | ||
348 | .set mt | 350 | .set mt |
349 | 351 | ||
350 | 1: /* Enter VPE configuration state */ | 352 | 1: /* Enter VPE configuration state */ |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 94c4a0c0a577..dc49cf30c2db 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -193,6 +193,32 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa) | |||
193 | static char unknown_isa[] = KERN_ERR \ | 193 | static char unknown_isa[] = KERN_ERR \ |
194 | "Unsupported ISA type, c0.config0: %d."; | 194 | "Unsupported ISA type, c0.config0: %d."; |
195 | 195 | ||
196 | static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c) | ||
197 | { | ||
198 | |||
199 | unsigned int probability = c->tlbsize / c->tlbsizevtlb; | ||
200 | |||
201 | /* | ||
202 | * 0 = All TLBWR instructions go to FTLB | ||
203 | * 1 = 15:1: For every 16 TBLWR instructions, 15 go to the | ||
204 | * FTLB and 1 goes to the VTLB. | ||
205 | * 2 = 7:1: As above with 7:1 ratio. | ||
206 | * 3 = 3:1: As above with 3:1 ratio. | ||
207 | * | ||
208 | * Use the linear midpoint as the probability threshold. | ||
209 | */ | ||
210 | if (probability >= 12) | ||
211 | return 1; | ||
212 | else if (probability >= 6) | ||
213 | return 2; | ||
214 | else | ||
215 | /* | ||
216 | * So FTLB is less than 4 times bigger than VTLB. | ||
217 | * A 3:1 ratio can still be useful though. | ||
218 | */ | ||
219 | return 3; | ||
220 | } | ||
221 | |||
196 | static void set_ftlb_enable(struct cpuinfo_mips *c, int enable) | 222 | static void set_ftlb_enable(struct cpuinfo_mips *c, int enable) |
197 | { | 223 | { |
198 | unsigned int config6; | 224 | unsigned int config6; |
@@ -203,9 +229,14 @@ static void set_ftlb_enable(struct cpuinfo_mips *c, int enable) | |||
203 | case CPU_P5600: | 229 | case CPU_P5600: |
204 | /* proAptiv & related cores use Config6 to enable the FTLB */ | 230 | /* proAptiv & related cores use Config6 to enable the FTLB */ |
205 | config6 = read_c0_config6(); | 231 | config6 = read_c0_config6(); |
232 | /* Clear the old probability value */ | ||
233 | config6 &= ~(3 << MIPS_CONF6_FTLBP_SHIFT); | ||
206 | if (enable) | 234 | if (enable) |
207 | /* Enable FTLB */ | 235 | /* Enable FTLB */ |
208 | write_c0_config6(config6 | MIPS_CONF6_FTLBEN); | 236 | write_c0_config6(config6 | |
237 | (calculate_ftlb_probability(c) | ||
238 | << MIPS_CONF6_FTLBP_SHIFT) | ||
239 | | MIPS_CONF6_FTLBEN); | ||
209 | else | 240 | else |
210 | /* Disable FTLB */ | 241 | /* Disable FTLB */ |
211 | write_c0_config6(config6 & ~MIPS_CONF6_FTLBEN); | 242 | write_c0_config6(config6 & ~MIPS_CONF6_FTLBEN); |
@@ -757,31 +788,34 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
757 | c->cputype = CPU_LOONGSON2; | 788 | c->cputype = CPU_LOONGSON2; |
758 | __cpu_name[cpu] = "ICT Loongson-2"; | 789 | __cpu_name[cpu] = "ICT Loongson-2"; |
759 | set_elf_platform(cpu, "loongson2e"); | 790 | set_elf_platform(cpu, "loongson2e"); |
791 | set_isa(c, MIPS_CPU_ISA_III); | ||
760 | break; | 792 | break; |
761 | case PRID_REV_LOONGSON2F: | 793 | case PRID_REV_LOONGSON2F: |
762 | c->cputype = CPU_LOONGSON2; | 794 | c->cputype = CPU_LOONGSON2; |
763 | __cpu_name[cpu] = "ICT Loongson-2"; | 795 | __cpu_name[cpu] = "ICT Loongson-2"; |
764 | set_elf_platform(cpu, "loongson2f"); | 796 | set_elf_platform(cpu, "loongson2f"); |
797 | set_isa(c, MIPS_CPU_ISA_III); | ||
765 | break; | 798 | break; |
766 | case PRID_REV_LOONGSON3A: | 799 | case PRID_REV_LOONGSON3A: |
767 | c->cputype = CPU_LOONGSON3; | 800 | c->cputype = CPU_LOONGSON3; |
768 | c->writecombine = _CACHE_UNCACHED_ACCELERATED; | ||
769 | __cpu_name[cpu] = "ICT Loongson-3"; | 801 | __cpu_name[cpu] = "ICT Loongson-3"; |
770 | set_elf_platform(cpu, "loongson3a"); | 802 | set_elf_platform(cpu, "loongson3a"); |
803 | set_isa(c, MIPS_CPU_ISA_M64R1); | ||
771 | break; | 804 | break; |
772 | case PRID_REV_LOONGSON3B_R1: | 805 | case PRID_REV_LOONGSON3B_R1: |
773 | case PRID_REV_LOONGSON3B_R2: | 806 | case PRID_REV_LOONGSON3B_R2: |
774 | c->cputype = CPU_LOONGSON3; | 807 | c->cputype = CPU_LOONGSON3; |
775 | __cpu_name[cpu] = "ICT Loongson-3"; | 808 | __cpu_name[cpu] = "ICT Loongson-3"; |
776 | set_elf_platform(cpu, "loongson3b"); | 809 | set_elf_platform(cpu, "loongson3b"); |
810 | set_isa(c, MIPS_CPU_ISA_M64R1); | ||
777 | break; | 811 | break; |
778 | } | 812 | } |
779 | 813 | ||
780 | set_isa(c, MIPS_CPU_ISA_III); | ||
781 | c->options = R4K_OPTS | | 814 | c->options = R4K_OPTS | |
782 | MIPS_CPU_FPU | MIPS_CPU_LLSC | | 815 | MIPS_CPU_FPU | MIPS_CPU_LLSC | |
783 | MIPS_CPU_32FPR; | 816 | MIPS_CPU_32FPR; |
784 | c->tlbsize = 64; | 817 | c->tlbsize = 64; |
818 | c->writecombine = _CACHE_UNCACHED_ACCELERATED; | ||
785 | break; | 819 | break; |
786 | case PRID_IMP_LOONGSON_32: /* Loongson-1 */ | 820 | case PRID_IMP_LOONGSON_32: /* Loongson-1 */ |
787 | decode_configs(c); | 821 | decode_configs(c); |
diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c index 6001610cfe55..dda800e9e731 100644 --- a/arch/mips/kernel/jump_label.c +++ b/arch/mips/kernel/jump_label.c | |||
@@ -18,31 +18,53 @@ | |||
18 | 18 | ||
19 | #ifdef HAVE_JUMP_LABEL | 19 | #ifdef HAVE_JUMP_LABEL |
20 | 20 | ||
21 | #define J_RANGE_MASK ((1ul << 28) - 1) | 21 | /* |
22 | * Define parameters for the standard MIPS and the microMIPS jump | ||
23 | * instruction encoding respectively: | ||
24 | * | ||
25 | * - the ISA bit of the target, either 0 or 1 respectively, | ||
26 | * | ||
27 | * - the amount the jump target address is shifted right to fit in the | ||
28 | * immediate field of the machine instruction, either 2 or 1, | ||
29 | * | ||
30 | * - the mask determining the size of the jump region relative to the | ||
31 | * delay-slot instruction, either 256MB or 128MB, | ||
32 | * | ||
33 | * - the jump target alignment, either 4 or 2 bytes. | ||
34 | */ | ||
35 | #define J_ISA_BIT IS_ENABLED(CONFIG_CPU_MICROMIPS) | ||
36 | #define J_RANGE_SHIFT (2 - J_ISA_BIT) | ||
37 | #define J_RANGE_MASK ((1ul << (26 + J_RANGE_SHIFT)) - 1) | ||
38 | #define J_ALIGN_MASK ((1ul << J_RANGE_SHIFT) - 1) | ||
22 | 39 | ||
23 | void arch_jump_label_transform(struct jump_entry *e, | 40 | void arch_jump_label_transform(struct jump_entry *e, |
24 | enum jump_label_type type) | 41 | enum jump_label_type type) |
25 | { | 42 | { |
43 | union mips_instruction *insn_p; | ||
26 | union mips_instruction insn; | 44 | union mips_instruction insn; |
27 | union mips_instruction *insn_p = | ||
28 | (union mips_instruction *)(unsigned long)e->code; | ||
29 | 45 | ||
30 | /* Jump only works within a 256MB aligned region. */ | 46 | insn_p = (union mips_instruction *)msk_isa16_mode(e->code); |
31 | BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK)); | 47 | |
48 | /* Jump only works within an aligned region its delay slot is in. */ | ||
49 | BUG_ON((e->target & ~J_RANGE_MASK) != ((e->code + 4) & ~J_RANGE_MASK)); | ||
32 | 50 | ||
33 | /* Target must have 4 byte alignment. */ | 51 | /* Target must have the right alignment and ISA must be preserved. */ |
34 | BUG_ON((e->target & 3) != 0); | 52 | BUG_ON((e->target & J_ALIGN_MASK) != J_ISA_BIT); |
35 | 53 | ||
36 | if (type == JUMP_LABEL_ENABLE) { | 54 | if (type == JUMP_LABEL_ENABLE) { |
37 | insn.j_format.opcode = j_op; | 55 | insn.j_format.opcode = J_ISA_BIT ? mm_j32_op : j_op; |
38 | insn.j_format.target = (e->target & J_RANGE_MASK) >> 2; | 56 | insn.j_format.target = e->target >> J_RANGE_SHIFT; |
39 | } else { | 57 | } else { |
40 | insn.word = 0; /* nop */ | 58 | insn.word = 0; /* nop */ |
41 | } | 59 | } |
42 | 60 | ||
43 | get_online_cpus(); | 61 | get_online_cpus(); |
44 | mutex_lock(&text_mutex); | 62 | mutex_lock(&text_mutex); |
45 | *insn_p = insn; | 63 | if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) { |
64 | insn_p->halfword[0] = insn.word >> 16; | ||
65 | insn_p->halfword[1] = insn.word; | ||
66 | } else | ||
67 | *insn_p = insn; | ||
46 | 68 | ||
47 | flush_icache_range((unsigned long)insn_p, | 69 | flush_icache_range((unsigned long)insn_p, |
48 | (unsigned long)insn_p + sizeof(*insn_p)); | 70 | (unsigned long)insn_p + sizeof(*insn_p)); |
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 31b1b763cb29..c5c4fd54d797 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
@@ -94,12 +94,12 @@ int rtlx_open(int index, int can_sleep) | |||
94 | int ret = 0; | 94 | int ret = 0; |
95 | 95 | ||
96 | if (index >= RTLX_CHANNELS) { | 96 | if (index >= RTLX_CHANNELS) { |
97 | pr_debug(KERN_DEBUG "rtlx_open index out of range\n"); | 97 | pr_debug("rtlx_open index out of range\n"); |
98 | return -ENOSYS; | 98 | return -ENOSYS; |
99 | } | 99 | } |
100 | 100 | ||
101 | if (atomic_inc_return(&channel_wqs[index].in_open) > 1) { | 101 | if (atomic_inc_return(&channel_wqs[index].in_open) > 1) { |
102 | pr_debug(KERN_DEBUG "rtlx_open channel %d already opened\n", index); | 102 | pr_debug("rtlx_open channel %d already opened\n", index); |
103 | ret = -EBUSY; | 103 | ret = -EBUSY; |
104 | goto out_fail; | 104 | goto out_fail; |
105 | } | 105 | } |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index d21ec57b6e95..f3b635f86c39 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -485,7 +485,7 @@ static void __init bootmem_init(void) | |||
485 | * NOTE: historically plat_mem_setup did the entire platform initialization. | 485 | * NOTE: historically plat_mem_setup did the entire platform initialization. |
486 | * This was rather impractical because it meant plat_mem_setup had to | 486 | * This was rather impractical because it meant plat_mem_setup had to |
487 | * get away without any kind of memory allocator. To keep old code from | 487 | * get away without any kind of memory allocator. To keep old code from |
488 | * breaking plat_setup was just renamed to plat_setup and a second platform | 488 | * breaking plat_setup was just renamed to plat_mem_setup and a second platform |
489 | * initialization hook for anything else was introduced. | 489 | * initialization hook for anything else was introduced. |
490 | */ | 490 | */ |
491 | 491 | ||
@@ -493,7 +493,7 @@ static int usermem __initdata; | |||
493 | 493 | ||
494 | static int __init early_parse_mem(char *p) | 494 | static int __init early_parse_mem(char *p) |
495 | { | 495 | { |
496 | unsigned long start, size; | 496 | phys_t start, size; |
497 | 497 | ||
498 | /* | 498 | /* |
499 | * If a user specifies memory size, we | 499 | * If a user specifies memory size, we |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 1d57605e4615..16f1e4f2bf3c 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -658,13 +658,13 @@ static int signal_setup(void) | |||
658 | save_fp_context = _save_fp_context; | 658 | save_fp_context = _save_fp_context; |
659 | restore_fp_context = _restore_fp_context; | 659 | restore_fp_context = _restore_fp_context; |
660 | } else { | 660 | } else { |
661 | save_fp_context = copy_fp_from_sigcontext; | 661 | save_fp_context = copy_fp_to_sigcontext; |
662 | restore_fp_context = copy_fp_to_sigcontext; | 662 | restore_fp_context = copy_fp_from_sigcontext; |
663 | } | 663 | } |
664 | #endif /* CONFIG_SMP */ | 664 | #endif /* CONFIG_SMP */ |
665 | #else | 665 | #else |
666 | save_fp_context = copy_fp_from_sigcontext;; | 666 | save_fp_context = copy_fp_to_sigcontext; |
667 | restore_fp_context = copy_fp_to_sigcontext; | 667 | restore_fp_context = copy_fp_from_sigcontext; |
668 | #endif | 668 | #endif |
669 | 669 | ||
670 | return 0; | 670 | return 0; |
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S index c17ef80cf65a..5d3238af9b5c 100644 --- a/arch/mips/lib/memcpy.S +++ b/arch/mips/lib/memcpy.S | |||
@@ -503,6 +503,7 @@ | |||
503 | STOREB(t0, NBYTES-2(dst), .Ls_exc_p1\@) | 503 | STOREB(t0, NBYTES-2(dst), .Ls_exc_p1\@) |
504 | .Ldone\@: | 504 | .Ldone\@: |
505 | jr ra | 505 | jr ra |
506 | nop | ||
506 | .if __memcpy == 1 | 507 | .if __memcpy == 1 |
507 | END(memcpy) | 508 | END(memcpy) |
508 | .set __memcpy, 0 | 509 | .set __memcpy, 0 |
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index 0bb9cc9dc621..d87e03330b29 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile | |||
@@ -11,7 +11,8 @@ obj-$(CONFIG_PCI) += pci.o | |||
11 | # Serial port support | 11 | # Serial port support |
12 | # | 12 | # |
13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
14 | obj-$(CONFIG_SERIAL_8250) += serial.o | 14 | loongson-serial-$(CONFIG_SERIAL_8250) := serial.o |
15 | obj-y += $(loongson-serial-m) $(loongson-serial-y) | ||
15 | obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o | 16 | obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o |
16 | obj-$(CONFIG_LOONGSON_MC146818) += rtc.o | 17 | obj-$(CONFIG_LOONGSON_MC146818) += rtc.o |
17 | 18 | ||
diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c index 37ed184398c6..42323bcc5d28 100644 --- a/arch/mips/loongson/loongson-3/numa.c +++ b/arch/mips/loongson/loongson-3/numa.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | static struct node_data prealloc__node_data[MAX_NUMNODES]; | 34 | static struct node_data prealloc__node_data[MAX_NUMNODES]; |
35 | unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; | 35 | unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; |
36 | EXPORT_SYMBOL(__node_distances); | ||
36 | struct node_data *__node_data[MAX_NUMNODES]; | 37 | struct node_data *__node_data[MAX_NUMNODES]; |
37 | EXPORT_SYMBOL(__node_data); | 38 | EXPORT_SYMBOL(__node_data); |
38 | 39 | ||
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index fa6ebd4bc9e9..c3917e251f59 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -299,6 +299,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
299 | 299 | ||
300 | local_irq_save(flags); | 300 | local_irq_save(flags); |
301 | 301 | ||
302 | htw_stop(); | ||
302 | pid = read_c0_entryhi() & ASID_MASK; | 303 | pid = read_c0_entryhi() & ASID_MASK; |
303 | address &= (PAGE_MASK << 1); | 304 | address &= (PAGE_MASK << 1); |
304 | write_c0_entryhi(address | pid); | 305 | write_c0_entryhi(address | pid); |
@@ -346,6 +347,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
346 | tlb_write_indexed(); | 347 | tlb_write_indexed(); |
347 | } | 348 | } |
348 | tlbw_use_hazard(); | 349 | tlbw_use_hazard(); |
350 | htw_start(); | ||
349 | flush_itlb_vm(vma); | 351 | flush_itlb_vm(vma); |
350 | local_irq_restore(flags); | 352 | local_irq_restore(flags); |
351 | } | 353 | } |
@@ -422,6 +424,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
422 | 424 | ||
423 | local_irq_save(flags); | 425 | local_irq_save(flags); |
424 | /* Save old context and create impossible VPN2 value */ | 426 | /* Save old context and create impossible VPN2 value */ |
427 | htw_stop(); | ||
425 | old_ctx = read_c0_entryhi(); | 428 | old_ctx = read_c0_entryhi(); |
426 | old_pagemask = read_c0_pagemask(); | 429 | old_pagemask = read_c0_pagemask(); |
427 | wired = read_c0_wired(); | 430 | wired = read_c0_wired(); |
@@ -443,6 +446,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
443 | 446 | ||
444 | write_c0_entryhi(old_ctx); | 447 | write_c0_entryhi(old_ctx); |
445 | write_c0_pagemask(old_pagemask); | 448 | write_c0_pagemask(old_pagemask); |
449 | htw_start(); | ||
446 | out: | 450 | out: |
447 | local_irq_restore(flags); | 451 | local_irq_restore(flags); |
448 | return ret; | 452 | return ret; |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index b5f228e7eae6..e3328a96e809 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -1872,8 +1872,16 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, | |||
1872 | uasm_l_smp_pgtable_change(l, *p); | 1872 | uasm_l_smp_pgtable_change(l, *p); |
1873 | #endif | 1873 | #endif |
1874 | iPTE_LW(p, wr.r1, wr.r2); /* get even pte */ | 1874 | iPTE_LW(p, wr.r1, wr.r2); /* get even pte */ |
1875 | if (!m4kc_tlbp_war()) | 1875 | if (!m4kc_tlbp_war()) { |
1876 | build_tlb_probe_entry(p); | 1876 | build_tlb_probe_entry(p); |
1877 | if (cpu_has_htw) { | ||
1878 | /* race condition happens, leaving */ | ||
1879 | uasm_i_ehb(p); | ||
1880 | uasm_i_mfc0(p, wr.r3, C0_INDEX); | ||
1881 | uasm_il_bltz(p, r, wr.r3, label_leave); | ||
1882 | uasm_i_nop(p); | ||
1883 | } | ||
1884 | } | ||
1877 | return wr; | 1885 | return wr; |
1878 | } | 1886 | } |
1879 | 1887 | ||
diff --git a/arch/mips/mti-sead3/sead3-leds.c b/arch/mips/mti-sead3/sead3-leds.c index 20102a6d4141..c427c5778186 100644 --- a/arch/mips/mti-sead3/sead3-leds.c +++ b/arch/mips/mti-sead3/sead3-leds.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | 6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/init.h> |
9 | #include <linux/leds.h> | 9 | #include <linux/leds.h> |
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | 11 | ||
@@ -76,8 +76,4 @@ static int __init led_init(void) | |||
76 | return platform_device_register(&fled_device); | 76 | return platform_device_register(&fled_device); |
77 | } | 77 | } |
78 | 78 | ||
79 | module_init(led_init); | 79 | device_initcall(led_init); |
80 | |||
81 | MODULE_AUTHOR("Chris Dearman <chris@mips.com>"); | ||
82 | MODULE_LICENSE("GPL"); | ||
83 | MODULE_DESCRIPTION("LED probe driver for SEAD-3"); | ||
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile index be358a8050c5..6b43af0a34d9 100644 --- a/arch/mips/netlogic/xlp/Makefile +++ b/arch/mips/netlogic/xlp/Makefile | |||
@@ -1,6 +1,10 @@ | |||
1 | obj-y += setup.o nlm_hal.o cop2-ex.o dt.o | 1 | obj-y += setup.o nlm_hal.o cop2-ex.o dt.o |
2 | obj-$(CONFIG_SMP) += wakeup.o | 2 | obj-$(CONFIG_SMP) += wakeup.o |
3 | obj-$(CONFIG_USB) += usb-init.o | 3 | ifdef CONFIG_USB |
4 | obj-$(CONFIG_USB) += usb-init-xlp2.o | 4 | obj-y += usb-init.o |
5 | obj-$(CONFIG_SATA_AHCI) += ahci-init.o | 5 | obj-y += usb-init-xlp2.o |
6 | obj-$(CONFIG_SATA_AHCI) += ahci-init-xlp2.o | 6 | endif |
7 | ifdef CONFIG_SATA_AHCI | ||
8 | obj-y += ahci-init.o | ||
9 | obj-y += ahci-init-xlp2.o | ||
10 | endif | ||
diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 6854ed5097d2..83a1dfd8f0e3 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c | |||
@@ -92,7 +92,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, | |||
92 | /* This marks the end of the previous function, | 92 | /* This marks the end of the previous function, |
93 | which means we overran. */ | 93 | which means we overran. */ |
94 | break; | 94 | break; |
95 | stack_size = (unsigned) stack_adjustment; | 95 | stack_size = (unsigned long) stack_adjustment; |
96 | } else if (is_ra_save_ins(&ip)) { | 96 | } else if (is_ra_save_ins(&ip)) { |
97 | int ra_slot = ip.i_format.simmediate; | 97 | int ra_slot = ip.i_format.simmediate; |
98 | if (ra_slot < 0) | 98 | if (ra_slot < 0) |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index a95c00f5fb96..a304bcc37e4f 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -107,6 +107,7 @@ static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; | 109 | unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; |
110 | EXPORT_SYMBOL(__node_distances); | ||
110 | 111 | ||
111 | static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b) | 112 | static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b) |
112 | { | 113 | { |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 4ca90a39d6d0..725247beebec 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -159,8 +159,6 @@ struct pci_dn { | |||
159 | 159 | ||
160 | int pci_ext_config_space; /* for pci devices */ | 160 | int pci_ext_config_space; /* for pci devices */ |
161 | 161 | ||
162 | bool force_32bit_msi; | ||
163 | |||
164 | struct pci_dev *pcidev; /* back-pointer to the pci device */ | 162 | struct pci_dev *pcidev; /* back-pointer to the pci device */ |
165 | #ifdef CONFIG_EEH | 163 | #ifdef CONFIG_EEH |
166 | struct eeh_dev *edev; /* eeh device */ | 164 | struct eeh_dev *edev; /* eeh device */ |
diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index f19b1e5cb060..1ceecdda810b 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c | |||
@@ -65,7 +65,7 @@ static ssize_t eeh_pe_state_show(struct device *dev, | |||
65 | return -ENODEV; | 65 | return -ENODEV; |
66 | 66 | ||
67 | state = eeh_ops->get_state(edev->pe, NULL); | 67 | state = eeh_ops->get_state(edev->pe, NULL); |
68 | return sprintf(buf, "%0x08x %0x08x\n", | 68 | return sprintf(buf, "0x%08x 0x%08x\n", |
69 | state, edev->pe->state); | 69 | state, edev->pe->state); |
70 | } | 70 | } |
71 | 71 | ||
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 155013da27e0..b15194e2c5fc 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -266,13 +266,3 @@ int pcibus_to_node(struct pci_bus *bus) | |||
266 | } | 266 | } |
267 | EXPORT_SYMBOL(pcibus_to_node); | 267 | EXPORT_SYMBOL(pcibus_to_node); |
268 | #endif | 268 | #endif |
269 | |||
270 | static void quirk_radeon_32bit_msi(struct pci_dev *dev) | ||
271 | { | ||
272 | struct pci_dn *pdn = pci_get_pdn(dev); | ||
273 | |||
274 | if (pdn) | ||
275 | pdn->force_32bit_msi = true; | ||
276 | } | ||
277 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi); | ||
278 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi); | ||
diff --git a/arch/powerpc/kernel/vdso32/getcpu.S b/arch/powerpc/kernel/vdso32/getcpu.S index 23eb9a9441bd..c62be60c7274 100644 --- a/arch/powerpc/kernel/vdso32/getcpu.S +++ b/arch/powerpc/kernel/vdso32/getcpu.S | |||
@@ -30,8 +30,8 @@ | |||
30 | V_FUNCTION_BEGIN(__kernel_getcpu) | 30 | V_FUNCTION_BEGIN(__kernel_getcpu) |
31 | .cfi_startproc | 31 | .cfi_startproc |
32 | mfspr r5,SPRN_SPRG_VDSO_READ | 32 | mfspr r5,SPRN_SPRG_VDSO_READ |
33 | cmpdi cr0,r3,0 | 33 | cmpwi cr0,r3,0 |
34 | cmpdi cr1,r4,0 | 34 | cmpwi cr1,r4,0 |
35 | clrlwi r6,r5,16 | 35 | clrlwi r6,r5,16 |
36 | rlwinm r7,r5,16,31-15,31-0 | 36 | rlwinm r7,r5,16,31-15,31-0 |
37 | beq cr0,1f | 37 | beq cr0,1f |
diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index 5e1ed1575aab..b322bfb51343 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c | |||
@@ -57,7 +57,7 @@ static void print_hmi_event_info(struct OpalHMIEvent *hmi_evt) | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | /* Print things out */ | 59 | /* Print things out */ |
60 | if (hmi_evt->version != OpalHMIEvt_V1) { | 60 | if (hmi_evt->version < OpalHMIEvt_V1) { |
61 | pr_err("HMI Interrupt, Unknown event version %d !\n", | 61 | pr_err("HMI Interrupt, Unknown event version %d !\n", |
62 | hmi_evt->version); | 62 | hmi_evt->version); |
63 | return; | 63 | return; |
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 468a0f23c7f2..3ba435ec3dcd 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -1509,7 +1509,6 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
1509 | unsigned int is_64, struct msi_msg *msg) | 1509 | unsigned int is_64, struct msi_msg *msg) |
1510 | { | 1510 | { |
1511 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); | 1511 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); |
1512 | struct pci_dn *pdn = pci_get_pdn(dev); | ||
1513 | unsigned int xive_num = hwirq - phb->msi_base; | 1512 | unsigned int xive_num = hwirq - phb->msi_base; |
1514 | __be32 data; | 1513 | __be32 data; |
1515 | int rc; | 1514 | int rc; |
@@ -1523,7 +1522,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
1523 | return -ENXIO; | 1522 | return -ENXIO; |
1524 | 1523 | ||
1525 | /* Force 32-bit MSI on some broken devices */ | 1524 | /* Force 32-bit MSI on some broken devices */ |
1526 | if (pdn && pdn->force_32bit_msi) | 1525 | if (dev->no_64bit_msi) |
1527 | is_64 = 0; | 1526 | is_64 = 0; |
1528 | 1527 | ||
1529 | /* Assign XIVE to PE */ | 1528 | /* Assign XIVE to PE */ |
@@ -1997,7 +1996,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
1997 | if (is_kdump_kernel()) { | 1996 | if (is_kdump_kernel()) { |
1998 | pr_info(" Issue PHB reset ...\n"); | 1997 | pr_info(" Issue PHB reset ...\n"); |
1999 | ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); | 1998 | ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); |
2000 | ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET); | 1999 | ioda_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE); |
2001 | } | 2000 | } |
2002 | 2001 | ||
2003 | /* Configure M64 window */ | 2002 | /* Configure M64 window */ |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b2187d0068b8..4b20f2c6b3b2 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -50,7 +50,6 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
50 | { | 50 | { |
51 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 51 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
52 | struct pnv_phb *phb = hose->private_data; | 52 | struct pnv_phb *phb = hose->private_data; |
53 | struct pci_dn *pdn = pci_get_pdn(pdev); | ||
54 | struct msi_desc *entry; | 53 | struct msi_desc *entry; |
55 | struct msi_msg msg; | 54 | struct msi_msg msg; |
56 | int hwirq; | 55 | int hwirq; |
@@ -60,7 +59,7 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
60 | if (WARN_ON(!phb) || !phb->msi_bmp.bitmap) | 59 | if (WARN_ON(!phb) || !phb->msi_bmp.bitmap) |
61 | return -ENODEV; | 60 | return -ENODEV; |
62 | 61 | ||
63 | if (pdn && pdn->force_32bit_msi && !phb->msi32_support) | 62 | if (pdev->no_64bit_msi && !phb->msi32_support) |
64 | return -ENODEV; | 63 | return -ENODEV; |
65 | 64 | ||
66 | list_for_each_entry(entry, &pdev->msi_list, list) { | 65 | list_for_each_entry(entry, &pdev->msi_list, list) { |
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 8ab5add4ac82..8b909e94fd9a 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
@@ -420,7 +420,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | |||
420 | */ | 420 | */ |
421 | again: | 421 | again: |
422 | if (type == PCI_CAP_ID_MSI) { | 422 | if (type == PCI_CAP_ID_MSI) { |
423 | if (pdn->force_32bit_msi) { | 423 | if (pdev->no_64bit_msi) { |
424 | rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); | 424 | rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); |
425 | if (rc < 0) { | 425 | if (rc < 0) { |
426 | /* | 426 | /* |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index de40b48b460e..da08ed088157 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -361,7 +361,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, | |||
361 | cascade_data->virq = virt_msir; | 361 | cascade_data->virq = virt_msir; |
362 | msi->cascade_array[irq_index] = cascade_data; | 362 | msi->cascade_array[irq_index] = cascade_data; |
363 | 363 | ||
364 | ret = request_irq(virt_msir, fsl_msi_cascade, 0, | 364 | ret = request_irq(virt_msir, fsl_msi_cascade, IRQF_NO_THREAD, |
365 | "fsl-msi-cascade", cascade_data); | 365 | "fsl-msi-cascade", cascade_data); |
366 | if (ret) { | 366 | if (ret) { |
367 | dev_err(&dev->dev, "failed to request_irq(%d), ret = %d\n", | 367 | dev_err(&dev->dev, "failed to request_irq(%d), ret = %d\n", |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index b988b5addf86..c8efbb37d6e0 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -293,10 +293,10 @@ static inline void disable_surveillance(void) | |||
293 | args.token = rtas_token("set-indicator"); | 293 | args.token = rtas_token("set-indicator"); |
294 | if (args.token == RTAS_UNKNOWN_SERVICE) | 294 | if (args.token == RTAS_UNKNOWN_SERVICE) |
295 | return; | 295 | return; |
296 | args.nargs = 3; | 296 | args.nargs = cpu_to_be32(3); |
297 | args.nret = 1; | 297 | args.nret = cpu_to_be32(1); |
298 | args.rets = &args.args[3]; | 298 | args.rets = &args.args[3]; |
299 | args.args[0] = SURVEILLANCE_TOKEN; | 299 | args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN); |
300 | args.args[1] = 0; | 300 | args.args[1] = 0; |
301 | args.args[2] = 0; | 301 | args.args[2] = 0; |
302 | enter_rtas(__pa(&args)); | 302 | enter_rtas(__pa(&args)); |
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 5b1b52a04ad6..7e064c68c5ec 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h | |||
@@ -12,6 +12,14 @@ int dma_supported(struct device *dev, u64 mask); | |||
12 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 12 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
13 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 13 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
14 | 14 | ||
15 | static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | ||
16 | enum dma_data_direction dir) | ||
17 | { | ||
18 | /* Since dma_{alloc,free}_noncoherent() allocated coherent memory, this | ||
19 | * routine can be a nop. | ||
20 | */ | ||
21 | } | ||
22 | |||
15 | extern struct dma_map_ops *dma_ops; | 23 | extern struct dma_map_ops *dma_ops; |
16 | extern struct dma_map_ops *leon_dma_ops; | 24 | extern struct dma_map_ops *leon_dma_ops; |
17 | extern struct dma_map_ops pci32_dma_ops; | 25 | extern struct dma_map_ops pci32_dma_ops; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ded8a6774ac9..41a503c15862 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -144,7 +144,7 @@ config INSTRUCTION_DECODER | |||
144 | 144 | ||
145 | config PERF_EVENTS_INTEL_UNCORE | 145 | config PERF_EVENTS_INTEL_UNCORE |
146 | def_bool y | 146 | def_bool y |
147 | depends on PERF_EVENTS && SUP_SUP_INTEL && PCI | 147 | depends on PERF_EVENTS && CPU_SUP_INTEL && PCI |
148 | 148 | ||
149 | config OUTPUT_FORMAT | 149 | config OUTPUT_FORMAT |
150 | string | 150 | string |
diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index f48b17df4224..3a52ee0e726d 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h | |||
@@ -20,7 +20,6 @@ | |||
20 | #define THREAD_SIZE_ORDER 1 | 20 | #define THREAD_SIZE_ORDER 1 |
21 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 21 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
22 | 22 | ||
23 | #define STACKFAULT_STACK 0 | ||
24 | #define DOUBLEFAULT_STACK 1 | 23 | #define DOUBLEFAULT_STACK 1 |
25 | #define NMI_STACK 0 | 24 | #define NMI_STACK 0 |
26 | #define DEBUG_STACK 0 | 25 | #define DEBUG_STACK 0 |
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 678205195ae1..75450b2c7be4 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h | |||
@@ -14,12 +14,11 @@ | |||
14 | #define IRQ_STACK_ORDER 2 | 14 | #define IRQ_STACK_ORDER 2 |
15 | #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) | 15 | #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) |
16 | 16 | ||
17 | #define STACKFAULT_STACK 1 | 17 | #define DOUBLEFAULT_STACK 1 |
18 | #define DOUBLEFAULT_STACK 2 | 18 | #define NMI_STACK 2 |
19 | #define NMI_STACK 3 | 19 | #define DEBUG_STACK 3 |
20 | #define DEBUG_STACK 4 | 20 | #define MCE_STACK 4 |
21 | #define MCE_STACK 5 | 21 | #define N_EXCEPTION_STACKS 4 /* hw limit: 7 */ |
22 | #define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ | ||
23 | 22 | ||
24 | #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) | 23 | #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) |
25 | #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) | 24 | #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 854053889d4d..547e344a6dc6 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
@@ -141,7 +141,7 @@ struct thread_info { | |||
141 | /* Only used for 64 bit */ | 141 | /* Only used for 64 bit */ |
142 | #define _TIF_DO_NOTIFY_MASK \ | 142 | #define _TIF_DO_NOTIFY_MASK \ |
143 | (_TIF_SIGPENDING | _TIF_MCE_NOTIFY | _TIF_NOTIFY_RESUME | \ | 143 | (_TIF_SIGPENDING | _TIF_MCE_NOTIFY | _TIF_NOTIFY_RESUME | \ |
144 | _TIF_USER_RETURN_NOTIFY) | 144 | _TIF_USER_RETURN_NOTIFY | _TIF_UPROBE) |
145 | 145 | ||
146 | /* flags to check in __switch_to() */ | 146 | /* flags to check in __switch_to() */ |
147 | #define _TIF_WORK_CTXSW \ | 147 | #define _TIF_WORK_CTXSW \ |
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index bc8352e7010a..707adc6549d8 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h | |||
@@ -39,6 +39,7 @@ asmlinkage void simd_coprocessor_error(void); | |||
39 | 39 | ||
40 | #ifdef CONFIG_TRACING | 40 | #ifdef CONFIG_TRACING |
41 | asmlinkage void trace_page_fault(void); | 41 | asmlinkage void trace_page_fault(void); |
42 | #define trace_stack_segment stack_segment | ||
42 | #define trace_divide_error divide_error | 43 | #define trace_divide_error divide_error |
43 | #define trace_bounds bounds | 44 | #define trace_bounds bounds |
44 | #define trace_invalid_op invalid_op | 45 | #define trace_invalid_op invalid_op |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4b4f78c9ba19..cfa9b5b2c27a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -146,6 +146,8 @@ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); | |||
146 | 146 | ||
147 | static int __init x86_xsave_setup(char *s) | 147 | static int __init x86_xsave_setup(char *s) |
148 | { | 148 | { |
149 | if (strlen(s)) | ||
150 | return 0; | ||
149 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); | 151 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); |
150 | setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); | 152 | setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); |
151 | setup_clear_cpu_cap(X86_FEATURE_XSAVES); | 153 | setup_clear_cpu_cap(X86_FEATURE_XSAVES); |
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index dd9d6190b08d..2ce9051174e6 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c | |||
@@ -465,6 +465,14 @@ static void mc_bp_resume(void) | |||
465 | 465 | ||
466 | if (uci->valid && uci->mc) | 466 | if (uci->valid && uci->mc) |
467 | microcode_ops->apply_microcode(cpu); | 467 | microcode_ops->apply_microcode(cpu); |
468 | else if (!uci->mc) | ||
469 | /* | ||
470 | * We might resume and not have applied late microcode but still | ||
471 | * have a newer patch stashed from the early loader. We don't | ||
472 | * have it in uci->mc so we have to load it the same way we're | ||
473 | * applying patches early on the APs. | ||
474 | */ | ||
475 | load_ucode_ap(); | ||
468 | } | 476 | } |
469 | 477 | ||
470 | static struct syscore_ops mc_syscore_ops = { | 478 | static struct syscore_ops mc_syscore_ops = { |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c index adf138eac85c..f9ed429d6e4f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c | |||
@@ -486,14 +486,17 @@ static struct attribute_group snbep_uncore_qpi_format_group = { | |||
486 | .attrs = snbep_uncore_qpi_formats_attr, | 486 | .attrs = snbep_uncore_qpi_formats_attr, |
487 | }; | 487 | }; |
488 | 488 | ||
489 | #define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ | 489 | #define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ |
490 | .init_box = snbep_uncore_msr_init_box, \ | ||
491 | .disable_box = snbep_uncore_msr_disable_box, \ | 490 | .disable_box = snbep_uncore_msr_disable_box, \ |
492 | .enable_box = snbep_uncore_msr_enable_box, \ | 491 | .enable_box = snbep_uncore_msr_enable_box, \ |
493 | .disable_event = snbep_uncore_msr_disable_event, \ | 492 | .disable_event = snbep_uncore_msr_disable_event, \ |
494 | .enable_event = snbep_uncore_msr_enable_event, \ | 493 | .enable_event = snbep_uncore_msr_enable_event, \ |
495 | .read_counter = uncore_msr_read_counter | 494 | .read_counter = uncore_msr_read_counter |
496 | 495 | ||
496 | #define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ | ||
497 | __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), \ | ||
498 | .init_box = snbep_uncore_msr_init_box \ | ||
499 | |||
497 | static struct intel_uncore_ops snbep_uncore_msr_ops = { | 500 | static struct intel_uncore_ops snbep_uncore_msr_ops = { |
498 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), | 501 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), |
499 | }; | 502 | }; |
@@ -1919,6 +1922,30 @@ static struct intel_uncore_type hswep_uncore_cbox = { | |||
1919 | .format_group = &hswep_uncore_cbox_format_group, | 1922 | .format_group = &hswep_uncore_cbox_format_group, |
1920 | }; | 1923 | }; |
1921 | 1924 | ||
1925 | /* | ||
1926 | * Write SBOX Initialization register bit by bit to avoid spurious #GPs | ||
1927 | */ | ||
1928 | static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box) | ||
1929 | { | ||
1930 | unsigned msr = uncore_msr_box_ctl(box); | ||
1931 | |||
1932 | if (msr) { | ||
1933 | u64 init = SNBEP_PMON_BOX_CTL_INT; | ||
1934 | u64 flags = 0; | ||
1935 | int i; | ||
1936 | |||
1937 | for_each_set_bit(i, (unsigned long *)&init, 64) { | ||
1938 | flags |= (1ULL << i); | ||
1939 | wrmsrl(msr, flags); | ||
1940 | } | ||
1941 | } | ||
1942 | } | ||
1943 | |||
1944 | static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = { | ||
1945 | __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), | ||
1946 | .init_box = hswep_uncore_sbox_msr_init_box | ||
1947 | }; | ||
1948 | |||
1922 | static struct attribute *hswep_uncore_sbox_formats_attr[] = { | 1949 | static struct attribute *hswep_uncore_sbox_formats_attr[] = { |
1923 | &format_attr_event.attr, | 1950 | &format_attr_event.attr, |
1924 | &format_attr_umask.attr, | 1951 | &format_attr_umask.attr, |
@@ -1944,7 +1971,7 @@ static struct intel_uncore_type hswep_uncore_sbox = { | |||
1944 | .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK, | 1971 | .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK, |
1945 | .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL, | 1972 | .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL, |
1946 | .msr_offset = HSWEP_SBOX_MSR_OFFSET, | 1973 | .msr_offset = HSWEP_SBOX_MSR_OFFSET, |
1947 | .ops = &snbep_uncore_msr_ops, | 1974 | .ops = &hswep_uncore_sbox_msr_ops, |
1948 | .format_group = &hswep_uncore_sbox_format_group, | 1975 | .format_group = &hswep_uncore_sbox_format_group, |
1949 | }; | 1976 | }; |
1950 | 1977 | ||
@@ -2025,13 +2052,27 @@ static struct intel_uncore_type hswep_uncore_imc = { | |||
2025 | SNBEP_UNCORE_PCI_COMMON_INIT(), | 2052 | SNBEP_UNCORE_PCI_COMMON_INIT(), |
2026 | }; | 2053 | }; |
2027 | 2054 | ||
2055 | static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8}; | ||
2056 | |||
2057 | static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) | ||
2058 | { | ||
2059 | struct pci_dev *pdev = box->pci_dev; | ||
2060 | struct hw_perf_event *hwc = &event->hw; | ||
2061 | u64 count = 0; | ||
2062 | |||
2063 | pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count); | ||
2064 | pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); | ||
2065 | |||
2066 | return count; | ||
2067 | } | ||
2068 | |||
2028 | static struct intel_uncore_ops hswep_uncore_irp_ops = { | 2069 | static struct intel_uncore_ops hswep_uncore_irp_ops = { |
2029 | .init_box = snbep_uncore_pci_init_box, | 2070 | .init_box = snbep_uncore_pci_init_box, |
2030 | .disable_box = snbep_uncore_pci_disable_box, | 2071 | .disable_box = snbep_uncore_pci_disable_box, |
2031 | .enable_box = snbep_uncore_pci_enable_box, | 2072 | .enable_box = snbep_uncore_pci_enable_box, |
2032 | .disable_event = ivbep_uncore_irp_disable_event, | 2073 | .disable_event = ivbep_uncore_irp_disable_event, |
2033 | .enable_event = ivbep_uncore_irp_enable_event, | 2074 | .enable_event = ivbep_uncore_irp_enable_event, |
2034 | .read_counter = ivbep_uncore_irp_read_counter, | 2075 | .read_counter = hswep_uncore_irp_read_counter, |
2035 | }; | 2076 | }; |
2036 | 2077 | ||
2037 | static struct intel_uncore_type hswep_uncore_irp = { | 2078 | static struct intel_uncore_type hswep_uncore_irp = { |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 1abcb50b48ae..ff86f19b5758 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -24,7 +24,6 @@ static char x86_stack_ids[][8] = { | |||
24 | [ DEBUG_STACK-1 ] = "#DB", | 24 | [ DEBUG_STACK-1 ] = "#DB", |
25 | [ NMI_STACK-1 ] = "NMI", | 25 | [ NMI_STACK-1 ] = "NMI", |
26 | [ DOUBLEFAULT_STACK-1 ] = "#DF", | 26 | [ DOUBLEFAULT_STACK-1 ] = "#DF", |
27 | [ STACKFAULT_STACK-1 ] = "#SS", | ||
28 | [ MCE_STACK-1 ] = "#MC", | 27 | [ MCE_STACK-1 ] = "#MC", |
29 | #if DEBUG_STKSZ > EXCEPTION_STKSZ | 28 | #if DEBUG_STKSZ > EXCEPTION_STKSZ |
30 | [ N_EXCEPTION_STACKS ... | 29 | [ N_EXCEPTION_STACKS ... |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index df088bb03fb3..c0226ab54106 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -828,9 +828,15 @@ ENTRY(native_iret) | |||
828 | jnz native_irq_return_ldt | 828 | jnz native_irq_return_ldt |
829 | #endif | 829 | #endif |
830 | 830 | ||
831 | .global native_irq_return_iret | ||
831 | native_irq_return_iret: | 832 | native_irq_return_iret: |
833 | /* | ||
834 | * This may fault. Non-paranoid faults on return to userspace are | ||
835 | * handled by fixup_bad_iret. These include #SS, #GP, and #NP. | ||
836 | * Double-faults due to espfix64 are handled in do_double_fault. | ||
837 | * Other faults here are fatal. | ||
838 | */ | ||
832 | iretq | 839 | iretq |
833 | _ASM_EXTABLE(native_irq_return_iret, bad_iret) | ||
834 | 840 | ||
835 | #ifdef CONFIG_X86_ESPFIX64 | 841 | #ifdef CONFIG_X86_ESPFIX64 |
836 | native_irq_return_ldt: | 842 | native_irq_return_ldt: |
@@ -858,25 +864,6 @@ native_irq_return_ldt: | |||
858 | jmp native_irq_return_iret | 864 | jmp native_irq_return_iret |
859 | #endif | 865 | #endif |
860 | 866 | ||
861 | .section .fixup,"ax" | ||
862 | bad_iret: | ||
863 | /* | ||
864 | * The iret traps when the %cs or %ss being restored is bogus. | ||
865 | * We've lost the original trap vector and error code. | ||
866 | * #GPF is the most likely one to get for an invalid selector. | ||
867 | * So pretend we completed the iret and took the #GPF in user mode. | ||
868 | * | ||
869 | * We are now running with the kernel GS after exception recovery. | ||
870 | * But error_entry expects us to have user GS to match the user %cs, | ||
871 | * so swap back. | ||
872 | */ | ||
873 | pushq $0 | ||
874 | |||
875 | SWAPGS | ||
876 | jmp general_protection | ||
877 | |||
878 | .previous | ||
879 | |||
880 | /* edi: workmask, edx: work */ | 867 | /* edi: workmask, edx: work */ |
881 | retint_careful: | 868 | retint_careful: |
882 | CFI_RESTORE_STATE | 869 | CFI_RESTORE_STATE |
@@ -922,37 +909,6 @@ ENTRY(retint_kernel) | |||
922 | CFI_ENDPROC | 909 | CFI_ENDPROC |
923 | END(common_interrupt) | 910 | END(common_interrupt) |
924 | 911 | ||
925 | /* | ||
926 | * If IRET takes a fault on the espfix stack, then we | ||
927 | * end up promoting it to a doublefault. In that case, | ||
928 | * modify the stack to make it look like we just entered | ||
929 | * the #GP handler from user space, similar to bad_iret. | ||
930 | */ | ||
931 | #ifdef CONFIG_X86_ESPFIX64 | ||
932 | ALIGN | ||
933 | __do_double_fault: | ||
934 | XCPT_FRAME 1 RDI+8 | ||
935 | movq RSP(%rdi),%rax /* Trap on the espfix stack? */ | ||
936 | sarq $PGDIR_SHIFT,%rax | ||
937 | cmpl $ESPFIX_PGD_ENTRY,%eax | ||
938 | jne do_double_fault /* No, just deliver the fault */ | ||
939 | cmpl $__KERNEL_CS,CS(%rdi) | ||
940 | jne do_double_fault | ||
941 | movq RIP(%rdi),%rax | ||
942 | cmpq $native_irq_return_iret,%rax | ||
943 | jne do_double_fault /* This shouldn't happen... */ | ||
944 | movq PER_CPU_VAR(kernel_stack),%rax | ||
945 | subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */ | ||
946 | movq %rax,RSP(%rdi) | ||
947 | movq $0,(%rax) /* Missing (lost) #GP error code */ | ||
948 | movq $general_protection,RIP(%rdi) | ||
949 | retq | ||
950 | CFI_ENDPROC | ||
951 | END(__do_double_fault) | ||
952 | #else | ||
953 | # define __do_double_fault do_double_fault | ||
954 | #endif | ||
955 | |||
956 | /* | 912 | /* |
957 | * APIC interrupts. | 913 | * APIC interrupts. |
958 | */ | 914 | */ |
@@ -1124,7 +1080,7 @@ idtentry overflow do_overflow has_error_code=0 | |||
1124 | idtentry bounds do_bounds has_error_code=0 | 1080 | idtentry bounds do_bounds has_error_code=0 |
1125 | idtentry invalid_op do_invalid_op has_error_code=0 | 1081 | idtentry invalid_op do_invalid_op has_error_code=0 |
1126 | idtentry device_not_available do_device_not_available has_error_code=0 | 1082 | idtentry device_not_available do_device_not_available has_error_code=0 |
1127 | idtentry double_fault __do_double_fault has_error_code=1 paranoid=1 | 1083 | idtentry double_fault do_double_fault has_error_code=1 paranoid=1 |
1128 | idtentry coprocessor_segment_overrun do_coprocessor_segment_overrun has_error_code=0 | 1084 | idtentry coprocessor_segment_overrun do_coprocessor_segment_overrun has_error_code=0 |
1129 | idtentry invalid_TSS do_invalid_TSS has_error_code=1 | 1085 | idtentry invalid_TSS do_invalid_TSS has_error_code=1 |
1130 | idtentry segment_not_present do_segment_not_present has_error_code=1 | 1086 | idtentry segment_not_present do_segment_not_present has_error_code=1 |
@@ -1289,7 +1245,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ | |||
1289 | 1245 | ||
1290 | idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK | 1246 | idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK |
1291 | idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK | 1247 | idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK |
1292 | idtentry stack_segment do_stack_segment has_error_code=1 paranoid=1 | 1248 | idtentry stack_segment do_stack_segment has_error_code=1 |
1293 | #ifdef CONFIG_XEN | 1249 | #ifdef CONFIG_XEN |
1294 | idtentry xen_debug do_debug has_error_code=0 | 1250 | idtentry xen_debug do_debug has_error_code=0 |
1295 | idtentry xen_int3 do_int3 has_error_code=0 | 1251 | idtentry xen_int3 do_int3 has_error_code=0 |
@@ -1399,17 +1355,16 @@ error_sti: | |||
1399 | 1355 | ||
1400 | /* | 1356 | /* |
1401 | * There are two places in the kernel that can potentially fault with | 1357 | * There are two places in the kernel that can potentially fault with |
1402 | * usergs. Handle them here. The exception handlers after iret run with | 1358 | * usergs. Handle them here. B stepping K8s sometimes report a |
1403 | * kernel gs again, so don't set the user space flag. B stepping K8s | 1359 | * truncated RIP for IRET exceptions returning to compat mode. Check |
1404 | * sometimes report an truncated RIP for IRET exceptions returning to | 1360 | * for these here too. |
1405 | * compat mode. Check for these here too. | ||
1406 | */ | 1361 | */ |
1407 | error_kernelspace: | 1362 | error_kernelspace: |
1408 | CFI_REL_OFFSET rcx, RCX+8 | 1363 | CFI_REL_OFFSET rcx, RCX+8 |
1409 | incl %ebx | 1364 | incl %ebx |
1410 | leaq native_irq_return_iret(%rip),%rcx | 1365 | leaq native_irq_return_iret(%rip),%rcx |
1411 | cmpq %rcx,RIP+8(%rsp) | 1366 | cmpq %rcx,RIP+8(%rsp) |
1412 | je error_swapgs | 1367 | je error_bad_iret |
1413 | movl %ecx,%eax /* zero extend */ | 1368 | movl %ecx,%eax /* zero extend */ |
1414 | cmpq %rax,RIP+8(%rsp) | 1369 | cmpq %rax,RIP+8(%rsp) |
1415 | je bstep_iret | 1370 | je bstep_iret |
@@ -1420,7 +1375,15 @@ error_kernelspace: | |||
1420 | bstep_iret: | 1375 | bstep_iret: |
1421 | /* Fix truncated RIP */ | 1376 | /* Fix truncated RIP */ |
1422 | movq %rcx,RIP+8(%rsp) | 1377 | movq %rcx,RIP+8(%rsp) |
1423 | jmp error_swapgs | 1378 | /* fall through */ |
1379 | |||
1380 | error_bad_iret: | ||
1381 | SWAPGS | ||
1382 | mov %rsp,%rdi | ||
1383 | call fixup_bad_iret | ||
1384 | mov %rax,%rsp | ||
1385 | decl %ebx /* Return to usergs */ | ||
1386 | jmp error_sti | ||
1424 | CFI_ENDPROC | 1387 | CFI_ENDPROC |
1425 | END(error_entry) | 1388 | END(error_entry) |
1426 | 1389 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 749b0e423419..e510618b2e91 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -1484,7 +1484,7 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch) | |||
1484 | */ | 1484 | */ |
1485 | if (work & _TIF_NOHZ) { | 1485 | if (work & _TIF_NOHZ) { |
1486 | user_exit(); | 1486 | user_exit(); |
1487 | work &= ~TIF_NOHZ; | 1487 | work &= ~_TIF_NOHZ; |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | #ifdef CONFIG_SECCOMP | 1490 | #ifdef CONFIG_SECCOMP |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 0d0e922fafc1..de801f22128a 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -233,32 +233,40 @@ DO_ERROR(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op) | |||
233 | DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun) | 233 | DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun) |
234 | DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS) | 234 | DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS) |
235 | DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present) | 235 | DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present) |
236 | #ifdef CONFIG_X86_32 | ||
237 | DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment) | 236 | DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment) |
238 | #endif | ||
239 | DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check) | 237 | DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check) |
240 | 238 | ||
241 | #ifdef CONFIG_X86_64 | 239 | #ifdef CONFIG_X86_64 |
242 | /* Runs on IST stack */ | 240 | /* Runs on IST stack */ |
243 | dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) | ||
244 | { | ||
245 | enum ctx_state prev_state; | ||
246 | |||
247 | prev_state = exception_enter(); | ||
248 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, | ||
249 | X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) { | ||
250 | preempt_conditional_sti(regs); | ||
251 | do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL); | ||
252 | preempt_conditional_cli(regs); | ||
253 | } | ||
254 | exception_exit(prev_state); | ||
255 | } | ||
256 | |||
257 | dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | 241 | dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) |
258 | { | 242 | { |
259 | static const char str[] = "double fault"; | 243 | static const char str[] = "double fault"; |
260 | struct task_struct *tsk = current; | 244 | struct task_struct *tsk = current; |
261 | 245 | ||
246 | #ifdef CONFIG_X86_ESPFIX64 | ||
247 | extern unsigned char native_irq_return_iret[]; | ||
248 | |||
249 | /* | ||
250 | * If IRET takes a non-IST fault on the espfix64 stack, then we | ||
251 | * end up promoting it to a doublefault. In that case, modify | ||
252 | * the stack to make it look like we just entered the #GP | ||
253 | * handler from user space, similar to bad_iret. | ||
254 | */ | ||
255 | if (((long)regs->sp >> PGDIR_SHIFT) == ESPFIX_PGD_ENTRY && | ||
256 | regs->cs == __KERNEL_CS && | ||
257 | regs->ip == (unsigned long)native_irq_return_iret) | ||
258 | { | ||
259 | struct pt_regs *normal_regs = task_pt_regs(current); | ||
260 | |||
261 | /* Fake a #GP(0) from userspace. */ | ||
262 | memmove(&normal_regs->ip, (void *)regs->sp, 5*8); | ||
263 | normal_regs->orig_ax = 0; /* Missing (lost) #GP error code */ | ||
264 | regs->ip = (unsigned long)general_protection; | ||
265 | regs->sp = (unsigned long)&normal_regs->orig_ax; | ||
266 | return; | ||
267 | } | ||
268 | #endif | ||
269 | |||
262 | exception_enter(); | 270 | exception_enter(); |
263 | /* Return not checked because double check cannot be ignored */ | 271 | /* Return not checked because double check cannot be ignored */ |
264 | notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); | 272 | notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); |
@@ -399,6 +407,35 @@ asmlinkage __visible struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
399 | return regs; | 407 | return regs; |
400 | } | 408 | } |
401 | NOKPROBE_SYMBOL(sync_regs); | 409 | NOKPROBE_SYMBOL(sync_regs); |
410 | |||
411 | struct bad_iret_stack { | ||
412 | void *error_entry_ret; | ||
413 | struct pt_regs regs; | ||
414 | }; | ||
415 | |||
416 | asmlinkage __visible | ||
417 | struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s) | ||
418 | { | ||
419 | /* | ||
420 | * This is called from entry_64.S early in handling a fault | ||
421 | * caused by a bad iret to user mode. To handle the fault | ||
422 | * correctly, we want move our stack frame to task_pt_regs | ||
423 | * and we want to pretend that the exception came from the | ||
424 | * iret target. | ||
425 | */ | ||
426 | struct bad_iret_stack *new_stack = | ||
427 | container_of(task_pt_regs(current), | ||
428 | struct bad_iret_stack, regs); | ||
429 | |||
430 | /* Copy the IRET target to the new stack. */ | ||
431 | memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8); | ||
432 | |||
433 | /* Copy the remainder of the stack from the current stack. */ | ||
434 | memmove(new_stack, s, offsetof(struct bad_iret_stack, regs.ip)); | ||
435 | |||
436 | BUG_ON(!user_mode_vm(&new_stack->regs)); | ||
437 | return new_stack; | ||
438 | } | ||
402 | #endif | 439 | #endif |
403 | 440 | ||
404 | /* | 441 | /* |
@@ -778,7 +815,7 @@ void __init trap_init(void) | |||
778 | set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun); | 815 | set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun); |
779 | set_intr_gate(X86_TRAP_TS, invalid_TSS); | 816 | set_intr_gate(X86_TRAP_TS, invalid_TSS); |
780 | set_intr_gate(X86_TRAP_NP, segment_not_present); | 817 | set_intr_gate(X86_TRAP_NP, segment_not_present); |
781 | set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK); | 818 | set_intr_gate(X86_TRAP_SS, stack_segment); |
782 | set_intr_gate(X86_TRAP_GP, general_protection); | 819 | set_intr_gate(X86_TRAP_GP, general_protection); |
783 | set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug); | 820 | set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug); |
784 | set_intr_gate(X86_TRAP_MF, coprocessor_error); | 821 | set_intr_gate(X86_TRAP_MF, coprocessor_error); |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ac1c4de3a484..978f402006ee 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -630,7 +630,7 @@ static int mmu_spte_clear_track_bits(u64 *sptep) | |||
630 | * kvm mmu, before reclaiming the page, we should | 630 | * kvm mmu, before reclaiming the page, we should |
631 | * unmap it from mmu first. | 631 | * unmap it from mmu first. |
632 | */ | 632 | */ |
633 | WARN_ON(!kvm_is_mmio_pfn(pfn) && !page_count(pfn_to_page(pfn))); | 633 | WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn))); |
634 | 634 | ||
635 | if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) | 635 | if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) |
636 | kvm_set_pfn_accessed(pfn); | 636 | kvm_set_pfn_accessed(pfn); |
@@ -2461,7 +2461,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
2461 | spte |= PT_PAGE_SIZE_MASK; | 2461 | spte |= PT_PAGE_SIZE_MASK; |
2462 | if (tdp_enabled) | 2462 | if (tdp_enabled) |
2463 | spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, | 2463 | spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, |
2464 | kvm_is_mmio_pfn(pfn)); | 2464 | kvm_is_reserved_pfn(pfn)); |
2465 | 2465 | ||
2466 | if (host_writable) | 2466 | if (host_writable) |
2467 | spte |= SPTE_HOST_WRITEABLE; | 2467 | spte |= SPTE_HOST_WRITEABLE; |
@@ -2737,7 +2737,7 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu, | |||
2737 | * PT_PAGE_TABLE_LEVEL and there would be no adjustment done | 2737 | * PT_PAGE_TABLE_LEVEL and there would be no adjustment done |
2738 | * here. | 2738 | * here. |
2739 | */ | 2739 | */ |
2740 | if (!is_error_noslot_pfn(pfn) && !kvm_is_mmio_pfn(pfn) && | 2740 | if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn) && |
2741 | level == PT_PAGE_TABLE_LEVEL && | 2741 | level == PT_PAGE_TABLE_LEVEL && |
2742 | PageTransCompound(pfn_to_page(pfn)) && | 2742 | PageTransCompound(pfn_to_page(pfn)) && |
2743 | !has_wrprotected_page(vcpu->kvm, gfn, PT_DIRECTORY_LEVEL)) { | 2743 | !has_wrprotected_page(vcpu->kvm, gfn, PT_DIRECTORY_LEVEL)) { |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 4cb8763868fc..4e5dfec750fc 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -1123,7 +1123,7 @@ void mark_rodata_ro(void) | |||
1123 | unsigned long end = (unsigned long) &__end_rodata_hpage_align; | 1123 | unsigned long end = (unsigned long) &__end_rodata_hpage_align; |
1124 | unsigned long text_end = PFN_ALIGN(&__stop___ex_table); | 1124 | unsigned long text_end = PFN_ALIGN(&__stop___ex_table); |
1125 | unsigned long rodata_end = PFN_ALIGN(&__end_rodata); | 1125 | unsigned long rodata_end = PFN_ALIGN(&__end_rodata); |
1126 | unsigned long all_end = PFN_ALIGN(&_end); | 1126 | unsigned long all_end; |
1127 | 1127 | ||
1128 | printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", | 1128 | printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", |
1129 | (end - start) >> 10); | 1129 | (end - start) >> 10); |
@@ -1134,7 +1134,16 @@ void mark_rodata_ro(void) | |||
1134 | /* | 1134 | /* |
1135 | * The rodata/data/bss/brk section (but not the kernel text!) | 1135 | * The rodata/data/bss/brk section (but not the kernel text!) |
1136 | * should also be not-executable. | 1136 | * should also be not-executable. |
1137 | * | ||
1138 | * We align all_end to PMD_SIZE because the existing mapping | ||
1139 | * is a full PMD. If we would align _brk_end to PAGE_SIZE we | ||
1140 | * split the PMD and the reminder between _brk_end and the end | ||
1141 | * of the PMD will remain mapped executable. | ||
1142 | * | ||
1143 | * Any PMD which was setup after the one which covers _brk_end | ||
1144 | * has been zapped already via cleanup_highmem(). | ||
1137 | */ | 1145 | */ |
1146 | all_end = roundup((unsigned long)_brk_end, PMD_SIZE); | ||
1138 | set_memory_nx(rodata_start, (all_end - rodata_start) >> PAGE_SHIFT); | 1147 | set_memory_nx(rodata_start, (all_end - rodata_start) >> PAGE_SHIFT); |
1139 | 1148 | ||
1140 | rodata_test(); | 1149 | rodata_test(); |
diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl index 0b0b124d3ece..23210baade2d 100644 --- a/arch/x86/tools/calc_run_size.pl +++ b/arch/x86/tools/calc_run_size.pl | |||
@@ -19,7 +19,16 @@ while (<>) { | |||
19 | if ($file_offset == 0) { | 19 | if ($file_offset == 0) { |
20 | $file_offset = $offset; | 20 | $file_offset = $offset; |
21 | } elsif ($file_offset != $offset) { | 21 | } elsif ($file_offset != $offset) { |
22 | die ".bss and .brk lack common file offset\n"; | 22 | # BFD linker shows the same file offset in ELF. |
23 | # Gold linker shows them as consecutive. | ||
24 | next if ($file_offset + $mem_size == $offset + $size); | ||
25 | |||
26 | printf STDERR "file_offset: 0x%lx\n", $file_offset; | ||
27 | printf STDERR "mem_size: 0x%lx\n", $mem_size; | ||
28 | printf STDERR "offset: 0x%lx\n", $offset; | ||
29 | printf STDERR "size: 0x%lx\n", $size; | ||
30 | |||
31 | die ".bss and .brk are non-contiguous\n"; | ||
23 | } | 32 | } |
24 | } | 33 | } |
25 | } | 34 | } |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 143ec6ea1468..7db193160766 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -878,7 +878,7 @@ int acpi_dev_suspend_late(struct device *dev) | |||
878 | return 0; | 878 | return 0; |
879 | 879 | ||
880 | target_state = acpi_target_system_state(); | 880 | target_state = acpi_target_system_state(); |
881 | wakeup = device_may_wakeup(dev); | 881 | wakeup = device_may_wakeup(dev) && acpi_device_can_wakeup(adev); |
882 | error = acpi_device_wakeup(adev, target_state, wakeup); | 882 | error = acpi_device_wakeup(adev, target_state, wakeup); |
883 | if (wakeup && error) | 883 | if (wakeup && error) |
884 | return error; | 884 | return error; |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 7652e8dc188f..21b0bc6a9c96 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -1225,11 +1225,13 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1225 | card->config_regs = pci_iomap(dev, 0, CONFIG_RAM_SIZE); | 1225 | card->config_regs = pci_iomap(dev, 0, CONFIG_RAM_SIZE); |
1226 | if (!card->config_regs) { | 1226 | if (!card->config_regs) { |
1227 | dev_warn(&dev->dev, "Failed to ioremap config registers\n"); | 1227 | dev_warn(&dev->dev, "Failed to ioremap config registers\n"); |
1228 | err = -ENOMEM; | ||
1228 | goto out_release_regions; | 1229 | goto out_release_regions; |
1229 | } | 1230 | } |
1230 | card->buffers = pci_iomap(dev, 1, DATA_RAM_SIZE); | 1231 | card->buffers = pci_iomap(dev, 1, DATA_RAM_SIZE); |
1231 | if (!card->buffers) { | 1232 | if (!card->buffers) { |
1232 | dev_warn(&dev->dev, "Failed to ioremap data buffers\n"); | 1233 | dev_warn(&dev->dev, "Failed to ioremap data buffers\n"); |
1234 | err = -ENOMEM; | ||
1233 | goto out_unmap_config; | 1235 | goto out_unmap_config; |
1234 | } | 1236 | } |
1235 | 1237 | ||
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 24b5b020753a..a23ac0c724f0 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c | |||
@@ -52,29 +52,26 @@ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, | |||
52 | 52 | ||
53 | tmp = pmc_read(pmc, AT91_PMC_USB); | 53 | tmp = pmc_read(pmc, AT91_PMC_USB); |
54 | usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; | 54 | usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; |
55 | return parent_rate / (usbdiv + 1); | 55 | |
56 | return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); | ||
56 | } | 57 | } |
57 | 58 | ||
58 | static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, | 59 | static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, |
59 | unsigned long *parent_rate) | 60 | unsigned long *parent_rate) |
60 | { | 61 | { |
61 | unsigned long div; | 62 | unsigned long div; |
62 | unsigned long bestrate; | 63 | |
63 | unsigned long tmp; | 64 | if (!rate) |
65 | return -EINVAL; | ||
64 | 66 | ||
65 | if (rate >= *parent_rate) | 67 | if (rate >= *parent_rate) |
66 | return *parent_rate; | 68 | return *parent_rate; |
67 | 69 | ||
68 | div = *parent_rate / rate; | 70 | div = DIV_ROUND_CLOSEST(*parent_rate, rate); |
69 | if (div >= SAM9X5_USB_MAX_DIV) | 71 | if (div > SAM9X5_USB_MAX_DIV + 1) |
70 | return *parent_rate / (SAM9X5_USB_MAX_DIV + 1); | 72 | div = SAM9X5_USB_MAX_DIV + 1; |
71 | |||
72 | bestrate = *parent_rate / div; | ||
73 | tmp = *parent_rate / (div + 1); | ||
74 | if (bestrate - rate > rate - tmp) | ||
75 | bestrate = tmp; | ||
76 | 73 | ||
77 | return bestrate; | 74 | return DIV_ROUND_CLOSEST(*parent_rate, div); |
78 | } | 75 | } |
79 | 76 | ||
80 | static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) | 77 | static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) |
@@ -106,9 +103,13 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | |||
106 | u32 tmp; | 103 | u32 tmp; |
107 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 104 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
108 | struct at91_pmc *pmc = usb->pmc; | 105 | struct at91_pmc *pmc = usb->pmc; |
109 | unsigned long div = parent_rate / rate; | 106 | unsigned long div; |
107 | |||
108 | if (!rate) | ||
109 | return -EINVAL; | ||
110 | 110 | ||
111 | if (parent_rate % rate || div < 1 || div >= SAM9X5_USB_MAX_DIV) | 111 | div = DIV_ROUND_CLOSEST(parent_rate, rate); |
112 | if (div > SAM9X5_USB_MAX_DIV + 1 || !div) | ||
112 | return -EINVAL; | 113 | return -EINVAL; |
113 | 114 | ||
114 | tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; | 115 | tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; |
@@ -253,7 +254,7 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, | |||
253 | 254 | ||
254 | tmp_parent_rate = rate * usb->divisors[i]; | 255 | tmp_parent_rate = rate * usb->divisors[i]; |
255 | tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate); | 256 | tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate); |
256 | tmprate = tmp_parent_rate / usb->divisors[i]; | 257 | tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]); |
257 | if (tmprate < rate) | 258 | if (tmprate < rate) |
258 | tmpdiff = rate - tmprate; | 259 | tmpdiff = rate - tmprate; |
259 | else | 260 | else |
@@ -281,10 +282,10 @@ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | |||
281 | struct at91_pmc *pmc = usb->pmc; | 282 | struct at91_pmc *pmc = usb->pmc; |
282 | unsigned long div; | 283 | unsigned long div; |
283 | 284 | ||
284 | if (!rate || parent_rate % rate) | 285 | if (!rate) |
285 | return -EINVAL; | 286 | return -EINVAL; |
286 | 287 | ||
287 | div = parent_rate / rate; | 288 | div = DIV_ROUND_CLOSEST(parent_rate, rate); |
288 | 289 | ||
289 | for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { | 290 | for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { |
290 | if (usb->divisors[i] == div) { | 291 | if (usb->divisors[i] == div) { |
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 18a9de29df0e..c0a842b335c5 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -263,6 +263,14 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | |||
263 | if (!rate) | 263 | if (!rate) |
264 | rate = 1; | 264 | rate = 1; |
265 | 265 | ||
266 | /* if read only, just return current value */ | ||
267 | if (divider->flags & CLK_DIVIDER_READ_ONLY) { | ||
268 | bestdiv = readl(divider->reg) >> divider->shift; | ||
269 | bestdiv &= div_mask(divider); | ||
270 | bestdiv = _get_div(divider, bestdiv); | ||
271 | return bestdiv; | ||
272 | } | ||
273 | |||
266 | maxdiv = _get_maxdiv(divider); | 274 | maxdiv = _get_maxdiv(divider); |
267 | 275 | ||
268 | if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { | 276 | if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { |
@@ -361,11 +369,6 @@ const struct clk_ops clk_divider_ops = { | |||
361 | }; | 369 | }; |
362 | EXPORT_SYMBOL_GPL(clk_divider_ops); | 370 | EXPORT_SYMBOL_GPL(clk_divider_ops); |
363 | 371 | ||
364 | const struct clk_ops clk_divider_ro_ops = { | ||
365 | .recalc_rate = clk_divider_recalc_rate, | ||
366 | }; | ||
367 | EXPORT_SYMBOL_GPL(clk_divider_ro_ops); | ||
368 | |||
369 | static struct clk *_register_divider(struct device *dev, const char *name, | 372 | static struct clk *_register_divider(struct device *dev, const char *name, |
370 | const char *parent_name, unsigned long flags, | 373 | const char *parent_name, unsigned long flags, |
371 | void __iomem *reg, u8 shift, u8 width, | 374 | void __iomem *reg, u8 shift, u8 width, |
@@ -391,10 +394,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, | |||
391 | } | 394 | } |
392 | 395 | ||
393 | init.name = name; | 396 | init.name = name; |
394 | if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) | 397 | init.ops = &clk_divider_ops; |
395 | init.ops = &clk_divider_ro_ops; | ||
396 | else | ||
397 | init.ops = &clk_divider_ops; | ||
398 | init.flags = flags | CLK_IS_BASIC; | 398 | init.flags = flags | CLK_IS_BASIC; |
399 | init.parent_names = (parent_name ? &parent_name: NULL); | 399 | init.parent_names = (parent_name ? &parent_name: NULL); |
400 | init.num_parents = (parent_name ? 1 : 0); | 400 | init.num_parents = (parent_name ? 1 : 0); |
diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index b345cc791e5d..88b9fe13fa44 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c | |||
@@ -322,7 +322,7 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, | |||
322 | unsigned long ccsr = CCSR; | 322 | unsigned long ccsr = CCSR; |
323 | 323 | ||
324 | osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); | 324 | osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); |
325 | a = cccr & CCCR_A_BIT; | 325 | a = cccr & (1 << CCCR_A_BIT); |
326 | l = ccsr & CCSR_L_MASK; | 326 | l = ccsr & CCSR_L_MASK; |
327 | 327 | ||
328 | if (osc_forced || a) | 328 | if (osc_forced || a) |
@@ -341,7 +341,7 @@ static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) | |||
341 | unsigned long ccsr = CCSR; | 341 | unsigned long ccsr = CCSR; |
342 | 342 | ||
343 | osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); | 343 | osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); |
344 | a = cccr & CCCR_A_BIT; | 344 | a = cccr & (1 << CCCR_A_BIT); |
345 | if (osc_forced) | 345 | if (osc_forced) |
346 | return PXA_MEM_13Mhz; | 346 | return PXA_MEM_13Mhz; |
347 | if (a) | 347 | if (a) |
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index dab988ab8cf1..157139a5c1ca 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c | |||
@@ -3122,7 +3122,7 @@ static struct clk_regmap *mmcc_apq8084_clocks[] = { | |||
3122 | [ESC1_CLK_SRC] = &esc1_clk_src.clkr, | 3122 | [ESC1_CLK_SRC] = &esc1_clk_src.clkr, |
3123 | [HDMI_CLK_SRC] = &hdmi_clk_src.clkr, | 3123 | [HDMI_CLK_SRC] = &hdmi_clk_src.clkr, |
3124 | [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, | 3124 | [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, |
3125 | [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, | 3125 | [MMSS_RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, |
3126 | [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, | 3126 | [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, |
3127 | [MAPLE_CLK_SRC] = &maple_clk_src.clkr, | 3127 | [MAPLE_CLK_SRC] = &maple_clk_src.clkr, |
3128 | [VDP_CLK_SRC] = &vdp_clk_src.clkr, | 3128 | [VDP_CLK_SRC] = &vdp_clk_src.clkr, |
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 1e68bff481b8..880a266f0143 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c | |||
@@ -90,9 +90,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, | |||
90 | div->width = div_width; | 90 | div->width = div_width; |
91 | div->lock = lock; | 91 | div->lock = lock; |
92 | div->table = div_table; | 92 | div->table = div_table; |
93 | div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) | 93 | div_ops = &clk_divider_ops; |
94 | ? &clk_divider_ro_ops | ||
95 | : &clk_divider_ops; | ||
96 | } | 94 | } |
97 | 95 | ||
98 | clk = clk_register_composite(NULL, name, parent_names, num_parents, | 96 | clk = clk_register_composite(NULL, name, parent_names, num_parents, |
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c index efb17c3ee120..f4a9c0058b4d 100644 --- a/drivers/clocksource/sun4i_timer.c +++ b/drivers/clocksource/sun4i_timer.c | |||
@@ -182,6 +182,12 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
182 | /* Make sure timer is stopped before playing with interrupts */ | 182 | /* Make sure timer is stopped before playing with interrupts */ |
183 | sun4i_clkevt_time_stop(0); | 183 | sun4i_clkevt_time_stop(0); |
184 | 184 | ||
185 | sun4i_clockevent.cpumask = cpu_possible_mask; | ||
186 | sun4i_clockevent.irq = irq; | ||
187 | |||
188 | clockevents_config_and_register(&sun4i_clockevent, rate, | ||
189 | TIMER_SYNC_TICKS, 0xffffffff); | ||
190 | |||
185 | ret = setup_irq(irq, &sun4i_timer_irq); | 191 | ret = setup_irq(irq, &sun4i_timer_irq); |
186 | if (ret) | 192 | if (ret) |
187 | pr_warn("failed to setup irq %d\n", irq); | 193 | pr_warn("failed to setup irq %d\n", irq); |
@@ -189,12 +195,6 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
189 | /* Enable timer0 interrupt */ | 195 | /* Enable timer0 interrupt */ |
190 | val = readl(timer_base + TIMER_IRQ_EN_REG); | 196 | val = readl(timer_base + TIMER_IRQ_EN_REG); |
191 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); | 197 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); |
192 | |||
193 | sun4i_clockevent.cpumask = cpu_possible_mask; | ||
194 | sun4i_clockevent.irq = irq; | ||
195 | |||
196 | clockevents_config_and_register(&sun4i_clockevent, rate, | ||
197 | TIMER_SYNC_TICKS, 0xffffffff); | ||
198 | } | 198 | } |
199 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer", | 199 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer", |
200 | sun4i_timer_init); | 200 | sun4i_timer_init); |
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 4839bfa74a10..19a99743cf52 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
@@ -271,7 +271,7 @@ struct pl330_config { | |||
271 | #define DMAC_MODE_NS (1 << 0) | 271 | #define DMAC_MODE_NS (1 << 0) |
272 | unsigned int mode; | 272 | unsigned int mode; |
273 | unsigned int data_bus_width:10; /* In number of bits */ | 273 | unsigned int data_bus_width:10; /* In number of bits */ |
274 | unsigned int data_buf_dep:10; | 274 | unsigned int data_buf_dep:11; |
275 | unsigned int num_chan:4; | 275 | unsigned int num_chan:4; |
276 | unsigned int num_peri:6; | 276 | unsigned int num_peri:6; |
277 | u32 peri_ns; | 277 | u32 peri_ns; |
@@ -2336,7 +2336,7 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) | |||
2336 | int burst_len; | 2336 | int burst_len; |
2337 | 2337 | ||
2338 | burst_len = pl330->pcfg.data_bus_width / 8; | 2338 | burst_len = pl330->pcfg.data_bus_width / 8; |
2339 | burst_len *= pl330->pcfg.data_buf_dep; | 2339 | burst_len *= pl330->pcfg.data_buf_dep / pl330->pcfg.num_chan; |
2340 | burst_len >>= desc->rqcfg.brst_size; | 2340 | burst_len >>= desc->rqcfg.brst_size; |
2341 | 2341 | ||
2342 | /* src/dst_burst_len can't be more than 16 */ | 2342 | /* src/dst_burst_len can't be more than 16 */ |
@@ -2459,16 +2459,25 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, | |||
2459 | /* Select max possible burst size */ | 2459 | /* Select max possible burst size */ |
2460 | burst = pl330->pcfg.data_bus_width / 8; | 2460 | burst = pl330->pcfg.data_bus_width / 8; |
2461 | 2461 | ||
2462 | while (burst > 1) { | 2462 | /* |
2463 | if (!(len % burst)) | 2463 | * Make sure we use a burst size that aligns with all the memcpy |
2464 | break; | 2464 | * parameters because our DMA programming algorithm doesn't cope with |
2465 | * transfers which straddle an entry in the DMA device's MFIFO. | ||
2466 | */ | ||
2467 | while ((src | dst | len) & (burst - 1)) | ||
2465 | burst /= 2; | 2468 | burst /= 2; |
2466 | } | ||
2467 | 2469 | ||
2468 | desc->rqcfg.brst_size = 0; | 2470 | desc->rqcfg.brst_size = 0; |
2469 | while (burst != (1 << desc->rqcfg.brst_size)) | 2471 | while (burst != (1 << desc->rqcfg.brst_size)) |
2470 | desc->rqcfg.brst_size++; | 2472 | desc->rqcfg.brst_size++; |
2471 | 2473 | ||
2474 | /* | ||
2475 | * If burst size is smaller than bus width then make sure we only | ||
2476 | * transfer one at a time to avoid a burst stradling an MFIFO entry. | ||
2477 | */ | ||
2478 | if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width) | ||
2479 | desc->rqcfg.brst_len = 1; | ||
2480 | |||
2472 | desc->rqcfg.brst_len = get_burst_len(desc, len); | 2481 | desc->rqcfg.brst_len = get_burst_len(desc, len); |
2473 | 2482 | ||
2474 | desc->txd.flags = flags; | 2483 | desc->txd.flags = flags; |
@@ -2732,7 +2741,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) | |||
2732 | 2741 | ||
2733 | 2742 | ||
2734 | dev_info(&adev->dev, | 2743 | dev_info(&adev->dev, |
2735 | "Loaded driver for PL330 DMAC-%d\n", adev->periphid); | 2744 | "Loaded driver for PL330 DMAC-%x\n", adev->periphid); |
2736 | dev_info(&adev->dev, | 2745 | dev_info(&adev->dev, |
2737 | "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", | 2746 | "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", |
2738 | pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan, | 2747 | pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan, |
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 3aa10b328254..91292f5513ff 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c | |||
@@ -230,30 +230,25 @@ static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev, | |||
230 | readl(pchan->base + DMA_CHAN_CUR_PARA)); | 230 | readl(pchan->base + DMA_CHAN_CUR_PARA)); |
231 | } | 231 | } |
232 | 232 | ||
233 | static inline int convert_burst(u32 maxburst, u8 *burst) | 233 | static inline s8 convert_burst(u32 maxburst) |
234 | { | 234 | { |
235 | switch (maxburst) { | 235 | switch (maxburst) { |
236 | case 1: | 236 | case 1: |
237 | *burst = 0; | 237 | return 0; |
238 | break; | ||
239 | case 8: | 238 | case 8: |
240 | *burst = 2; | 239 | return 2; |
241 | break; | ||
242 | default: | 240 | default: |
243 | return -EINVAL; | 241 | return -EINVAL; |
244 | } | 242 | } |
245 | |||
246 | return 0; | ||
247 | } | 243 | } |
248 | 244 | ||
249 | static inline int convert_buswidth(enum dma_slave_buswidth addr_width, u8 *width) | 245 | static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width) |
250 | { | 246 | { |
251 | if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) || | 247 | if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) || |
252 | (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES)) | 248 | (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES)) |
253 | return -EINVAL; | 249 | return -EINVAL; |
254 | 250 | ||
255 | *width = addr_width >> 1; | 251 | return addr_width >> 1; |
256 | return 0; | ||
257 | } | 252 | } |
258 | 253 | ||
259 | static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev, | 254 | static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev, |
@@ -284,26 +279,25 @@ static inline int sun6i_dma_cfg_lli(struct sun6i_dma_lli *lli, | |||
284 | struct dma_slave_config *config) | 279 | struct dma_slave_config *config) |
285 | { | 280 | { |
286 | u8 src_width, dst_width, src_burst, dst_burst; | 281 | u8 src_width, dst_width, src_burst, dst_burst; |
287 | int ret; | ||
288 | 282 | ||
289 | if (!config) | 283 | if (!config) |
290 | return -EINVAL; | 284 | return -EINVAL; |
291 | 285 | ||
292 | ret = convert_burst(config->src_maxburst, &src_burst); | 286 | src_burst = convert_burst(config->src_maxburst); |
293 | if (ret) | 287 | if (src_burst) |
294 | return ret; | 288 | return src_burst; |
295 | 289 | ||
296 | ret = convert_burst(config->dst_maxburst, &dst_burst); | 290 | dst_burst = convert_burst(config->dst_maxburst); |
297 | if (ret) | 291 | if (dst_burst) |
298 | return ret; | 292 | return dst_burst; |
299 | 293 | ||
300 | ret = convert_buswidth(config->src_addr_width, &src_width); | 294 | src_width = convert_buswidth(config->src_addr_width); |
301 | if (ret) | 295 | if (src_width) |
302 | return ret; | 296 | return src_width; |
303 | 297 | ||
304 | ret = convert_buswidth(config->dst_addr_width, &dst_width); | 298 | dst_width = convert_buswidth(config->dst_addr_width); |
305 | if (ret) | 299 | if (dst_width) |
306 | return ret; | 300 | return dst_width; |
307 | 301 | ||
308 | lli->cfg = DMA_CHAN_CFG_SRC_BURST(src_burst) | | 302 | lli->cfg = DMA_CHAN_CFG_SRC_BURST(src_burst) | |
309 | DMA_CHAN_CFG_SRC_WIDTH(src_width) | | 303 | DMA_CHAN_CFG_SRC_WIDTH(src_width) | |
@@ -542,11 +536,10 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( | |||
542 | { | 536 | { |
543 | struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device); | 537 | struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device); |
544 | struct sun6i_vchan *vchan = to_sun6i_vchan(chan); | 538 | struct sun6i_vchan *vchan = to_sun6i_vchan(chan); |
545 | struct dma_slave_config *sconfig = &vchan->cfg; | ||
546 | struct sun6i_dma_lli *v_lli; | 539 | struct sun6i_dma_lli *v_lli; |
547 | struct sun6i_desc *txd; | 540 | struct sun6i_desc *txd; |
548 | dma_addr_t p_lli; | 541 | dma_addr_t p_lli; |
549 | int ret; | 542 | s8 burst, width; |
550 | 543 | ||
551 | dev_dbg(chan2dev(chan), | 544 | dev_dbg(chan2dev(chan), |
552 | "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", | 545 | "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", |
@@ -565,14 +558,21 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( | |||
565 | goto err_txd_free; | 558 | goto err_txd_free; |
566 | } | 559 | } |
567 | 560 | ||
568 | ret = sun6i_dma_cfg_lli(v_lli, src, dest, len, sconfig); | 561 | v_lli->src = src; |
569 | if (ret) | 562 | v_lli->dst = dest; |
570 | goto err_dma_free; | 563 | v_lli->len = len; |
564 | v_lli->para = NORMAL_WAIT; | ||
571 | 565 | ||
566 | burst = convert_burst(8); | ||
567 | width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); | ||
572 | v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | | 568 | v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
573 | DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | | 569 | DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
574 | DMA_CHAN_CFG_DST_LINEAR_MODE | | 570 | DMA_CHAN_CFG_DST_LINEAR_MODE | |
575 | DMA_CHAN_CFG_SRC_LINEAR_MODE; | 571 | DMA_CHAN_CFG_SRC_LINEAR_MODE | |
572 | DMA_CHAN_CFG_SRC_BURST(burst) | | ||
573 | DMA_CHAN_CFG_SRC_WIDTH(width) | | ||
574 | DMA_CHAN_CFG_DST_BURST(burst) | | ||
575 | DMA_CHAN_CFG_DST_WIDTH(width); | ||
576 | 576 | ||
577 | sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); | 577 | sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); |
578 | 578 | ||
@@ -580,8 +580,6 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( | |||
580 | 580 | ||
581 | return vchan_tx_prep(&vchan->vc, &txd->vd, flags); | 581 | return vchan_tx_prep(&vchan->vc, &txd->vd, flags); |
582 | 582 | ||
583 | err_dma_free: | ||
584 | dma_pool_free(sdev->pool, v_lli, p_lli); | ||
585 | err_txd_free: | 583 | err_txd_free: |
586 | kfree(txd); | 584 | kfree(txd); |
587 | return NULL; | 585 | return NULL; |
@@ -915,6 +913,7 @@ static int sun6i_dma_probe(struct platform_device *pdev) | |||
915 | sdc->slave.device_prep_dma_memcpy = sun6i_dma_prep_dma_memcpy; | 913 | sdc->slave.device_prep_dma_memcpy = sun6i_dma_prep_dma_memcpy; |
916 | sdc->slave.device_control = sun6i_dma_control; | 914 | sdc->slave.device_control = sun6i_dma_control; |
917 | sdc->slave.chancnt = NR_MAX_VCHANS; | 915 | sdc->slave.chancnt = NR_MAX_VCHANS; |
916 | sdc->slave.copy_align = 4; | ||
918 | 917 | ||
919 | sdc->slave.dev = &pdev->dev; | 918 | sdc->slave.dev = &pdev->dev; |
920 | 919 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1403b01e8216..318ade9bb5af 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1670,15 +1670,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1670 | goto out_regs; | 1670 | goto out_regs; |
1671 | 1671 | ||
1672 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1672 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1673 | ret = i915_kick_out_vgacon(dev_priv); | 1673 | /* WARNING: Apparently we must kick fbdev drivers before vgacon, |
1674 | * otherwise the vga fbdev driver falls over. */ | ||
1675 | ret = i915_kick_out_firmware_fb(dev_priv); | ||
1674 | if (ret) { | 1676 | if (ret) { |
1675 | DRM_ERROR("failed to remove conflicting VGA console\n"); | 1677 | DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); |
1676 | goto out_gtt; | 1678 | goto out_gtt; |
1677 | } | 1679 | } |
1678 | 1680 | ||
1679 | ret = i915_kick_out_firmware_fb(dev_priv); | 1681 | ret = i915_kick_out_vgacon(dev_priv); |
1680 | if (ret) { | 1682 | if (ret) { |
1681 | DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); | 1683 | DRM_ERROR("failed to remove conflicting VGA console\n"); |
1682 | goto out_gtt; | 1684 | goto out_gtt; |
1683 | } | 1685 | } |
1684 | } | 1686 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f0a1a56406eb..8bcdb981d540 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -9408,6 +9408,10 @@ static bool page_flip_finished(struct intel_crtc *crtc) | |||
9408 | struct drm_device *dev = crtc->base.dev; | 9408 | struct drm_device *dev = crtc->base.dev; |
9409 | struct drm_i915_private *dev_priv = dev->dev_private; | 9409 | struct drm_i915_private *dev_priv = dev->dev_private; |
9410 | 9410 | ||
9411 | if (i915_reset_in_progress(&dev_priv->gpu_error) || | ||
9412 | crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) | ||
9413 | return true; | ||
9414 | |||
9411 | /* | 9415 | /* |
9412 | * The relevant registers doen't exist on pre-ctg. | 9416 | * The relevant registers doen't exist on pre-ctg. |
9413 | * As the flip done interrupt doesn't trigger for mmio | 9417 | * As the flip done interrupt doesn't trigger for mmio |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5ad45bfff3fe..4bcd91757321 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -4450,6 +4450,7 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | |||
4450 | * vdd might still be enabled do to the delayed vdd off. | 4450 | * vdd might still be enabled do to the delayed vdd off. |
4451 | * Make sure vdd is actually turned off here. | 4451 | * Make sure vdd is actually turned off here. |
4452 | */ | 4452 | */ |
4453 | cancel_delayed_work_sync(&intel_dp->panel_vdd_work); | ||
4453 | pps_lock(intel_dp); | 4454 | pps_lock(intel_dp); |
4454 | edp_panel_vdd_off_sync(intel_dp); | 4455 | edp_panel_vdd_off_sync(intel_dp); |
4455 | pps_unlock(intel_dp); | 4456 | pps_unlock(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c27b6140bfd1..ad2fd605f76b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5469,11 +5469,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
5469 | I915_WRITE(_3D_CHICKEN, | 5469 | I915_WRITE(_3D_CHICKEN, |
5470 | _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); | 5470 | _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); |
5471 | 5471 | ||
5472 | /* WaSetupGtModeTdRowDispatch:snb */ | ||
5473 | if (IS_SNB_GT1(dev)) | ||
5474 | I915_WRITE(GEN6_GT_MODE, | ||
5475 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); | ||
5476 | |||
5477 | /* WaDisable_RenderCache_OperationalFlush:snb */ | 5472 | /* WaDisable_RenderCache_OperationalFlush:snb */ |
5478 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | 5473 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
5479 | 5474 | ||
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index f6309bd23e01..b5c73df8e202 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c | |||
@@ -1256,7 +1256,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) | |||
1256 | (mode_info->atom_context->bios + data_offset + | 1256 | (mode_info->atom_context->bios + data_offset + |
1257 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); | 1257 | le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); |
1258 | rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = | 1258 | rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = |
1259 | ppt->usMaximumPowerDeliveryLimit; | 1259 | le16_to_cpu(ppt->usMaximumPowerDeliveryLimit); |
1260 | pt = &ppt->power_tune_table; | 1260 | pt = &ppt->power_tune_table; |
1261 | } else { | 1261 | } else { |
1262 | ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *) | 1262 | ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *) |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 300c4b3d4669..26baa9c05f6c 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -322,6 +322,12 @@ static void radeon_connector_get_edid(struct drm_connector *connector) | |||
322 | } | 322 | } |
323 | 323 | ||
324 | if (!radeon_connector->edid) { | 324 | if (!radeon_connector->edid) { |
325 | /* don't fetch the edid from the vbios if ddc fails and runpm is | ||
326 | * enabled so we report disconnected. | ||
327 | */ | ||
328 | if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0)) | ||
329 | return; | ||
330 | |||
325 | if (rdev->is_atom_bios) { | 331 | if (rdev->is_atom_bios) { |
326 | /* some laptops provide a hardcoded edid in rom for LCDs */ | 332 | /* some laptops provide a hardcoded edid in rom for LCDs */ |
327 | if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || | 333 | if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || |
@@ -826,6 +832,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, | |||
826 | static enum drm_connector_status | 832 | static enum drm_connector_status |
827 | radeon_lvds_detect(struct drm_connector *connector, bool force) | 833 | radeon_lvds_detect(struct drm_connector *connector, bool force) |
828 | { | 834 | { |
835 | struct drm_device *dev = connector->dev; | ||
836 | struct radeon_device *rdev = dev->dev_private; | ||
829 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 837 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
830 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 838 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
831 | enum drm_connector_status ret = connector_status_disconnected; | 839 | enum drm_connector_status ret = connector_status_disconnected; |
@@ -842,7 +850,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
842 | /* check if panel is valid */ | 850 | /* check if panel is valid */ |
843 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) | 851 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) |
844 | ret = connector_status_connected; | 852 | ret = connector_status_connected; |
845 | 853 | /* don't fetch the edid from the vbios if ddc fails and runpm is | |
854 | * enabled so we report disconnected. | ||
855 | */ | ||
856 | if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0)) | ||
857 | ret = connector_status_disconnected; | ||
846 | } | 858 | } |
847 | 859 | ||
848 | /* check for edid as well */ | 860 | /* check for edid as well */ |
@@ -1589,6 +1601,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1589 | /* check if panel is valid */ | 1601 | /* check if panel is valid */ |
1590 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) | 1602 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) |
1591 | ret = connector_status_connected; | 1603 | ret = connector_status_connected; |
1604 | /* don't fetch the edid from the vbios if ddc fails and runpm is | ||
1605 | * enabled so we report disconnected. | ||
1606 | */ | ||
1607 | if ((rdev->flags & RADEON_IS_PX) && (radeon_runtime_pm != 0)) | ||
1608 | ret = connector_status_disconnected; | ||
1592 | } | 1609 | } |
1593 | /* eDP is always DP */ | 1610 | /* eDP is always DP */ |
1594 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; | 1611 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 9a19e52cc655..6b670b0bc47b 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -179,6 +179,9 @@ static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder, | |||
179 | (rdev->pdev->subsystem_vendor == 0x1734) && | 179 | (rdev->pdev->subsystem_vendor == 0x1734) && |
180 | (rdev->pdev->subsystem_device == 0x1107)) | 180 | (rdev->pdev->subsystem_device == 0x1107)) |
181 | use_bl = false; | 181 | use_bl = false; |
182 | /* disable native backlight control on older asics */ | ||
183 | else if (rdev->family < CHIP_R600) | ||
184 | use_bl = false; | ||
182 | else | 185 | else |
183 | use_bl = true; | 186 | use_bl = true; |
184 | } | 187 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 7784911d78ef..00fc59762e0d 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -185,6 +185,16 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
185 | if (rdev->flags & RADEON_IS_AGP) | 185 | if (rdev->flags & RADEON_IS_AGP) |
186 | return false; | 186 | return false; |
187 | 187 | ||
188 | /* | ||
189 | * Older chips have a HW limitation, they can only generate 40 bits | ||
190 | * of address for "64-bit" MSIs which breaks on some platforms, notably | ||
191 | * IBM POWER servers, so we limit them | ||
192 | */ | ||
193 | if (rdev->family < CHIP_BONAIRE) { | ||
194 | dev_info(rdev->dev, "radeon: MSI limited to 32-bit\n"); | ||
195 | rdev->pdev->no_64bit_msi = 1; | ||
196 | } | ||
197 | |||
188 | /* force MSI on */ | 198 | /* force MSI on */ |
189 | if (radeon_msi == 1) | 199 | if (radeon_msi == 1) |
190 | return true; | 200 | return true; |
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c index 6aac695b1688..9b55e673b67c 100644 --- a/drivers/hwmon/g762.c +++ b/drivers/hwmon/g762.c | |||
@@ -1084,10 +1084,8 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1084 | if (ret) | 1084 | if (ret) |
1085 | goto clock_dis; | 1085 | goto clock_dis; |
1086 | 1086 | ||
1087 | data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, | 1087 | data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, |
1088 | client->name, | 1088 | data, g762_groups); |
1089 | data, | ||
1090 | g762_groups); | ||
1091 | if (IS_ERR(data->hwmon_dev)) { | 1089 | if (IS_ERR(data->hwmon_dev)) { |
1092 | ret = PTR_ERR(data->hwmon_dev); | 1090 | ret = PTR_ERR(data->hwmon_dev); |
1093 | goto clock_dis; | 1091 | goto clock_dis; |
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 22c096ce39ad..513bd6d14293 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c | |||
@@ -44,6 +44,9 @@ | |||
44 | 44 | ||
45 | #define BMC150_ACCEL_REG_INT_STATUS_2 0x0B | 45 | #define BMC150_ACCEL_REG_INT_STATUS_2 0x0B |
46 | #define BMC150_ACCEL_ANY_MOTION_MASK 0x07 | 46 | #define BMC150_ACCEL_ANY_MOTION_MASK 0x07 |
47 | #define BMC150_ACCEL_ANY_MOTION_BIT_X BIT(0) | ||
48 | #define BMC150_ACCEL_ANY_MOTION_BIT_Y BIT(1) | ||
49 | #define BMC150_ACCEL_ANY_MOTION_BIT_Z BIT(2) | ||
47 | #define BMC150_ACCEL_ANY_MOTION_BIT_SIGN BIT(3) | 50 | #define BMC150_ACCEL_ANY_MOTION_BIT_SIGN BIT(3) |
48 | 51 | ||
49 | #define BMC150_ACCEL_REG_PMU_LPW 0x11 | 52 | #define BMC150_ACCEL_REG_PMU_LPW 0x11 |
@@ -92,9 +95,9 @@ | |||
92 | #define BMC150_ACCEL_SLOPE_THRES_MASK 0xFF | 95 | #define BMC150_ACCEL_SLOPE_THRES_MASK 0xFF |
93 | 96 | ||
94 | /* Slope duration in terms of number of samples */ | 97 | /* Slope duration in terms of number of samples */ |
95 | #define BMC150_ACCEL_DEF_SLOPE_DURATION 2 | 98 | #define BMC150_ACCEL_DEF_SLOPE_DURATION 1 |
96 | /* in terms of multiples of g's/LSB, based on range */ | 99 | /* in terms of multiples of g's/LSB, based on range */ |
97 | #define BMC150_ACCEL_DEF_SLOPE_THRESHOLD 5 | 100 | #define BMC150_ACCEL_DEF_SLOPE_THRESHOLD 1 |
98 | 101 | ||
99 | #define BMC150_ACCEL_REG_XOUT_L 0x02 | 102 | #define BMC150_ACCEL_REG_XOUT_L 0x02 |
100 | 103 | ||
@@ -536,6 +539,9 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) | |||
536 | if (ret < 0) { | 539 | if (ret < 0) { |
537 | dev_err(&data->client->dev, | 540 | dev_err(&data->client->dev, |
538 | "Failed: bmc150_accel_set_power_state for %d\n", on); | 541 | "Failed: bmc150_accel_set_power_state for %d\n", on); |
542 | if (on) | ||
543 | pm_runtime_put_noidle(&data->client->dev); | ||
544 | |||
539 | return ret; | 545 | return ret; |
540 | } | 546 | } |
541 | 547 | ||
@@ -811,6 +817,7 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, | |||
811 | 817 | ||
812 | ret = bmc150_accel_setup_any_motion_interrupt(data, state); | 818 | ret = bmc150_accel_setup_any_motion_interrupt(data, state); |
813 | if (ret < 0) { | 819 | if (ret < 0) { |
820 | bmc150_accel_set_power_state(data, false); | ||
814 | mutex_unlock(&data->mutex); | 821 | mutex_unlock(&data->mutex); |
815 | return ret; | 822 | return ret; |
816 | } | 823 | } |
@@ -846,7 +853,7 @@ static const struct attribute_group bmc150_accel_attrs_group = { | |||
846 | 853 | ||
847 | static const struct iio_event_spec bmc150_accel_event = { | 854 | static const struct iio_event_spec bmc150_accel_event = { |
848 | .type = IIO_EV_TYPE_ROC, | 855 | .type = IIO_EV_TYPE_ROC, |
849 | .dir = IIO_EV_DIR_RISING | IIO_EV_DIR_FALLING, | 856 | .dir = IIO_EV_DIR_EITHER, |
850 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | 857 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
851 | BIT(IIO_EV_INFO_ENABLE) | | 858 | BIT(IIO_EV_INFO_ENABLE) | |
852 | BIT(IIO_EV_INFO_PERIOD) | 859 | BIT(IIO_EV_INFO_PERIOD) |
@@ -1054,6 +1061,7 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, | |||
1054 | else | 1061 | else |
1055 | ret = bmc150_accel_setup_new_data_interrupt(data, state); | 1062 | ret = bmc150_accel_setup_new_data_interrupt(data, state); |
1056 | if (ret < 0) { | 1063 | if (ret < 0) { |
1064 | bmc150_accel_set_power_state(data, false); | ||
1057 | mutex_unlock(&data->mutex); | 1065 | mutex_unlock(&data->mutex); |
1058 | return ret; | 1066 | return ret; |
1059 | } | 1067 | } |
@@ -1092,12 +1100,26 @@ static irqreturn_t bmc150_accel_event_handler(int irq, void *private) | |||
1092 | else | 1100 | else |
1093 | dir = IIO_EV_DIR_RISING; | 1101 | dir = IIO_EV_DIR_RISING; |
1094 | 1102 | ||
1095 | if (ret & BMC150_ACCEL_ANY_MOTION_MASK) | 1103 | if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X) |
1104 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, | ||
1105 | 0, | ||
1106 | IIO_MOD_X, | ||
1107 | IIO_EV_TYPE_ROC, | ||
1108 | dir), | ||
1109 | data->timestamp); | ||
1110 | if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y) | ||
1096 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, | 1111 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, |
1097 | 0, | 1112 | 0, |
1098 | IIO_MOD_X_OR_Y_OR_Z, | 1113 | IIO_MOD_Y, |
1099 | IIO_EV_TYPE_ROC, | 1114 | IIO_EV_TYPE_ROC, |
1100 | IIO_EV_DIR_EITHER), | 1115 | dir), |
1116 | data->timestamp); | ||
1117 | if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z) | ||
1118 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, | ||
1119 | 0, | ||
1120 | IIO_MOD_Z, | ||
1121 | IIO_EV_TYPE_ROC, | ||
1122 | dir), | ||
1101 | data->timestamp); | 1123 | data->timestamp); |
1102 | ack_intr_status: | 1124 | ack_intr_status: |
1103 | if (!data->dready_trigger_on) | 1125 | if (!data->dready_trigger_on) |
@@ -1354,10 +1376,14 @@ static int bmc150_accel_runtime_suspend(struct device *dev) | |||
1354 | { | 1376 | { |
1355 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | 1377 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
1356 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1378 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
1379 | int ret; | ||
1357 | 1380 | ||
1358 | dev_dbg(&data->client->dev, __func__); | 1381 | dev_dbg(&data->client->dev, __func__); |
1382 | ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0); | ||
1383 | if (ret < 0) | ||
1384 | return -EAGAIN; | ||
1359 | 1385 | ||
1360 | return bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0); | 1386 | return 0; |
1361 | } | 1387 | } |
1362 | 1388 | ||
1363 | static int bmc150_accel_runtime_resume(struct device *dev) | 1389 | static int bmc150_accel_runtime_resume(struct device *dev) |
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index a23e58c4ed99..320aa72c0349 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c | |||
@@ -269,6 +269,8 @@ static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index) | |||
269 | return ret; | 269 | return ret; |
270 | } | 270 | } |
271 | 271 | ||
272 | ret &= ~(KXCJK1013_REG_CTRL1_BIT_GSEL0 | | ||
273 | KXCJK1013_REG_CTRL1_BIT_GSEL1); | ||
272 | ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3); | 274 | ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3); |
273 | ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4); | 275 | ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4); |
274 | 276 | ||
diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c index b58d6302521f..d095efe1ba14 100644 --- a/drivers/iio/adc/men_z188_adc.c +++ b/drivers/iio/adc/men_z188_adc.c | |||
@@ -152,6 +152,7 @@ static void men_z188_remove(struct mcb_device *dev) | |||
152 | 152 | ||
153 | static const struct mcb_device_id men_z188_ids[] = { | 153 | static const struct mcb_device_id men_z188_ids[] = { |
154 | { .device = 0xbc }, | 154 | { .device = 0xbc }, |
155 | { } | ||
155 | }; | 156 | }; |
156 | MODULE_DEVICE_TABLE(mcb, men_z188_ids); | 157 | MODULE_DEVICE_TABLE(mcb, men_z188_ids); |
157 | 158 | ||
diff --git a/drivers/iio/gyro/bmg160.c b/drivers/iio/gyro/bmg160.c index 1f967e0d688e..d2fa526740ca 100644 --- a/drivers/iio/gyro/bmg160.c +++ b/drivers/iio/gyro/bmg160.c | |||
@@ -67,6 +67,9 @@ | |||
67 | #define BMG160_REG_INT_EN_0 0x15 | 67 | #define BMG160_REG_INT_EN_0 0x15 |
68 | #define BMG160_DATA_ENABLE_INT BIT(7) | 68 | #define BMG160_DATA_ENABLE_INT BIT(7) |
69 | 69 | ||
70 | #define BMG160_REG_INT_EN_1 0x16 | ||
71 | #define BMG160_INT1_BIT_OD BIT(1) | ||
72 | |||
70 | #define BMG160_REG_XOUT_L 0x02 | 73 | #define BMG160_REG_XOUT_L 0x02 |
71 | #define BMG160_AXIS_TO_REG(axis) (BMG160_REG_XOUT_L + (axis * 2)) | 74 | #define BMG160_AXIS_TO_REG(axis) (BMG160_REG_XOUT_L + (axis * 2)) |
72 | 75 | ||
@@ -82,6 +85,9 @@ | |||
82 | 85 | ||
83 | #define BMG160_REG_INT_STATUS_2 0x0B | 86 | #define BMG160_REG_INT_STATUS_2 0x0B |
84 | #define BMG160_ANY_MOTION_MASK 0x07 | 87 | #define BMG160_ANY_MOTION_MASK 0x07 |
88 | #define BMG160_ANY_MOTION_BIT_X BIT(0) | ||
89 | #define BMG160_ANY_MOTION_BIT_Y BIT(1) | ||
90 | #define BMG160_ANY_MOTION_BIT_Z BIT(2) | ||
85 | 91 | ||
86 | #define BMG160_REG_TEMP 0x08 | 92 | #define BMG160_REG_TEMP 0x08 |
87 | #define BMG160_TEMP_CENTER_VAL 23 | 93 | #define BMG160_TEMP_CENTER_VAL 23 |
@@ -222,6 +228,19 @@ static int bmg160_chip_init(struct bmg160_data *data) | |||
222 | data->slope_thres = ret; | 228 | data->slope_thres = ret; |
223 | 229 | ||
224 | /* Set default interrupt mode */ | 230 | /* Set default interrupt mode */ |
231 | ret = i2c_smbus_read_byte_data(data->client, BMG160_REG_INT_EN_1); | ||
232 | if (ret < 0) { | ||
233 | dev_err(&data->client->dev, "Error reading reg_int_en_1\n"); | ||
234 | return ret; | ||
235 | } | ||
236 | ret &= ~BMG160_INT1_BIT_OD; | ||
237 | ret = i2c_smbus_write_byte_data(data->client, | ||
238 | BMG160_REG_INT_EN_1, ret); | ||
239 | if (ret < 0) { | ||
240 | dev_err(&data->client->dev, "Error writing reg_int_en_1\n"); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
225 | ret = i2c_smbus_write_byte_data(data->client, | 244 | ret = i2c_smbus_write_byte_data(data->client, |
226 | BMG160_REG_INT_RST_LATCH, | 245 | BMG160_REG_INT_RST_LATCH, |
227 | BMG160_INT_MODE_LATCH_INT | | 246 | BMG160_INT_MODE_LATCH_INT | |
@@ -250,6 +269,9 @@ static int bmg160_set_power_state(struct bmg160_data *data, bool on) | |||
250 | if (ret < 0) { | 269 | if (ret < 0) { |
251 | dev_err(&data->client->dev, | 270 | dev_err(&data->client->dev, |
252 | "Failed: bmg160_set_power_state for %d\n", on); | 271 | "Failed: bmg160_set_power_state for %d\n", on); |
272 | if (on) | ||
273 | pm_runtime_put_noidle(&data->client->dev); | ||
274 | |||
253 | return ret; | 275 | return ret; |
254 | } | 276 | } |
255 | #endif | 277 | #endif |
@@ -705,6 +727,7 @@ static int bmg160_write_event_config(struct iio_dev *indio_dev, | |||
705 | 727 | ||
706 | ret = bmg160_setup_any_motion_interrupt(data, state); | 728 | ret = bmg160_setup_any_motion_interrupt(data, state); |
707 | if (ret < 0) { | 729 | if (ret < 0) { |
730 | bmg160_set_power_state(data, false); | ||
708 | mutex_unlock(&data->mutex); | 731 | mutex_unlock(&data->mutex); |
709 | return ret; | 732 | return ret; |
710 | } | 733 | } |
@@ -743,7 +766,7 @@ static const struct attribute_group bmg160_attrs_group = { | |||
743 | 766 | ||
744 | static const struct iio_event_spec bmg160_event = { | 767 | static const struct iio_event_spec bmg160_event = { |
745 | .type = IIO_EV_TYPE_ROC, | 768 | .type = IIO_EV_TYPE_ROC, |
746 | .dir = IIO_EV_DIR_RISING | IIO_EV_DIR_FALLING, | 769 | .dir = IIO_EV_DIR_EITHER, |
747 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | | 770 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | |
748 | BIT(IIO_EV_INFO_ENABLE) | 771 | BIT(IIO_EV_INFO_ENABLE) |
749 | }; | 772 | }; |
@@ -871,6 +894,7 @@ static int bmg160_data_rdy_trigger_set_state(struct iio_trigger *trig, | |||
871 | else | 894 | else |
872 | ret = bmg160_setup_new_data_interrupt(data, state); | 895 | ret = bmg160_setup_new_data_interrupt(data, state); |
873 | if (ret < 0) { | 896 | if (ret < 0) { |
897 | bmg160_set_power_state(data, false); | ||
874 | mutex_unlock(&data->mutex); | 898 | mutex_unlock(&data->mutex); |
875 | return ret; | 899 | return ret; |
876 | } | 900 | } |
@@ -908,10 +932,24 @@ static irqreturn_t bmg160_event_handler(int irq, void *private) | |||
908 | else | 932 | else |
909 | dir = IIO_EV_DIR_FALLING; | 933 | dir = IIO_EV_DIR_FALLING; |
910 | 934 | ||
911 | if (ret & BMG160_ANY_MOTION_MASK) | 935 | if (ret & BMG160_ANY_MOTION_BIT_X) |
912 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, | 936 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, |
913 | 0, | 937 | 0, |
914 | IIO_MOD_X_OR_Y_OR_Z, | 938 | IIO_MOD_X, |
939 | IIO_EV_TYPE_ROC, | ||
940 | dir), | ||
941 | data->timestamp); | ||
942 | if (ret & BMG160_ANY_MOTION_BIT_Y) | ||
943 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, | ||
944 | 0, | ||
945 | IIO_MOD_Y, | ||
946 | IIO_EV_TYPE_ROC, | ||
947 | dir), | ||
948 | data->timestamp); | ||
949 | if (ret & BMG160_ANY_MOTION_BIT_Z) | ||
950 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, | ||
951 | 0, | ||
952 | IIO_MOD_Z, | ||
915 | IIO_EV_TYPE_ROC, | 953 | IIO_EV_TYPE_ROC, |
916 | dir), | 954 | dir), |
917 | data->timestamp); | 955 | data->timestamp); |
@@ -1169,8 +1207,15 @@ static int bmg160_runtime_suspend(struct device *dev) | |||
1169 | { | 1207 | { |
1170 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | 1208 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
1171 | struct bmg160_data *data = iio_priv(indio_dev); | 1209 | struct bmg160_data *data = iio_priv(indio_dev); |
1210 | int ret; | ||
1211 | |||
1212 | ret = bmg160_set_mode(data, BMG160_MODE_SUSPEND); | ||
1213 | if (ret < 0) { | ||
1214 | dev_err(&data->client->dev, "set mode failed\n"); | ||
1215 | return -EAGAIN; | ||
1216 | } | ||
1172 | 1217 | ||
1173 | return bmg160_set_mode(data, BMG160_MODE_SUSPEND); | 1218 | return 0; |
1174 | } | 1219 | } |
1175 | 1220 | ||
1176 | static int bmg160_runtime_resume(struct device *dev) | 1221 | static int bmg160_runtime_resume(struct device *dev) |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 3effa931fce2..10641b7816f4 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -115,9 +115,12 @@ isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id, | |||
115 | attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS; | 115 | attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS; |
116 | /* | 116 | /* |
117 | * FIXME: Use devattr.max_sge - 2 for max_send_sge as | 117 | * FIXME: Use devattr.max_sge - 2 for max_send_sge as |
118 | * work-around for RDMA_READ.. | 118 | * work-around for RDMA_READs with ConnectX-2. |
119 | * | ||
120 | * Also, still make sure to have at least two SGEs for | ||
121 | * outgoing control PDU responses. | ||
119 | */ | 122 | */ |
120 | attr.cap.max_send_sge = device->dev_attr.max_sge - 2; | 123 | attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2); |
121 | isert_conn->max_sge = attr.cap.max_send_sge; | 124 | isert_conn->max_sge = attr.cap.max_send_sge; |
122 | 125 | ||
123 | attr.cap.max_recv_sge = 1; | 126 | attr.cap.max_recv_sge = 1; |
@@ -225,12 +228,16 @@ isert_create_device_ib_res(struct isert_device *device) | |||
225 | struct isert_cq_desc *cq_desc; | 228 | struct isert_cq_desc *cq_desc; |
226 | struct ib_device_attr *dev_attr; | 229 | struct ib_device_attr *dev_attr; |
227 | int ret = 0, i, j; | 230 | int ret = 0, i, j; |
231 | int max_rx_cqe, max_tx_cqe; | ||
228 | 232 | ||
229 | dev_attr = &device->dev_attr; | 233 | dev_attr = &device->dev_attr; |
230 | ret = isert_query_device(ib_dev, dev_attr); | 234 | ret = isert_query_device(ib_dev, dev_attr); |
231 | if (ret) | 235 | if (ret) |
232 | return ret; | 236 | return ret; |
233 | 237 | ||
238 | max_rx_cqe = min(ISER_MAX_RX_CQ_LEN, dev_attr->max_cqe); | ||
239 | max_tx_cqe = min(ISER_MAX_TX_CQ_LEN, dev_attr->max_cqe); | ||
240 | |||
234 | /* asign function handlers */ | 241 | /* asign function handlers */ |
235 | if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS && | 242 | if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS && |
236 | dev_attr->device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER) { | 243 | dev_attr->device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER) { |
@@ -272,7 +279,7 @@ isert_create_device_ib_res(struct isert_device *device) | |||
272 | isert_cq_rx_callback, | 279 | isert_cq_rx_callback, |
273 | isert_cq_event_callback, | 280 | isert_cq_event_callback, |
274 | (void *)&cq_desc[i], | 281 | (void *)&cq_desc[i], |
275 | ISER_MAX_RX_CQ_LEN, i); | 282 | max_rx_cqe, i); |
276 | if (IS_ERR(device->dev_rx_cq[i])) { | 283 | if (IS_ERR(device->dev_rx_cq[i])) { |
277 | ret = PTR_ERR(device->dev_rx_cq[i]); | 284 | ret = PTR_ERR(device->dev_rx_cq[i]); |
278 | device->dev_rx_cq[i] = NULL; | 285 | device->dev_rx_cq[i] = NULL; |
@@ -284,7 +291,7 @@ isert_create_device_ib_res(struct isert_device *device) | |||
284 | isert_cq_tx_callback, | 291 | isert_cq_tx_callback, |
285 | isert_cq_event_callback, | 292 | isert_cq_event_callback, |
286 | (void *)&cq_desc[i], | 293 | (void *)&cq_desc[i], |
287 | ISER_MAX_TX_CQ_LEN, i); | 294 | max_tx_cqe, i); |
288 | if (IS_ERR(device->dev_tx_cq[i])) { | 295 | if (IS_ERR(device->dev_tx_cq[i])) { |
289 | ret = PTR_ERR(device->dev_tx_cq[i]); | 296 | ret = PTR_ERR(device->dev_tx_cq[i]); |
290 | device->dev_tx_cq[i] = NULL; | 297 | device->dev_tx_cq[i] = NULL; |
@@ -803,14 +810,25 @@ wake_up: | |||
803 | complete(&isert_conn->conn_wait); | 810 | complete(&isert_conn->conn_wait); |
804 | } | 811 | } |
805 | 812 | ||
806 | static void | 813 | static int |
807 | isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect) | 814 | isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect) |
808 | { | 815 | { |
809 | struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context; | 816 | struct isert_conn *isert_conn; |
817 | |||
818 | if (!cma_id->qp) { | ||
819 | struct isert_np *isert_np = cma_id->context; | ||
820 | |||
821 | isert_np->np_cm_id = NULL; | ||
822 | return -1; | ||
823 | } | ||
824 | |||
825 | isert_conn = (struct isert_conn *)cma_id->context; | ||
810 | 826 | ||
811 | isert_conn->disconnect = disconnect; | 827 | isert_conn->disconnect = disconnect; |
812 | INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work); | 828 | INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work); |
813 | schedule_work(&isert_conn->conn_logout_work); | 829 | schedule_work(&isert_conn->conn_logout_work); |
830 | |||
831 | return 0; | ||
814 | } | 832 | } |
815 | 833 | ||
816 | static int | 834 | static int |
@@ -825,6 +843,9 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
825 | switch (event->event) { | 843 | switch (event->event) { |
826 | case RDMA_CM_EVENT_CONNECT_REQUEST: | 844 | case RDMA_CM_EVENT_CONNECT_REQUEST: |
827 | ret = isert_connect_request(cma_id, event); | 845 | ret = isert_connect_request(cma_id, event); |
846 | if (ret) | ||
847 | pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n", | ||
848 | event->event, ret); | ||
828 | break; | 849 | break; |
829 | case RDMA_CM_EVENT_ESTABLISHED: | 850 | case RDMA_CM_EVENT_ESTABLISHED: |
830 | isert_connected_handler(cma_id); | 851 | isert_connected_handler(cma_id); |
@@ -834,7 +855,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
834 | case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */ | 855 | case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */ |
835 | disconnect = true; | 856 | disconnect = true; |
836 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ | 857 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ |
837 | isert_disconnected_handler(cma_id, disconnect); | 858 | ret = isert_disconnected_handler(cma_id, disconnect); |
838 | break; | 859 | break; |
839 | case RDMA_CM_EVENT_CONNECT_ERROR: | 860 | case RDMA_CM_EVENT_CONNECT_ERROR: |
840 | default: | 861 | default: |
@@ -842,12 +863,6 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
842 | break; | 863 | break; |
843 | } | 864 | } |
844 | 865 | ||
845 | if (ret != 0) { | ||
846 | pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n", | ||
847 | event->event, ret); | ||
848 | dump_stack(); | ||
849 | } | ||
850 | |||
851 | return ret; | 866 | return ret; |
852 | } | 867 | } |
853 | 868 | ||
@@ -3190,7 +3205,8 @@ isert_free_np(struct iscsi_np *np) | |||
3190 | { | 3205 | { |
3191 | struct isert_np *isert_np = (struct isert_np *)np->np_context; | 3206 | struct isert_np *isert_np = (struct isert_np *)np->np_context; |
3192 | 3207 | ||
3193 | rdma_destroy_id(isert_np->np_cm_id); | 3208 | if (isert_np->np_cm_id) |
3209 | rdma_destroy_id(isert_np->np_cm_id); | ||
3194 | 3210 | ||
3195 | np->np_context = NULL; | 3211 | np->np_context = NULL; |
3196 | kfree(isert_np); | 3212 | kfree(isert_np); |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 7206547c13ce..dc829682701a 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -2092,6 +2092,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) | |||
2092 | if (!qp_init) | 2092 | if (!qp_init) |
2093 | goto out; | 2093 | goto out; |
2094 | 2094 | ||
2095 | retry: | ||
2095 | ch->cq = ib_create_cq(sdev->device, srpt_completion, NULL, ch, | 2096 | ch->cq = ib_create_cq(sdev->device, srpt_completion, NULL, ch, |
2096 | ch->rq_size + srp_sq_size, 0); | 2097 | ch->rq_size + srp_sq_size, 0); |
2097 | if (IS_ERR(ch->cq)) { | 2098 | if (IS_ERR(ch->cq)) { |
@@ -2115,6 +2116,13 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) | |||
2115 | ch->qp = ib_create_qp(sdev->pd, qp_init); | 2116 | ch->qp = ib_create_qp(sdev->pd, qp_init); |
2116 | if (IS_ERR(ch->qp)) { | 2117 | if (IS_ERR(ch->qp)) { |
2117 | ret = PTR_ERR(ch->qp); | 2118 | ret = PTR_ERR(ch->qp); |
2119 | if (ret == -ENOMEM) { | ||
2120 | srp_sq_size /= 2; | ||
2121 | if (srp_sq_size >= MIN_SRPT_SQ_SIZE) { | ||
2122 | ib_destroy_cq(ch->cq); | ||
2123 | goto retry; | ||
2124 | } | ||
2125 | } | ||
2118 | printk(KERN_ERR "failed to create_qp ret= %d\n", ret); | 2126 | printk(KERN_ERR "failed to create_qp ret= %d\n", ret); |
2119 | goto err_destroy_cq; | 2127 | goto err_destroy_cq; |
2120 | } | 2128 | } |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 2ed7905a068f..fc55f0d15b70 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -1179,9 +1179,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
1179 | } | 1179 | } |
1180 | 1180 | ||
1181 | ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; | 1181 | ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; |
1182 | usb_fill_bulk_urb(xpad->bulk_out, udev, | 1182 | if (usb_endpoint_is_bulk_out(ep_irq_in)) { |
1183 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), | 1183 | usb_fill_bulk_urb(xpad->bulk_out, udev, |
1184 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); | 1184 | usb_sndbulkpipe(udev, |
1185 | ep_irq_in->bEndpointAddress), | ||
1186 | xpad->bdata, XPAD_PKT_LEN, | ||
1187 | xpad_bulk_out, xpad); | ||
1188 | } else { | ||
1189 | usb_fill_int_urb(xpad->bulk_out, udev, | ||
1190 | usb_sndintpipe(udev, | ||
1191 | ep_irq_in->bEndpointAddress), | ||
1192 | xpad->bdata, XPAD_PKT_LEN, | ||
1193 | xpad_bulk_out, xpad, 0); | ||
1194 | } | ||
1185 | 1195 | ||
1186 | /* | 1196 | /* |
1187 | * Submit the int URB immediately rather than waiting for open | 1197 | * Submit the int URB immediately rather than waiting for open |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 3fcb6b3cb0bd..f2b978026407 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -428,14 +428,6 @@ static void elantech_report_trackpoint(struct psmouse *psmouse, | |||
428 | int x, y; | 428 | int x, y; |
429 | u32 t; | 429 | u32 t; |
430 | 430 | ||
431 | if (dev_WARN_ONCE(&psmouse->ps2dev.serio->dev, | ||
432 | !tp_dev, | ||
433 | psmouse_fmt("Unexpected trackpoint message\n"))) { | ||
434 | if (etd->debug == 1) | ||
435 | elantech_packet_dump(psmouse); | ||
436 | return; | ||
437 | } | ||
438 | |||
439 | t = get_unaligned_le32(&packet[0]); | 431 | t = get_unaligned_le32(&packet[0]); |
440 | 432 | ||
441 | switch (t & ~7U) { | 433 | switch (t & ~7U) { |
@@ -793,7 +785,7 @@ static int elantech_packet_check_v4(struct psmouse *psmouse) | |||
793 | unsigned char packet_type = packet[3] & 0x03; | 785 | unsigned char packet_type = packet[3] & 0x03; |
794 | bool sanity_check; | 786 | bool sanity_check; |
795 | 787 | ||
796 | if ((packet[3] & 0x0f) == 0x06) | 788 | if (etd->tp_dev && (packet[3] & 0x0f) == 0x06) |
797 | return PACKET_TRACKPOINT; | 789 | return PACKET_TRACKPOINT; |
798 | 790 | ||
799 | /* | 791 | /* |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2a7a9174c702..f9472920d986 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -143,6 +143,10 @@ static const struct min_max_quirk min_max_pnpid_table[] = { | |||
143 | (const char * const []){"LEN2001", NULL}, | 143 | (const char * const []){"LEN2001", NULL}, |
144 | 1024, 5022, 2508, 4832 | 144 | 1024, 5022, 2508, 4832 |
145 | }, | 145 | }, |
146 | { | ||
147 | (const char * const []){"LEN2006", NULL}, | ||
148 | 1264, 5675, 1171, 4688 | ||
149 | }, | ||
146 | { } | 150 | { } |
147 | }; | 151 | }; |
148 | 152 | ||
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index 6ae3cdee0681..cc4f9d80122e 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c | |||
@@ -217,8 +217,9 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node, | |||
217 | } | 217 | } |
218 | 218 | ||
219 | ret = irq_alloc_domain_generic_chips(domain, 32, 1, name, | 219 | ret = irq_alloc_domain_generic_chips(domain, 32, 1, name, |
220 | handle_level_irq, 0, 0, | 220 | handle_fasteoi_irq, |
221 | IRQCHIP_SKIP_SET_WAKE); | 221 | IRQ_NOREQUEST | IRQ_NOPROBE | |
222 | IRQ_NOAUTOEN, 0, 0); | ||
222 | if (ret) | 223 | if (ret) |
223 | goto err_domain_remove; | 224 | goto err_domain_remove; |
224 | 225 | ||
@@ -230,7 +231,6 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node, | |||
230 | gc->unused = 0; | 231 | gc->unused = 0; |
231 | gc->wake_enabled = ~0; | 232 | gc->wake_enabled = ~0; |
232 | gc->chip_types[0].type = IRQ_TYPE_SENSE_MASK; | 233 | gc->chip_types[0].type = IRQ_TYPE_SENSE_MASK; |
233 | gc->chip_types[0].handler = handle_fasteoi_irq; | ||
234 | gc->chip_types[0].chip.irq_eoi = irq_gc_eoi; | 234 | gc->chip_types[0].chip.irq_eoi = irq_gc_eoi; |
235 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; | 235 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; |
236 | gc->chip_types[0].chip.irq_shutdown = aic_common_shutdown; | 236 | gc->chip_types[0].chip.irq_shutdown = aic_common_shutdown; |
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index b9f4fb808e49..5fb38a2ac226 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c | |||
@@ -101,9 +101,9 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, | |||
101 | int parent_irq; | 101 | int parent_irq; |
102 | 102 | ||
103 | parent_irq = irq_of_parse_and_map(dn, irq); | 103 | parent_irq = irq_of_parse_and_map(dn, irq); |
104 | if (parent_irq < 0) { | 104 | if (!parent_irq) { |
105 | pr_err("failed to map interrupt %d\n", irq); | 105 | pr_err("failed to map interrupt %d\n", irq); |
106 | return parent_irq; | 106 | return -EINVAL; |
107 | } | 107 | } |
108 | 108 | ||
109 | data->irq_map_mask |= be32_to_cpup(map_mask + irq); | 109 | data->irq_map_mask |= be32_to_cpup(map_mask + irq); |
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index c15c840987d2..14691a4cb84c 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c | |||
@@ -135,9 +135,9 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
135 | __raw_writel(0xffffffff, data->base + CPU_CLEAR); | 135 | __raw_writel(0xffffffff, data->base + CPU_CLEAR); |
136 | 136 | ||
137 | data->parent_irq = irq_of_parse_and_map(np, 0); | 137 | data->parent_irq = irq_of_parse_and_map(np, 0); |
138 | if (data->parent_irq < 0) { | 138 | if (!data->parent_irq) { |
139 | pr_err("failed to find parent interrupt\n"); | 139 | pr_err("failed to find parent interrupt\n"); |
140 | ret = data->parent_irq; | 140 | ret = -EINVAL; |
141 | goto out_unmap; | 141 | goto out_unmap; |
142 | } | 142 | } |
143 | 143 | ||
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index 40569894c1c9..ac3cd74e824e 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c | |||
@@ -173,9 +173,7 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, | |||
173 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, | 173 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, |
174 | dev->dmasound.bufsize, dev->dmasound.blocks); | 174 | dev->dmasound.bufsize, dev->dmasound.blocks); |
175 | spin_unlock(&dev->slock); | 175 | spin_unlock(&dev->slock); |
176 | snd_pcm_stream_lock(dev->dmasound.substream); | 176 | snd_pcm_stop_xrun(dev->dmasound.substream); |
177 | snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); | ||
178 | snd_pcm_stream_unlock(dev->dmasound.substream); | ||
179 | return; | 177 | return; |
180 | } | 178 | } |
181 | 179 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c9ac06cfe6b7..a5115fb7cf33 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2471,7 +2471,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2471 | bond_slave_state_change(bond); | 2471 | bond_slave_state_change(bond); |
2472 | if (BOND_MODE(bond) == BOND_MODE_XOR) | 2472 | if (BOND_MODE(bond) == BOND_MODE_XOR) |
2473 | bond_update_slave_arr(bond, NULL); | 2473 | bond_update_slave_arr(bond, NULL); |
2474 | } else if (do_failover) { | 2474 | } |
2475 | if (do_failover) { | ||
2475 | block_netpoll_tx(); | 2476 | block_netpoll_tx(); |
2476 | bond_select_active_slave(bond); | 2477 | bond_select_active_slave(bond); |
2477 | unblock_netpoll_tx(); | 2478 | unblock_netpoll_tx(); |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 02492d241e4c..2cfe5012e4e5 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -110,7 +110,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, | |||
110 | long rate; | 110 | long rate; |
111 | u64 v64; | 111 | u64 v64; |
112 | 112 | ||
113 | /* Use CIA recommended sample points */ | 113 | /* Use CiA recommended sample points */ |
114 | if (bt->sample_point) { | 114 | if (bt->sample_point) { |
115 | sampl_pt = bt->sample_point; | 115 | sampl_pt = bt->sample_point; |
116 | } else { | 116 | } else { |
@@ -382,7 +382,7 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx) | |||
382 | BUG_ON(idx >= priv->echo_skb_max); | 382 | BUG_ON(idx >= priv->echo_skb_max); |
383 | 383 | ||
384 | if (priv->echo_skb[idx]) { | 384 | if (priv->echo_skb[idx]) { |
385 | kfree_skb(priv->echo_skb[idx]); | 385 | dev_kfree_skb_any(priv->echo_skb[idx]); |
386 | priv->echo_skb[idx] = NULL; | 386 | priv->echo_skb[idx] = NULL; |
387 | } | 387 | } |
388 | } | 388 | } |
diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig index fca5482c09ac..04f20dd39007 100644 --- a/drivers/net/can/m_can/Kconfig +++ b/drivers/net/can/m_can/Kconfig | |||
@@ -1,4 +1,5 @@ | |||
1 | config CAN_M_CAN | 1 | config CAN_M_CAN |
2 | depends on HAS_IOMEM | ||
2 | tristate "Bosch M_CAN devices" | 3 | tristate "Bosch M_CAN devices" |
3 | ---help--- | 4 | ---help--- |
4 | Say Y here if you want to support for Bosch M_CAN controller. | 5 | Say Y here if you want to support for Bosch M_CAN controller. |
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 10d571eaed85..d7bc462aafdc 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c | |||
@@ -105,14 +105,36 @@ enum m_can_mram_cfg { | |||
105 | MRAM_CFG_NUM, | 105 | MRAM_CFG_NUM, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* Fast Bit Timing & Prescaler Register (FBTP) */ | ||
109 | #define FBTR_FBRP_MASK 0x1f | ||
110 | #define FBTR_FBRP_SHIFT 16 | ||
111 | #define FBTR_FTSEG1_SHIFT 8 | ||
112 | #define FBTR_FTSEG1_MASK (0xf << FBTR_FTSEG1_SHIFT) | ||
113 | #define FBTR_FTSEG2_SHIFT 4 | ||
114 | #define FBTR_FTSEG2_MASK (0x7 << FBTR_FTSEG2_SHIFT) | ||
115 | #define FBTR_FSJW_SHIFT 0 | ||
116 | #define FBTR_FSJW_MASK 0x3 | ||
117 | |||
108 | /* Test Register (TEST) */ | 118 | /* Test Register (TEST) */ |
109 | #define TEST_LBCK BIT(4) | 119 | #define TEST_LBCK BIT(4) |
110 | 120 | ||
111 | /* CC Control Register(CCCR) */ | 121 | /* CC Control Register(CCCR) */ |
112 | #define CCCR_TEST BIT(7) | 122 | #define CCCR_TEST BIT(7) |
113 | #define CCCR_MON BIT(5) | 123 | #define CCCR_CMR_MASK 0x3 |
114 | #define CCCR_CCE BIT(1) | 124 | #define CCCR_CMR_SHIFT 10 |
115 | #define CCCR_INIT BIT(0) | 125 | #define CCCR_CMR_CANFD 0x1 |
126 | #define CCCR_CMR_CANFD_BRS 0x2 | ||
127 | #define CCCR_CMR_CAN 0x3 | ||
128 | #define CCCR_CME_MASK 0x3 | ||
129 | #define CCCR_CME_SHIFT 8 | ||
130 | #define CCCR_CME_CAN 0 | ||
131 | #define CCCR_CME_CANFD 0x1 | ||
132 | #define CCCR_CME_CANFD_BRS 0x2 | ||
133 | #define CCCR_TEST BIT(7) | ||
134 | #define CCCR_MON BIT(5) | ||
135 | #define CCCR_CCE BIT(1) | ||
136 | #define CCCR_INIT BIT(0) | ||
137 | #define CCCR_CANFD 0x10 | ||
116 | 138 | ||
117 | /* Bit Timing & Prescaler Register (BTP) */ | 139 | /* Bit Timing & Prescaler Register (BTP) */ |
118 | #define BTR_BRP_MASK 0x3ff | 140 | #define BTR_BRP_MASK 0x3ff |
@@ -204,6 +226,7 @@ enum m_can_mram_cfg { | |||
204 | 226 | ||
205 | /* Rx Buffer / FIFO Element Size Configuration (RXESC) */ | 227 | /* Rx Buffer / FIFO Element Size Configuration (RXESC) */ |
206 | #define M_CAN_RXESC_8BYTES 0x0 | 228 | #define M_CAN_RXESC_8BYTES 0x0 |
229 | #define M_CAN_RXESC_64BYTES 0x777 | ||
207 | 230 | ||
208 | /* Tx Buffer Configuration(TXBC) */ | 231 | /* Tx Buffer Configuration(TXBC) */ |
209 | #define TXBC_NDTB_OFF 16 | 232 | #define TXBC_NDTB_OFF 16 |
@@ -211,6 +234,7 @@ enum m_can_mram_cfg { | |||
211 | 234 | ||
212 | /* Tx Buffer Element Size Configuration(TXESC) */ | 235 | /* Tx Buffer Element Size Configuration(TXESC) */ |
213 | #define TXESC_TBDS_8BYTES 0x0 | 236 | #define TXESC_TBDS_8BYTES 0x0 |
237 | #define TXESC_TBDS_64BYTES 0x7 | ||
214 | 238 | ||
215 | /* Tx Event FIFO Con.guration (TXEFC) */ | 239 | /* Tx Event FIFO Con.guration (TXEFC) */ |
216 | #define TXEFC_EFS_OFF 16 | 240 | #define TXEFC_EFS_OFF 16 |
@@ -219,11 +243,11 @@ enum m_can_mram_cfg { | |||
219 | /* Message RAM Configuration (in bytes) */ | 243 | /* Message RAM Configuration (in bytes) */ |
220 | #define SIDF_ELEMENT_SIZE 4 | 244 | #define SIDF_ELEMENT_SIZE 4 |
221 | #define XIDF_ELEMENT_SIZE 8 | 245 | #define XIDF_ELEMENT_SIZE 8 |
222 | #define RXF0_ELEMENT_SIZE 16 | 246 | #define RXF0_ELEMENT_SIZE 72 |
223 | #define RXF1_ELEMENT_SIZE 16 | 247 | #define RXF1_ELEMENT_SIZE 72 |
224 | #define RXB_ELEMENT_SIZE 16 | 248 | #define RXB_ELEMENT_SIZE 16 |
225 | #define TXE_ELEMENT_SIZE 8 | 249 | #define TXE_ELEMENT_SIZE 8 |
226 | #define TXB_ELEMENT_SIZE 16 | 250 | #define TXB_ELEMENT_SIZE 72 |
227 | 251 | ||
228 | /* Message RAM Elements */ | 252 | /* Message RAM Elements */ |
229 | #define M_CAN_FIFO_ID 0x0 | 253 | #define M_CAN_FIFO_ID 0x0 |
@@ -231,11 +255,17 @@ enum m_can_mram_cfg { | |||
231 | #define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2)) | 255 | #define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2)) |
232 | 256 | ||
233 | /* Rx Buffer Element */ | 257 | /* Rx Buffer Element */ |
258 | /* R0 */ | ||
234 | #define RX_BUF_ESI BIT(31) | 259 | #define RX_BUF_ESI BIT(31) |
235 | #define RX_BUF_XTD BIT(30) | 260 | #define RX_BUF_XTD BIT(30) |
236 | #define RX_BUF_RTR BIT(29) | 261 | #define RX_BUF_RTR BIT(29) |
262 | /* R1 */ | ||
263 | #define RX_BUF_ANMF BIT(31) | ||
264 | #define RX_BUF_EDL BIT(21) | ||
265 | #define RX_BUF_BRS BIT(20) | ||
237 | 266 | ||
238 | /* Tx Buffer Element */ | 267 | /* Tx Buffer Element */ |
268 | /* R0 */ | ||
239 | #define TX_BUF_XTD BIT(30) | 269 | #define TX_BUF_XTD BIT(30) |
240 | #define TX_BUF_RTR BIT(29) | 270 | #define TX_BUF_RTR BIT(29) |
241 | 271 | ||
@@ -296,6 +326,7 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv, | |||
296 | if (enable) { | 326 | if (enable) { |
297 | /* enable m_can configuration */ | 327 | /* enable m_can configuration */ |
298 | m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT); | 328 | m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT); |
329 | udelay(5); | ||
299 | /* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */ | 330 | /* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */ |
300 | m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE); | 331 | m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE); |
301 | } else { | 332 | } else { |
@@ -326,41 +357,67 @@ static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv) | |||
326 | m_can_write(priv, M_CAN_ILE, 0x0); | 357 | m_can_write(priv, M_CAN_ILE, 0x0); |
327 | } | 358 | } |
328 | 359 | ||
329 | static void m_can_read_fifo(const struct net_device *dev, struct can_frame *cf, | 360 | static void m_can_read_fifo(struct net_device *dev, u32 rxfs) |
330 | u32 rxfs) | ||
331 | { | 361 | { |
362 | struct net_device_stats *stats = &dev->stats; | ||
332 | struct m_can_priv *priv = netdev_priv(dev); | 363 | struct m_can_priv *priv = netdev_priv(dev); |
333 | u32 id, fgi; | 364 | struct canfd_frame *cf; |
365 | struct sk_buff *skb; | ||
366 | u32 id, fgi, dlc; | ||
367 | int i; | ||
334 | 368 | ||
335 | /* calculate the fifo get index for where to read data */ | 369 | /* calculate the fifo get index for where to read data */ |
336 | fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_OFF; | 370 | fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_OFF; |
371 | dlc = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC); | ||
372 | if (dlc & RX_BUF_EDL) | ||
373 | skb = alloc_canfd_skb(dev, &cf); | ||
374 | else | ||
375 | skb = alloc_can_skb(dev, (struct can_frame **)&cf); | ||
376 | if (!skb) { | ||
377 | stats->rx_dropped++; | ||
378 | return; | ||
379 | } | ||
380 | |||
381 | if (dlc & RX_BUF_EDL) | ||
382 | cf->len = can_dlc2len((dlc >> 16) & 0x0F); | ||
383 | else | ||
384 | cf->len = get_can_dlc((dlc >> 16) & 0x0F); | ||
385 | |||
337 | id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID); | 386 | id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID); |
338 | if (id & RX_BUF_XTD) | 387 | if (id & RX_BUF_XTD) |
339 | cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; | 388 | cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; |
340 | else | 389 | else |
341 | cf->can_id = (id >> 18) & CAN_SFF_MASK; | 390 | cf->can_id = (id >> 18) & CAN_SFF_MASK; |
342 | 391 | ||
343 | if (id & RX_BUF_RTR) { | 392 | if (id & RX_BUF_ESI) { |
393 | cf->flags |= CANFD_ESI; | ||
394 | netdev_dbg(dev, "ESI Error\n"); | ||
395 | } | ||
396 | |||
397 | if (!(dlc & RX_BUF_EDL) && (id & RX_BUF_RTR)) { | ||
344 | cf->can_id |= CAN_RTR_FLAG; | 398 | cf->can_id |= CAN_RTR_FLAG; |
345 | } else { | 399 | } else { |
346 | id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC); | 400 | if (dlc & RX_BUF_BRS) |
347 | cf->can_dlc = get_can_dlc((id >> 16) & 0x0F); | 401 | cf->flags |= CANFD_BRS; |
348 | *(u32 *)(cf->data + 0) = m_can_fifo_read(priv, fgi, | 402 | |
349 | M_CAN_FIFO_DATA(0)); | 403 | for (i = 0; i < cf->len; i += 4) |
350 | *(u32 *)(cf->data + 4) = m_can_fifo_read(priv, fgi, | 404 | *(u32 *)(cf->data + i) = |
351 | M_CAN_FIFO_DATA(1)); | 405 | m_can_fifo_read(priv, fgi, |
406 | M_CAN_FIFO_DATA(i / 4)); | ||
352 | } | 407 | } |
353 | 408 | ||
354 | /* acknowledge rx fifo 0 */ | 409 | /* acknowledge rx fifo 0 */ |
355 | m_can_write(priv, M_CAN_RXF0A, fgi); | 410 | m_can_write(priv, M_CAN_RXF0A, fgi); |
411 | |||
412 | stats->rx_packets++; | ||
413 | stats->rx_bytes += cf->len; | ||
414 | |||
415 | netif_receive_skb(skb); | ||
356 | } | 416 | } |
357 | 417 | ||
358 | static int m_can_do_rx_poll(struct net_device *dev, int quota) | 418 | static int m_can_do_rx_poll(struct net_device *dev, int quota) |
359 | { | 419 | { |
360 | struct m_can_priv *priv = netdev_priv(dev); | 420 | struct m_can_priv *priv = netdev_priv(dev); |
361 | struct net_device_stats *stats = &dev->stats; | ||
362 | struct sk_buff *skb; | ||
363 | struct can_frame *frame; | ||
364 | u32 pkts = 0; | 421 | u32 pkts = 0; |
365 | u32 rxfs; | 422 | u32 rxfs; |
366 | 423 | ||
@@ -374,18 +431,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota) | |||
374 | if (rxfs & RXFS_RFL) | 431 | if (rxfs & RXFS_RFL) |
375 | netdev_warn(dev, "Rx FIFO 0 Message Lost\n"); | 432 | netdev_warn(dev, "Rx FIFO 0 Message Lost\n"); |
376 | 433 | ||
377 | skb = alloc_can_skb(dev, &frame); | 434 | m_can_read_fifo(dev, rxfs); |
378 | if (!skb) { | ||
379 | stats->rx_dropped++; | ||
380 | return pkts; | ||
381 | } | ||
382 | |||
383 | m_can_read_fifo(dev, frame, rxfs); | ||
384 | |||
385 | stats->rx_packets++; | ||
386 | stats->rx_bytes += frame->can_dlc; | ||
387 | |||
388 | netif_receive_skb(skb); | ||
389 | 435 | ||
390 | quota--; | 436 | quota--; |
391 | pkts++; | 437 | pkts++; |
@@ -481,11 +527,23 @@ static int m_can_handle_lec_err(struct net_device *dev, | |||
481 | return 1; | 527 | return 1; |
482 | } | 528 | } |
483 | 529 | ||
530 | static int __m_can_get_berr_counter(const struct net_device *dev, | ||
531 | struct can_berr_counter *bec) | ||
532 | { | ||
533 | struct m_can_priv *priv = netdev_priv(dev); | ||
534 | unsigned int ecr; | ||
535 | |||
536 | ecr = m_can_read(priv, M_CAN_ECR); | ||
537 | bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT; | ||
538 | bec->txerr = ecr & ECR_TEC_MASK; | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
484 | static int m_can_get_berr_counter(const struct net_device *dev, | 543 | static int m_can_get_berr_counter(const struct net_device *dev, |
485 | struct can_berr_counter *bec) | 544 | struct can_berr_counter *bec) |
486 | { | 545 | { |
487 | struct m_can_priv *priv = netdev_priv(dev); | 546 | struct m_can_priv *priv = netdev_priv(dev); |
488 | unsigned int ecr; | ||
489 | int err; | 547 | int err; |
490 | 548 | ||
491 | err = clk_prepare_enable(priv->hclk); | 549 | err = clk_prepare_enable(priv->hclk); |
@@ -498,9 +556,7 @@ static int m_can_get_berr_counter(const struct net_device *dev, | |||
498 | return err; | 556 | return err; |
499 | } | 557 | } |
500 | 558 | ||
501 | ecr = m_can_read(priv, M_CAN_ECR); | 559 | __m_can_get_berr_counter(dev, bec); |
502 | bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT; | ||
503 | bec->txerr = ecr & ECR_TEC_MASK; | ||
504 | 560 | ||
505 | clk_disable_unprepare(priv->cclk); | 561 | clk_disable_unprepare(priv->cclk); |
506 | clk_disable_unprepare(priv->hclk); | 562 | clk_disable_unprepare(priv->hclk); |
@@ -544,7 +600,7 @@ static int m_can_handle_state_change(struct net_device *dev, | |||
544 | if (unlikely(!skb)) | 600 | if (unlikely(!skb)) |
545 | return 0; | 601 | return 0; |
546 | 602 | ||
547 | m_can_get_berr_counter(dev, &bec); | 603 | __m_can_get_berr_counter(dev, &bec); |
548 | 604 | ||
549 | switch (new_state) { | 605 | switch (new_state) { |
550 | case CAN_STATE_ERROR_ACTIVE: | 606 | case CAN_STATE_ERROR_ACTIVE: |
@@ -596,14 +652,14 @@ static int m_can_handle_state_errors(struct net_device *dev, u32 psr) | |||
596 | 652 | ||
597 | if ((psr & PSR_EP) && | 653 | if ((psr & PSR_EP) && |
598 | (priv->can.state != CAN_STATE_ERROR_PASSIVE)) { | 654 | (priv->can.state != CAN_STATE_ERROR_PASSIVE)) { |
599 | netdev_dbg(dev, "entered error warning state\n"); | 655 | netdev_dbg(dev, "entered error passive state\n"); |
600 | work_done += m_can_handle_state_change(dev, | 656 | work_done += m_can_handle_state_change(dev, |
601 | CAN_STATE_ERROR_PASSIVE); | 657 | CAN_STATE_ERROR_PASSIVE); |
602 | } | 658 | } |
603 | 659 | ||
604 | if ((psr & PSR_BO) && | 660 | if ((psr & PSR_BO) && |
605 | (priv->can.state != CAN_STATE_BUS_OFF)) { | 661 | (priv->can.state != CAN_STATE_BUS_OFF)) { |
606 | netdev_dbg(dev, "entered error warning state\n"); | 662 | netdev_dbg(dev, "entered error bus off state\n"); |
607 | work_done += m_can_handle_state_change(dev, | 663 | work_done += m_can_handle_state_change(dev, |
608 | CAN_STATE_BUS_OFF); | 664 | CAN_STATE_BUS_OFF); |
609 | } | 665 | } |
@@ -615,7 +671,7 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus) | |||
615 | { | 671 | { |
616 | if (irqstatus & IR_WDI) | 672 | if (irqstatus & IR_WDI) |
617 | netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); | 673 | netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); |
618 | if (irqstatus & IR_BEU) | 674 | if (irqstatus & IR_ELO) |
619 | netdev_err(dev, "Error Logging Overflow\n"); | 675 | netdev_err(dev, "Error Logging Overflow\n"); |
620 | if (irqstatus & IR_BEU) | 676 | if (irqstatus & IR_BEU) |
621 | netdev_err(dev, "Bit Error Uncorrected\n"); | 677 | netdev_err(dev, "Bit Error Uncorrected\n"); |
@@ -733,10 +789,23 @@ static const struct can_bittiming_const m_can_bittiming_const = { | |||
733 | .brp_inc = 1, | 789 | .brp_inc = 1, |
734 | }; | 790 | }; |
735 | 791 | ||
792 | static const struct can_bittiming_const m_can_data_bittiming_const = { | ||
793 | .name = KBUILD_MODNAME, | ||
794 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | ||
795 | .tseg1_max = 16, | ||
796 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | ||
797 | .tseg2_max = 8, | ||
798 | .sjw_max = 4, | ||
799 | .brp_min = 1, | ||
800 | .brp_max = 32, | ||
801 | .brp_inc = 1, | ||
802 | }; | ||
803 | |||
736 | static int m_can_set_bittiming(struct net_device *dev) | 804 | static int m_can_set_bittiming(struct net_device *dev) |
737 | { | 805 | { |
738 | struct m_can_priv *priv = netdev_priv(dev); | 806 | struct m_can_priv *priv = netdev_priv(dev); |
739 | const struct can_bittiming *bt = &priv->can.bittiming; | 807 | const struct can_bittiming *bt = &priv->can.bittiming; |
808 | const struct can_bittiming *dbt = &priv->can.data_bittiming; | ||
740 | u16 brp, sjw, tseg1, tseg2; | 809 | u16 brp, sjw, tseg1, tseg2; |
741 | u32 reg_btp; | 810 | u32 reg_btp; |
742 | 811 | ||
@@ -747,7 +816,17 @@ static int m_can_set_bittiming(struct net_device *dev) | |||
747 | reg_btp = (brp << BTR_BRP_SHIFT) | (sjw << BTR_SJW_SHIFT) | | 816 | reg_btp = (brp << BTR_BRP_SHIFT) | (sjw << BTR_SJW_SHIFT) | |
748 | (tseg1 << BTR_TSEG1_SHIFT) | (tseg2 << BTR_TSEG2_SHIFT); | 817 | (tseg1 << BTR_TSEG1_SHIFT) | (tseg2 << BTR_TSEG2_SHIFT); |
749 | m_can_write(priv, M_CAN_BTP, reg_btp); | 818 | m_can_write(priv, M_CAN_BTP, reg_btp); |
750 | netdev_dbg(dev, "setting BTP 0x%x\n", reg_btp); | 819 | |
820 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { | ||
821 | brp = dbt->brp - 1; | ||
822 | sjw = dbt->sjw - 1; | ||
823 | tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; | ||
824 | tseg2 = dbt->phase_seg2 - 1; | ||
825 | reg_btp = (brp << FBTR_FBRP_SHIFT) | (sjw << FBTR_FSJW_SHIFT) | | ||
826 | (tseg1 << FBTR_FTSEG1_SHIFT) | | ||
827 | (tseg2 << FBTR_FTSEG2_SHIFT); | ||
828 | m_can_write(priv, M_CAN_FBTP, reg_btp); | ||
829 | } | ||
751 | 830 | ||
752 | return 0; | 831 | return 0; |
753 | } | 832 | } |
@@ -767,8 +846,8 @@ static void m_can_chip_config(struct net_device *dev) | |||
767 | 846 | ||
768 | m_can_config_endisable(priv, true); | 847 | m_can_config_endisable(priv, true); |
769 | 848 | ||
770 | /* RX Buffer/FIFO Element Size 8 bytes data field */ | 849 | /* RX Buffer/FIFO Element Size 64 bytes data field */ |
771 | m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_8BYTES); | 850 | m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_64BYTES); |
772 | 851 | ||
773 | /* Accept Non-matching Frames Into FIFO 0 */ | 852 | /* Accept Non-matching Frames Into FIFO 0 */ |
774 | m_can_write(priv, M_CAN_GFC, 0x0); | 853 | m_can_write(priv, M_CAN_GFC, 0x0); |
@@ -777,8 +856,8 @@ static void m_can_chip_config(struct net_device *dev) | |||
777 | m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_OFF) | | 856 | m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_OFF) | |
778 | priv->mcfg[MRAM_TXB].off); | 857 | priv->mcfg[MRAM_TXB].off); |
779 | 858 | ||
780 | /* only support 8 bytes firstly */ | 859 | /* support 64 bytes payload */ |
781 | m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_8BYTES); | 860 | m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_64BYTES); |
782 | 861 | ||
783 | m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_OFF) | | 862 | m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_OFF) | |
784 | priv->mcfg[MRAM_TXE].off); | 863 | priv->mcfg[MRAM_TXE].off); |
@@ -793,7 +872,8 @@ static void m_can_chip_config(struct net_device *dev) | |||
793 | RXFC_FWM_1 | priv->mcfg[MRAM_RXF1].off); | 872 | RXFC_FWM_1 | priv->mcfg[MRAM_RXF1].off); |
794 | 873 | ||
795 | cccr = m_can_read(priv, M_CAN_CCCR); | 874 | cccr = m_can_read(priv, M_CAN_CCCR); |
796 | cccr &= ~(CCCR_TEST | CCCR_MON); | 875 | cccr &= ~(CCCR_TEST | CCCR_MON | (CCCR_CMR_MASK << CCCR_CMR_SHIFT) | |
876 | (CCCR_CME_MASK << CCCR_CME_SHIFT)); | ||
797 | test = m_can_read(priv, M_CAN_TEST); | 877 | test = m_can_read(priv, M_CAN_TEST); |
798 | test &= ~TEST_LBCK; | 878 | test &= ~TEST_LBCK; |
799 | 879 | ||
@@ -805,6 +885,9 @@ static void m_can_chip_config(struct net_device *dev) | |||
805 | test |= TEST_LBCK; | 885 | test |= TEST_LBCK; |
806 | } | 886 | } |
807 | 887 | ||
888 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) | ||
889 | cccr |= CCCR_CME_CANFD_BRS << CCCR_CME_SHIFT; | ||
890 | |||
808 | m_can_write(priv, M_CAN_CCCR, cccr); | 891 | m_can_write(priv, M_CAN_CCCR, cccr); |
809 | m_can_write(priv, M_CAN_TEST, test); | 892 | m_can_write(priv, M_CAN_TEST, test); |
810 | 893 | ||
@@ -869,11 +952,13 @@ static struct net_device *alloc_m_can_dev(void) | |||
869 | 952 | ||
870 | priv->dev = dev; | 953 | priv->dev = dev; |
871 | priv->can.bittiming_const = &m_can_bittiming_const; | 954 | priv->can.bittiming_const = &m_can_bittiming_const; |
955 | priv->can.data_bittiming_const = &m_can_data_bittiming_const; | ||
872 | priv->can.do_set_mode = m_can_set_mode; | 956 | priv->can.do_set_mode = m_can_set_mode; |
873 | priv->can.do_get_berr_counter = m_can_get_berr_counter; | 957 | priv->can.do_get_berr_counter = m_can_get_berr_counter; |
874 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | | 958 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
875 | CAN_CTRLMODE_LISTENONLY | | 959 | CAN_CTRLMODE_LISTENONLY | |
876 | CAN_CTRLMODE_BERR_REPORTING; | 960 | CAN_CTRLMODE_BERR_REPORTING | |
961 | CAN_CTRLMODE_FD; | ||
877 | 962 | ||
878 | return dev; | 963 | return dev; |
879 | } | 964 | } |
@@ -956,8 +1041,9 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, | |||
956 | struct net_device *dev) | 1041 | struct net_device *dev) |
957 | { | 1042 | { |
958 | struct m_can_priv *priv = netdev_priv(dev); | 1043 | struct m_can_priv *priv = netdev_priv(dev); |
959 | struct can_frame *cf = (struct can_frame *)skb->data; | 1044 | struct canfd_frame *cf = (struct canfd_frame *)skb->data; |
960 | u32 id; | 1045 | u32 id, cccr; |
1046 | int i; | ||
961 | 1047 | ||
962 | if (can_dropped_invalid_skb(dev, skb)) | 1048 | if (can_dropped_invalid_skb(dev, skb)) |
963 | return NETDEV_TX_OK; | 1049 | return NETDEV_TX_OK; |
@@ -976,11 +1062,28 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, | |||
976 | 1062 | ||
977 | /* message ram configuration */ | 1063 | /* message ram configuration */ |
978 | m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id); | 1064 | m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id); |
979 | m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, cf->can_dlc << 16); | 1065 | m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16); |
980 | m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0)); | 1066 | |
981 | m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4)); | 1067 | for (i = 0; i < cf->len; i += 4) |
1068 | m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4), | ||
1069 | *(u32 *)(cf->data + i)); | ||
1070 | |||
982 | can_put_echo_skb(skb, dev, 0); | 1071 | can_put_echo_skb(skb, dev, 0); |
983 | 1072 | ||
1073 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { | ||
1074 | cccr = m_can_read(priv, M_CAN_CCCR); | ||
1075 | cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT); | ||
1076 | if (can_is_canfd_skb(skb)) { | ||
1077 | if (cf->flags & CANFD_BRS) | ||
1078 | cccr |= CCCR_CMR_CANFD_BRS << CCCR_CMR_SHIFT; | ||
1079 | else | ||
1080 | cccr |= CCCR_CMR_CANFD << CCCR_CMR_SHIFT; | ||
1081 | } else { | ||
1082 | cccr |= CCCR_CMR_CAN << CCCR_CMR_SHIFT; | ||
1083 | } | ||
1084 | m_can_write(priv, M_CAN_CCCR, cccr); | ||
1085 | } | ||
1086 | |||
984 | /* enable first TX buffer to start transfer */ | 1087 | /* enable first TX buffer to start transfer */ |
985 | m_can_write(priv, M_CAN_TXBTIE, 0x1); | 1088 | m_can_write(priv, M_CAN_TXBTIE, 0x1); |
986 | m_can_write(priv, M_CAN_TXBAR, 0x1); | 1089 | m_can_write(priv, M_CAN_TXBAR, 0x1); |
@@ -992,6 +1095,7 @@ static const struct net_device_ops m_can_netdev_ops = { | |||
992 | .ndo_open = m_can_open, | 1095 | .ndo_open = m_can_open, |
993 | .ndo_stop = m_can_close, | 1096 | .ndo_stop = m_can_close, |
994 | .ndo_start_xmit = m_can_start_xmit, | 1097 | .ndo_start_xmit = m_can_start_xmit, |
1098 | .ndo_change_mtu = can_change_mtu, | ||
995 | }; | 1099 | }; |
996 | 1100 | ||
997 | static int register_m_can_dev(struct net_device *dev) | 1101 | static int register_m_can_dev(struct net_device *dev) |
@@ -1009,7 +1113,7 @@ static int m_can_of_parse_mram(struct platform_device *pdev, | |||
1009 | struct resource *res; | 1113 | struct resource *res; |
1010 | void __iomem *addr; | 1114 | void __iomem *addr; |
1011 | u32 out_val[MRAM_CFG_LEN]; | 1115 | u32 out_val[MRAM_CFG_LEN]; |
1012 | int ret; | 1116 | int i, start, end, ret; |
1013 | 1117 | ||
1014 | /* message ram could be shared */ | 1118 | /* message ram could be shared */ |
1015 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram"); | 1119 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram"); |
@@ -1060,6 +1164,15 @@ static int m_can_of_parse_mram(struct platform_device *pdev, | |||
1060 | priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num, | 1164 | priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num, |
1061 | priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num); | 1165 | priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num); |
1062 | 1166 | ||
1167 | /* initialize the entire Message RAM in use to avoid possible | ||
1168 | * ECC/parity checksum errors when reading an uninitialized buffer | ||
1169 | */ | ||
1170 | start = priv->mcfg[MRAM_SIDF].off; | ||
1171 | end = priv->mcfg[MRAM_TXB].off + | ||
1172 | priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; | ||
1173 | for (i = start; i < end; i += 4) | ||
1174 | writel(0x0, priv->mram_base + i); | ||
1175 | |||
1063 | return 0; | 1176 | return 0; |
1064 | } | 1177 | } |
1065 | 1178 | ||
diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index 1abe133d1594..9718248e55f1 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c | |||
@@ -628,6 +628,7 @@ static const struct net_device_ops rcar_can_netdev_ops = { | |||
628 | .ndo_open = rcar_can_open, | 628 | .ndo_open = rcar_can_open, |
629 | .ndo_stop = rcar_can_close, | 629 | .ndo_stop = rcar_can_close, |
630 | .ndo_start_xmit = rcar_can_start_xmit, | 630 | .ndo_start_xmit = rcar_can_start_xmit, |
631 | .ndo_change_mtu = can_change_mtu, | ||
631 | }; | 632 | }; |
632 | 633 | ||
633 | static void rcar_can_rx_pkt(struct rcar_can_priv *priv) | 634 | static void rcar_can_rx_pkt(struct rcar_can_priv *priv) |
diff --git a/drivers/net/can/sja1000/kvaser_pci.c b/drivers/net/can/sja1000/kvaser_pci.c index 8ff3424d5147..15c00faeec61 100644 --- a/drivers/net/can/sja1000/kvaser_pci.c +++ b/drivers/net/can/sja1000/kvaser_pci.c | |||
@@ -214,7 +214,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, | |||
214 | struct net_device *dev; | 214 | struct net_device *dev; |
215 | struct sja1000_priv *priv; | 215 | struct sja1000_priv *priv; |
216 | struct kvaser_pci *board; | 216 | struct kvaser_pci *board; |
217 | int err, init_step; | 217 | int err; |
218 | 218 | ||
219 | dev = alloc_sja1000dev(sizeof(struct kvaser_pci)); | 219 | dev = alloc_sja1000dev(sizeof(struct kvaser_pci)); |
220 | if (dev == NULL) | 220 | if (dev == NULL) |
@@ -235,7 +235,6 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, | |||
235 | if (channel == 0) { | 235 | if (channel == 0) { |
236 | board->xilinx_ver = | 236 | board->xilinx_ver = |
237 | ioread8(board->res_addr + XILINX_VERINT) >> 4; | 237 | ioread8(board->res_addr + XILINX_VERINT) >> 4; |
238 | init_step = 2; | ||
239 | 238 | ||
240 | /* Assert PTADR# - we're in passive mode so the other bits are | 239 | /* Assert PTADR# - we're in passive mode so the other bits are |
241 | not important */ | 240 | not important */ |
@@ -264,8 +263,6 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, | |||
264 | priv->irq_flags = IRQF_SHARED; | 263 | priv->irq_flags = IRQF_SHARED; |
265 | dev->irq = pdev->irq; | 264 | dev->irq = pdev->irq; |
266 | 265 | ||
267 | init_step = 4; | ||
268 | |||
269 | dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n", | 266 | dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n", |
270 | priv->reg_base, board->conf_addr, dev->irq); | 267 | priv->reg_base, board->conf_addr, dev->irq); |
271 | 268 | ||
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 00f2534dde73..29d3f0938eb8 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c | |||
@@ -434,10 +434,9 @@ static void ems_usb_read_bulk_callback(struct urb *urb) | |||
434 | if (urb->actual_length > CPC_HEADER_SIZE) { | 434 | if (urb->actual_length > CPC_HEADER_SIZE) { |
435 | struct ems_cpc_msg *msg; | 435 | struct ems_cpc_msg *msg; |
436 | u8 *ibuf = urb->transfer_buffer; | 436 | u8 *ibuf = urb->transfer_buffer; |
437 | u8 msg_count, again, start; | 437 | u8 msg_count, start; |
438 | 438 | ||
439 | msg_count = ibuf[0] & ~0x80; | 439 | msg_count = ibuf[0] & ~0x80; |
440 | again = ibuf[0] & 0x80; | ||
441 | 440 | ||
442 | start = CPC_HEADER_SIZE; | 441 | start = CPC_HEADER_SIZE; |
443 | 442 | ||
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index b7c9e8b11460..c063a54ab8dd 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c | |||
@@ -464,7 +464,6 @@ static void esd_usb2_write_bulk_callback(struct urb *urb) | |||
464 | { | 464 | { |
465 | struct esd_tx_urb_context *context = urb->context; | 465 | struct esd_tx_urb_context *context = urb->context; |
466 | struct esd_usb2_net_priv *priv; | 466 | struct esd_usb2_net_priv *priv; |
467 | struct esd_usb2 *dev; | ||
468 | struct net_device *netdev; | 467 | struct net_device *netdev; |
469 | size_t size = sizeof(struct esd_usb2_msg); | 468 | size_t size = sizeof(struct esd_usb2_msg); |
470 | 469 | ||
@@ -472,7 +471,6 @@ static void esd_usb2_write_bulk_callback(struct urb *urb) | |||
472 | 471 | ||
473 | priv = context->priv; | 472 | priv = context->priv; |
474 | netdev = priv->netdev; | 473 | netdev = priv->netdev; |
475 | dev = priv->usb2; | ||
476 | 474 | ||
477 | /* free up our allocated buffer */ | 475 | /* free up our allocated buffer */ |
478 | usb_free_coherent(urb->dev, size, | 476 | usb_free_coherent(urb->dev, size, |
@@ -1143,6 +1141,7 @@ static void esd_usb2_disconnect(struct usb_interface *intf) | |||
1143 | } | 1141 | } |
1144 | } | 1142 | } |
1145 | unlink_all_urbs(dev); | 1143 | unlink_all_urbs(dev); |
1144 | kfree(dev); | ||
1146 | } | 1145 | } |
1147 | } | 1146 | } |
1148 | 1147 | ||
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 04b0f84612f0..009acc8641fc 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c | |||
@@ -718,6 +718,7 @@ static const struct net_device_ops gs_usb_netdev_ops = { | |||
718 | .ndo_open = gs_can_open, | 718 | .ndo_open = gs_can_open, |
719 | .ndo_stop = gs_can_close, | 719 | .ndo_stop = gs_can_close, |
720 | .ndo_start_xmit = gs_can_start_xmit, | 720 | .ndo_start_xmit = gs_can_start_xmit, |
721 | .ndo_change_mtu = can_change_mtu, | ||
721 | }; | 722 | }; |
722 | 723 | ||
723 | static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface *intf) | 724 | static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface *intf) |
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 5e8b5609c067..8a998e3884ce 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c | |||
@@ -300,7 +300,8 @@ static int xcan_set_bittiming(struct net_device *ndev) | |||
300 | static int xcan_chip_start(struct net_device *ndev) | 300 | static int xcan_chip_start(struct net_device *ndev) |
301 | { | 301 | { |
302 | struct xcan_priv *priv = netdev_priv(ndev); | 302 | struct xcan_priv *priv = netdev_priv(ndev); |
303 | u32 err, reg_msr, reg_sr_mask; | 303 | u32 reg_msr, reg_sr_mask; |
304 | int err; | ||
304 | unsigned long timeout; | 305 | unsigned long timeout; |
305 | 306 | ||
306 | /* Check if it is in reset mode */ | 307 | /* Check if it is in reset mode */ |
@@ -961,6 +962,7 @@ static const struct net_device_ops xcan_netdev_ops = { | |||
961 | .ndo_open = xcan_open, | 962 | .ndo_open = xcan_open, |
962 | .ndo_stop = xcan_close, | 963 | .ndo_stop = xcan_close, |
963 | .ndo_start_xmit = xcan_start_xmit, | 964 | .ndo_start_xmit = xcan_start_xmit, |
965 | .ndo_change_mtu = can_change_mtu, | ||
964 | }; | 966 | }; |
965 | 967 | ||
966 | /** | 968 | /** |
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index b9625968daac..4f4c2a7888e5 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c | |||
@@ -377,6 +377,29 @@ static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id) | |||
377 | return IRQ_HANDLED; | 377 | return IRQ_HANDLED; |
378 | } | 378 | } |
379 | 379 | ||
380 | static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv) | ||
381 | { | ||
382 | unsigned int timeout = 1000; | ||
383 | u32 reg; | ||
384 | |||
385 | reg = core_readl(priv, CORE_WATCHDOG_CTRL); | ||
386 | reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET; | ||
387 | core_writel(priv, reg, CORE_WATCHDOG_CTRL); | ||
388 | |||
389 | do { | ||
390 | reg = core_readl(priv, CORE_WATCHDOG_CTRL); | ||
391 | if (!(reg & SOFTWARE_RESET)) | ||
392 | break; | ||
393 | |||
394 | usleep_range(1000, 2000); | ||
395 | } while (timeout-- > 0); | ||
396 | |||
397 | if (timeout == 0) | ||
398 | return -ETIMEDOUT; | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
380 | static int bcm_sf2_sw_setup(struct dsa_switch *ds) | 403 | static int bcm_sf2_sw_setup(struct dsa_switch *ds) |
381 | { | 404 | { |
382 | const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; | 405 | const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; |
@@ -404,11 +427,18 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) | |||
404 | *base = of_iomap(dn, i); | 427 | *base = of_iomap(dn, i); |
405 | if (*base == NULL) { | 428 | if (*base == NULL) { |
406 | pr_err("unable to find register: %s\n", reg_names[i]); | 429 | pr_err("unable to find register: %s\n", reg_names[i]); |
407 | return -ENODEV; | 430 | ret = -ENOMEM; |
431 | goto out_unmap; | ||
408 | } | 432 | } |
409 | base++; | 433 | base++; |
410 | } | 434 | } |
411 | 435 | ||
436 | ret = bcm_sf2_sw_rst(priv); | ||
437 | if (ret) { | ||
438 | pr_err("unable to software reset switch: %d\n", ret); | ||
439 | goto out_unmap; | ||
440 | } | ||
441 | |||
412 | /* Disable all interrupts and request them */ | 442 | /* Disable all interrupts and request them */ |
413 | intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); | 443 | intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); |
414 | intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); | 444 | intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); |
@@ -484,7 +514,8 @@ out_free_irq0: | |||
484 | out_unmap: | 514 | out_unmap: |
485 | base = &priv->core; | 515 | base = &priv->core; |
486 | for (i = 0; i < BCM_SF2_REGS_NUM; i++) { | 516 | for (i = 0; i < BCM_SF2_REGS_NUM; i++) { |
487 | iounmap(*base); | 517 | if (*base) |
518 | iounmap(*base); | ||
488 | base++; | 519 | base++; |
489 | } | 520 | } |
490 | return ret; | 521 | return ret; |
@@ -733,29 +764,6 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds) | |||
733 | return 0; | 764 | return 0; |
734 | } | 765 | } |
735 | 766 | ||
736 | static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv) | ||
737 | { | ||
738 | unsigned int timeout = 1000; | ||
739 | u32 reg; | ||
740 | |||
741 | reg = core_readl(priv, CORE_WATCHDOG_CTRL); | ||
742 | reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET; | ||
743 | core_writel(priv, reg, CORE_WATCHDOG_CTRL); | ||
744 | |||
745 | do { | ||
746 | reg = core_readl(priv, CORE_WATCHDOG_CTRL); | ||
747 | if (!(reg & SOFTWARE_RESET)) | ||
748 | break; | ||
749 | |||
750 | usleep_range(1000, 2000); | ||
751 | } while (timeout-- > 0); | ||
752 | |||
753 | if (timeout == 0) | ||
754 | return -ETIMEDOUT; | ||
755 | |||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | static int bcm_sf2_sw_resume(struct dsa_switch *ds) | 767 | static int bcm_sf2_sw_resume(struct dsa_switch *ds) |
760 | { | 768 | { |
761 | struct bcm_sf2_priv *priv = ds_to_priv(ds); | 769 | struct bcm_sf2_priv *priv = ds_to_priv(ds); |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index dbb41c1923e6..77f8f836cbbe 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -8563,7 +8563,8 @@ static int tg3_init_rings(struct tg3 *tp) | |||
8563 | if (tnapi->rx_rcb) | 8563 | if (tnapi->rx_rcb) |
8564 | memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); | 8564 | memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); |
8565 | 8565 | ||
8566 | if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) { | 8566 | if (tnapi->prodring.rx_std && |
8567 | tg3_rx_prodring_alloc(tp, &tnapi->prodring)) { | ||
8567 | tg3_free_rings(tp); | 8568 | tg3_free_rings(tp); |
8568 | return -ENOMEM; | 8569 | return -ENOMEM; |
8569 | } | 8570 | } |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c index cca604994003..4fe33606f372 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | |||
@@ -1082,7 +1082,7 @@ static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg) | |||
1082 | pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid); | 1082 | pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid); |
1083 | 1083 | ||
1084 | for (i = 0; i < CXGB4_MAX_PRIORITY; i++) | 1084 | for (i = 0; i < CXGB4_MAX_PRIORITY; i++) |
1085 | pg->prio_pg[i] = (pgid >> (i * 4)) & 0xF; | 1085 | pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF; |
1086 | 1086 | ||
1087 | INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); | 1087 | INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); |
1088 | pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; | 1088 | pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 9a18e7930b31..597c463e384d 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -4309,11 +4309,16 @@ static int be_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh) | |||
4309 | return -EOPNOTSUPP; | 4309 | return -EOPNOTSUPP; |
4310 | 4310 | ||
4311 | br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); | 4311 | br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); |
4312 | if (!br_spec) | ||
4313 | return -EINVAL; | ||
4312 | 4314 | ||
4313 | nla_for_each_nested(attr, br_spec, rem) { | 4315 | nla_for_each_nested(attr, br_spec, rem) { |
4314 | if (nla_type(attr) != IFLA_BRIDGE_MODE) | 4316 | if (nla_type(attr) != IFLA_BRIDGE_MODE) |
4315 | continue; | 4317 | continue; |
4316 | 4318 | ||
4319 | if (nla_len(attr) < sizeof(mode)) | ||
4320 | return -EINVAL; | ||
4321 | |||
4317 | mode = nla_get_u16(attr); | 4322 | mode = nla_get_u16(attr); |
4318 | if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB) | 4323 | if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB) |
4319 | return -EINVAL; | 4324 | return -EINVAL; |
@@ -4421,6 +4426,11 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | |||
4421 | "Disabled VxLAN offloads for UDP port %d\n", | 4426 | "Disabled VxLAN offloads for UDP port %d\n", |
4422 | be16_to_cpu(port)); | 4427 | be16_to_cpu(port)); |
4423 | } | 4428 | } |
4429 | |||
4430 | static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) | ||
4431 | { | ||
4432 | return vxlan_gso_check(skb); | ||
4433 | } | ||
4424 | #endif | 4434 | #endif |
4425 | 4435 | ||
4426 | static const struct net_device_ops be_netdev_ops = { | 4436 | static const struct net_device_ops be_netdev_ops = { |
@@ -4450,6 +4460,7 @@ static const struct net_device_ops be_netdev_ops = { | |||
4450 | #ifdef CONFIG_BE2NET_VXLAN | 4460 | #ifdef CONFIG_BE2NET_VXLAN |
4451 | .ndo_add_vxlan_port = be_add_vxlan_port, | 4461 | .ndo_add_vxlan_port = be_add_vxlan_port, |
4452 | .ndo_del_vxlan_port = be_del_vxlan_port, | 4462 | .ndo_del_vxlan_port = be_del_vxlan_port, |
4463 | .ndo_gso_check = be_gso_check, | ||
4453 | #endif | 4464 | #endif |
4454 | }; | 4465 | }; |
4455 | 4466 | ||
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index a2d72a87cbde..487cd9c4ac0d 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -1012,7 +1012,8 @@ static void igb_free_q_vector(struct igb_adapter *adapter, int v_idx) | |||
1012 | /* igb_get_stats64() might access the rings on this vector, | 1012 | /* igb_get_stats64() might access the rings on this vector, |
1013 | * we must wait a grace period before freeing it. | 1013 | * we must wait a grace period before freeing it. |
1014 | */ | 1014 | */ |
1015 | kfree_rcu(q_vector, rcu); | 1015 | if (q_vector) |
1016 | kfree_rcu(q_vector, rcu); | ||
1016 | } | 1017 | } |
1017 | 1018 | ||
1018 | /** | 1019 | /** |
@@ -1792,8 +1793,10 @@ void igb_down(struct igb_adapter *adapter) | |||
1792 | adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; | 1793 | adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; |
1793 | 1794 | ||
1794 | for (i = 0; i < adapter->num_q_vectors; i++) { | 1795 | for (i = 0; i < adapter->num_q_vectors; i++) { |
1795 | napi_synchronize(&(adapter->q_vector[i]->napi)); | 1796 | if (adapter->q_vector[i]) { |
1796 | napi_disable(&(adapter->q_vector[i]->napi)); | 1797 | napi_synchronize(&adapter->q_vector[i]->napi); |
1798 | napi_disable(&adapter->q_vector[i]->napi); | ||
1799 | } | ||
1797 | } | 1800 | } |
1798 | 1801 | ||
1799 | 1802 | ||
@@ -3717,7 +3720,8 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter) | |||
3717 | int i; | 3720 | int i; |
3718 | 3721 | ||
3719 | for (i = 0; i < adapter->num_tx_queues; i++) | 3722 | for (i = 0; i < adapter->num_tx_queues; i++) |
3720 | igb_free_tx_resources(adapter->tx_ring[i]); | 3723 | if (adapter->tx_ring[i]) |
3724 | igb_free_tx_resources(adapter->tx_ring[i]); | ||
3721 | } | 3725 | } |
3722 | 3726 | ||
3723 | void igb_unmap_and_free_tx_resource(struct igb_ring *ring, | 3727 | void igb_unmap_and_free_tx_resource(struct igb_ring *ring, |
@@ -3782,7 +3786,8 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter) | |||
3782 | int i; | 3786 | int i; |
3783 | 3787 | ||
3784 | for (i = 0; i < adapter->num_tx_queues; i++) | 3788 | for (i = 0; i < adapter->num_tx_queues; i++) |
3785 | igb_clean_tx_ring(adapter->tx_ring[i]); | 3789 | if (adapter->tx_ring[i]) |
3790 | igb_clean_tx_ring(adapter->tx_ring[i]); | ||
3786 | } | 3791 | } |
3787 | 3792 | ||
3788 | /** | 3793 | /** |
@@ -3819,7 +3824,8 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter) | |||
3819 | int i; | 3824 | int i; |
3820 | 3825 | ||
3821 | for (i = 0; i < adapter->num_rx_queues; i++) | 3826 | for (i = 0; i < adapter->num_rx_queues; i++) |
3822 | igb_free_rx_resources(adapter->rx_ring[i]); | 3827 | if (adapter->rx_ring[i]) |
3828 | igb_free_rx_resources(adapter->rx_ring[i]); | ||
3823 | } | 3829 | } |
3824 | 3830 | ||
3825 | /** | 3831 | /** |
@@ -3874,7 +3880,8 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter) | |||
3874 | int i; | 3880 | int i; |
3875 | 3881 | ||
3876 | for (i = 0; i < adapter->num_rx_queues; i++) | 3882 | for (i = 0; i < adapter->num_rx_queues; i++) |
3877 | igb_clean_rx_ring(adapter->rx_ring[i]); | 3883 | if (adapter->rx_ring[i]) |
3884 | igb_clean_rx_ring(adapter->rx_ring[i]); | ||
3878 | } | 3885 | } |
3879 | 3886 | ||
3880 | /** | 3887 | /** |
@@ -7404,6 +7411,8 @@ static int igb_resume(struct device *dev) | |||
7404 | pci_restore_state(pdev); | 7411 | pci_restore_state(pdev); |
7405 | pci_save_state(pdev); | 7412 | pci_save_state(pdev); |
7406 | 7413 | ||
7414 | if (!pci_device_is_present(pdev)) | ||
7415 | return -ENODEV; | ||
7407 | err = pci_enable_device_mem(pdev); | 7416 | err = pci_enable_device_mem(pdev); |
7408 | if (err) { | 7417 | if (err) { |
7409 | dev_err(&pdev->dev, | 7418 | dev_err(&pdev->dev, |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d2df4e3d1032..cc51554c9e99 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -3936,8 +3936,8 @@ void ixgbe_set_rx_mode(struct net_device *netdev) | |||
3936 | * if SR-IOV and VMDQ are disabled - otherwise ensure | 3936 | * if SR-IOV and VMDQ are disabled - otherwise ensure |
3937 | * that hardware VLAN filters remain enabled. | 3937 | * that hardware VLAN filters remain enabled. |
3938 | */ | 3938 | */ |
3939 | if (!(adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED | | 3939 | if (adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED | |
3940 | IXGBE_FLAG_SRIOV_ENABLED))) | 3940 | IXGBE_FLAG_SRIOV_ENABLED)) |
3941 | vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); | 3941 | vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); |
3942 | } else { | 3942 | } else { |
3943 | if (netdev->flags & IFF_ALLMULTI) { | 3943 | if (netdev->flags & IFF_ALLMULTI) { |
@@ -7669,6 +7669,8 @@ static int ixgbe_ndo_bridge_setlink(struct net_device *dev, | |||
7669 | return -EOPNOTSUPP; | 7669 | return -EOPNOTSUPP; |
7670 | 7670 | ||
7671 | br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); | 7671 | br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); |
7672 | if (!br_spec) | ||
7673 | return -EINVAL; | ||
7672 | 7674 | ||
7673 | nla_for_each_nested(attr, br_spec, rem) { | 7675 | nla_for_each_nested(attr, br_spec, rem) { |
7674 | __u16 mode; | 7676 | __u16 mode; |
@@ -7677,6 +7679,9 @@ static int ixgbe_ndo_bridge_setlink(struct net_device *dev, | |||
7677 | if (nla_type(attr) != IFLA_BRIDGE_MODE) | 7679 | if (nla_type(attr) != IFLA_BRIDGE_MODE) |
7678 | continue; | 7680 | continue; |
7679 | 7681 | ||
7682 | if (nla_len(attr) < sizeof(mode)) | ||
7683 | return -EINVAL; | ||
7684 | |||
7680 | mode = nla_get_u16(attr); | 7685 | mode = nla_get_u16(attr); |
7681 | if (mode == BRIDGE_MODE_VEPA) { | 7686 | if (mode == BRIDGE_MODE_VEPA) { |
7682 | reg = 0; | 7687 | reg = 0; |
@@ -7979,6 +7984,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7979 | int i, err, pci_using_dac, expected_gts; | 7984 | int i, err, pci_using_dac, expected_gts; |
7980 | unsigned int indices = MAX_TX_QUEUES; | 7985 | unsigned int indices = MAX_TX_QUEUES; |
7981 | u8 part_str[IXGBE_PBANUM_LENGTH]; | 7986 | u8 part_str[IXGBE_PBANUM_LENGTH]; |
7987 | bool disable_dev = false; | ||
7982 | #ifdef IXGBE_FCOE | 7988 | #ifdef IXGBE_FCOE |
7983 | u16 device_caps; | 7989 | u16 device_caps; |
7984 | #endif | 7990 | #endif |
@@ -8369,13 +8375,14 @@ err_sw_init: | |||
8369 | iounmap(adapter->io_addr); | 8375 | iounmap(adapter->io_addr); |
8370 | kfree(adapter->mac_table); | 8376 | kfree(adapter->mac_table); |
8371 | err_ioremap: | 8377 | err_ioremap: |
8378 | disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); | ||
8372 | free_netdev(netdev); | 8379 | free_netdev(netdev); |
8373 | err_alloc_etherdev: | 8380 | err_alloc_etherdev: |
8374 | pci_release_selected_regions(pdev, | 8381 | pci_release_selected_regions(pdev, |
8375 | pci_select_bars(pdev, IORESOURCE_MEM)); | 8382 | pci_select_bars(pdev, IORESOURCE_MEM)); |
8376 | err_pci_reg: | 8383 | err_pci_reg: |
8377 | err_dma: | 8384 | err_dma: |
8378 | if (!adapter || !test_and_set_bit(__IXGBE_DISABLED, &adapter->state)) | 8385 | if (!adapter || disable_dev) |
8379 | pci_disable_device(pdev); | 8386 | pci_disable_device(pdev); |
8380 | return err; | 8387 | return err; |
8381 | } | 8388 | } |
@@ -8393,6 +8400,7 @@ static void ixgbe_remove(struct pci_dev *pdev) | |||
8393 | { | 8400 | { |
8394 | struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); | 8401 | struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); |
8395 | struct net_device *netdev = adapter->netdev; | 8402 | struct net_device *netdev = adapter->netdev; |
8403 | bool disable_dev; | ||
8396 | 8404 | ||
8397 | ixgbe_dbg_adapter_exit(adapter); | 8405 | ixgbe_dbg_adapter_exit(adapter); |
8398 | 8406 | ||
@@ -8442,11 +8450,12 @@ static void ixgbe_remove(struct pci_dev *pdev) | |||
8442 | e_dev_info("complete\n"); | 8450 | e_dev_info("complete\n"); |
8443 | 8451 | ||
8444 | kfree(adapter->mac_table); | 8452 | kfree(adapter->mac_table); |
8453 | disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); | ||
8445 | free_netdev(netdev); | 8454 | free_netdev(netdev); |
8446 | 8455 | ||
8447 | pci_disable_pcie_error_reporting(pdev); | 8456 | pci_disable_pcie_error_reporting(pdev); |
8448 | 8457 | ||
8449 | if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state)) | 8458 | if (disable_dev) |
8450 | pci_disable_device(pdev); | 8459 | pci_disable_device(pdev); |
8451 | } | 8460 | } |
8452 | 8461 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 02266e3de514..4d69e382b4e5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -1693,7 +1693,7 @@ int mlx4_en_start_port(struct net_device *dev) | |||
1693 | mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); | 1693 | mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); |
1694 | 1694 | ||
1695 | #ifdef CONFIG_MLX4_EN_VXLAN | 1695 | #ifdef CONFIG_MLX4_EN_VXLAN |
1696 | if (priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) | 1696 | if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) |
1697 | vxlan_get_rx_port(dev); | 1697 | vxlan_get_rx_port(dev); |
1698 | #endif | 1698 | #endif |
1699 | priv->port_up = true; | 1699 | priv->port_up = true; |
@@ -2355,6 +2355,11 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev, | |||
2355 | 2355 | ||
2356 | queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); | 2356 | queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); |
2357 | } | 2357 | } |
2358 | |||
2359 | static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev) | ||
2360 | { | ||
2361 | return vxlan_gso_check(skb); | ||
2362 | } | ||
2358 | #endif | 2363 | #endif |
2359 | 2364 | ||
2360 | static const struct net_device_ops mlx4_netdev_ops = { | 2365 | static const struct net_device_ops mlx4_netdev_ops = { |
@@ -2386,6 +2391,7 @@ static const struct net_device_ops mlx4_netdev_ops = { | |||
2386 | #ifdef CONFIG_MLX4_EN_VXLAN | 2391 | #ifdef CONFIG_MLX4_EN_VXLAN |
2387 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, | 2392 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, |
2388 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, | 2393 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, |
2394 | .ndo_gso_check = mlx4_en_gso_check, | ||
2389 | #endif | 2395 | #endif |
2390 | }; | 2396 | }; |
2391 | 2397 | ||
@@ -2416,6 +2422,11 @@ static const struct net_device_ops mlx4_netdev_ops_master = { | |||
2416 | .ndo_rx_flow_steer = mlx4_en_filter_rfs, | 2422 | .ndo_rx_flow_steer = mlx4_en_filter_rfs, |
2417 | #endif | 2423 | #endif |
2418 | .ndo_get_phys_port_id = mlx4_en_get_phys_port_id, | 2424 | .ndo_get_phys_port_id = mlx4_en_get_phys_port_id, |
2425 | #ifdef CONFIG_MLX4_EN_VXLAN | ||
2426 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, | ||
2427 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, | ||
2428 | .ndo_gso_check = mlx4_en_gso_check, | ||
2429 | #endif | ||
2419 | }; | 2430 | }; |
2420 | 2431 | ||
2421 | int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | 2432 | int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 5d2498dcf536..cd5cf6d957c7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -1546,7 +1546,7 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, | |||
1546 | 1546 | ||
1547 | switch (op) { | 1547 | switch (op) { |
1548 | case RES_OP_RESERVE: | 1548 | case RES_OP_RESERVE: |
1549 | count = get_param_l(&in_param); | 1549 | count = get_param_l(&in_param) & 0xffffff; |
1550 | align = get_param_h(&in_param); | 1550 | align = get_param_h(&in_param); |
1551 | err = mlx4_grant_resource(dev, slave, RES_QP, count, 0); | 1551 | err = mlx4_grant_resource(dev, slave, RES_QP, count, 0); |
1552 | if (err) | 1552 | if (err) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index f5e29f7bdae3..a913b3ad2f89 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -503,6 +503,11 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev, | |||
503 | 503 | ||
504 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; | 504 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; |
505 | } | 505 | } |
506 | |||
507 | static bool qlcnic_gso_check(struct sk_buff *skb, struct net_device *dev) | ||
508 | { | ||
509 | return vxlan_gso_check(skb); | ||
510 | } | ||
506 | #endif | 511 | #endif |
507 | 512 | ||
508 | static const struct net_device_ops qlcnic_netdev_ops = { | 513 | static const struct net_device_ops qlcnic_netdev_ops = { |
@@ -526,6 +531,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
526 | #ifdef CONFIG_QLCNIC_VXLAN | 531 | #ifdef CONFIG_QLCNIC_VXLAN |
527 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, | 532 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, |
528 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, | 533 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, |
534 | .ndo_gso_check = qlcnic_gso_check, | ||
529 | #endif | 535 | #endif |
530 | #ifdef CONFIG_NET_POLL_CONTROLLER | 536 | #ifdef CONFIG_NET_POLL_CONTROLLER |
531 | .ndo_poll_controller = qlcnic_poll_controller, | 537 | .ndo_poll_controller = qlcnic_poll_controller, |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index db56fa7ce8f9..5b0da3986216 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -177,12 +177,6 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, | |||
177 | */ | 177 | */ |
178 | plat->maxmtu = JUMBO_LEN; | 178 | plat->maxmtu = JUMBO_LEN; |
179 | 179 | ||
180 | /* Set default value for multicast hash bins */ | ||
181 | plat->multicast_filter_bins = HASH_TABLE_SIZE; | ||
182 | |||
183 | /* Set default value for unicast filter entries */ | ||
184 | plat->unicast_filter_entries = 1; | ||
185 | |||
186 | /* | 180 | /* |
187 | * Currently only the properties needed on SPEAr600 | 181 | * Currently only the properties needed on SPEAr600 |
188 | * are provided. All other properties should be added | 182 | * are provided. All other properties should be added |
@@ -270,6 +264,13 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) | |||
270 | return PTR_ERR(addr); | 264 | return PTR_ERR(addr); |
271 | 265 | ||
272 | plat_dat = dev_get_platdata(&pdev->dev); | 266 | plat_dat = dev_get_platdata(&pdev->dev); |
267 | |||
268 | /* Set default value for multicast hash bins */ | ||
269 | plat_dat->multicast_filter_bins = HASH_TABLE_SIZE; | ||
270 | |||
271 | /* Set default value for unicast filter entries */ | ||
272 | plat_dat->unicast_filter_entries = 1; | ||
273 | |||
273 | if (pdev->dev.of_node) { | 274 | if (pdev->dev.of_node) { |
274 | if (!plat_dat) | 275 | if (!plat_dat) |
275 | plat_dat = devm_kzalloc(&pdev->dev, | 276 | plat_dat = devm_kzalloc(&pdev->dev, |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index d8794488f80a..c560f9aeb55d 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -129,9 +129,9 @@ do { \ | |||
129 | #define CPSW_VLAN_AWARE BIT(1) | 129 | #define CPSW_VLAN_AWARE BIT(1) |
130 | #define CPSW_ALE_VLAN_AWARE 1 | 130 | #define CPSW_ALE_VLAN_AWARE 1 |
131 | 131 | ||
132 | #define CPSW_FIFO_NORMAL_MODE (0 << 15) | 132 | #define CPSW_FIFO_NORMAL_MODE (0 << 16) |
133 | #define CPSW_FIFO_DUAL_MAC_MODE (1 << 15) | 133 | #define CPSW_FIFO_DUAL_MAC_MODE (1 << 16) |
134 | #define CPSW_FIFO_RATE_LIMIT_MODE (2 << 15) | 134 | #define CPSW_FIFO_RATE_LIMIT_MODE (2 << 16) |
135 | 135 | ||
136 | #define CPSW_INTPACEEN (0x3f << 16) | 136 | #define CPSW_INTPACEEN (0x3f << 16) |
137 | #define CPSW_INTPRESCALE_MASK (0x7FF << 0) | 137 | #define CPSW_INTPRESCALE_MASK (0x7FF << 0) |
diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 9ce854f43917..6cbc56ad9ff4 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c | |||
@@ -377,17 +377,20 @@ static int ieee802154fake_probe(struct platform_device *pdev) | |||
377 | 377 | ||
378 | err = wpan_phy_register(phy); | 378 | err = wpan_phy_register(phy); |
379 | if (err) | 379 | if (err) |
380 | goto out; | 380 | goto err_phy_reg; |
381 | 381 | ||
382 | err = register_netdev(dev); | 382 | err = register_netdev(dev); |
383 | if (err < 0) | 383 | if (err) |
384 | goto out; | 384 | goto err_netdev_reg; |
385 | 385 | ||
386 | dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); | 386 | dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); |
387 | return 0; | 387 | return 0; |
388 | 388 | ||
389 | out: | 389 | err_netdev_reg: |
390 | unregister_netdev(dev); | 390 | wpan_phy_unregister(phy); |
391 | err_phy_reg: | ||
392 | free_netdev(dev); | ||
393 | wpan_phy_free(phy); | ||
391 | return err; | 394 | return err; |
392 | } | 395 | } |
393 | 396 | ||
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 1aff970be33e..1dc628ffce2b 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c | |||
@@ -506,7 +506,9 @@ static int pptp_getname(struct socket *sock, struct sockaddr *uaddr, | |||
506 | int len = sizeof(struct sockaddr_pppox); | 506 | int len = sizeof(struct sockaddr_pppox); |
507 | struct sockaddr_pppox sp; | 507 | struct sockaddr_pppox sp; |
508 | 508 | ||
509 | sp.sa_family = AF_PPPOX; | 509 | memset(&sp.sa_addr, 0, sizeof(sp.sa_addr)); |
510 | |||
511 | sp.sa_family = AF_PPPOX; | ||
510 | sp.sa_protocol = PX_PROTO_PPTP; | 512 | sp.sa_protocol = PX_PROTO_PPTP; |
511 | sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr; | 513 | sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr; |
512 | 514 | ||
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 22756db53dca..b8a82b86f909 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -780,6 +780,7 @@ static const struct usb_device_id products[] = { | |||
780 | {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ | 780 | {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ |
781 | {QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */ | 781 | {QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */ |
782 | {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ | 782 | {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ |
783 | {QMI_FIXED_INTF(0x03f0, 0x581d, 4)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */ | ||
783 | 784 | ||
784 | /* 4. Gobi 1000 devices */ | 785 | /* 4. Gobi 1000 devices */ |
785 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 786 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index ec2a8b41ed41..b0bc8ead47de 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -1673,6 +1673,40 @@ static const struct attribute_group virtio_net_mrg_rx_group = { | |||
1673 | }; | 1673 | }; |
1674 | #endif | 1674 | #endif |
1675 | 1675 | ||
1676 | static bool virtnet_fail_on_feature(struct virtio_device *vdev, | ||
1677 | unsigned int fbit, | ||
1678 | const char *fname, const char *dname) | ||
1679 | { | ||
1680 | if (!virtio_has_feature(vdev, fbit)) | ||
1681 | return false; | ||
1682 | |||
1683 | dev_err(&vdev->dev, "device advertises feature %s but not %s", | ||
1684 | fname, dname); | ||
1685 | |||
1686 | return true; | ||
1687 | } | ||
1688 | |||
1689 | #define VIRTNET_FAIL_ON(vdev, fbit, dbit) \ | ||
1690 | virtnet_fail_on_feature(vdev, fbit, #fbit, dbit) | ||
1691 | |||
1692 | static bool virtnet_validate_features(struct virtio_device *vdev) | ||
1693 | { | ||
1694 | if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ) && | ||
1695 | (VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_RX, | ||
1696 | "VIRTIO_NET_F_CTRL_VQ") || | ||
1697 | VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_VLAN, | ||
1698 | "VIRTIO_NET_F_CTRL_VQ") || | ||
1699 | VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE, | ||
1700 | "VIRTIO_NET_F_CTRL_VQ") || | ||
1701 | VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_MQ, "VIRTIO_NET_F_CTRL_VQ") || | ||
1702 | VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR, | ||
1703 | "VIRTIO_NET_F_CTRL_VQ"))) { | ||
1704 | return false; | ||
1705 | } | ||
1706 | |||
1707 | return true; | ||
1708 | } | ||
1709 | |||
1676 | static int virtnet_probe(struct virtio_device *vdev) | 1710 | static int virtnet_probe(struct virtio_device *vdev) |
1677 | { | 1711 | { |
1678 | int i, err; | 1712 | int i, err; |
@@ -1680,6 +1714,9 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1680 | struct virtnet_info *vi; | 1714 | struct virtnet_info *vi; |
1681 | u16 max_queue_pairs; | 1715 | u16 max_queue_pairs; |
1682 | 1716 | ||
1717 | if (!virtnet_validate_features(vdev)) | ||
1718 | return -EINVAL; | ||
1719 | |||
1683 | /* Find if host supports multiqueue virtio_net device */ | 1720 | /* Find if host supports multiqueue virtio_net device */ |
1684 | err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ, | 1721 | err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ, |
1685 | struct virtio_net_config, | 1722 | struct virtio_net_config, |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index fa9dc45b75a6..be4649a49c5e 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -67,12 +67,6 @@ | |||
67 | 67 | ||
68 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ | 68 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ |
69 | 69 | ||
70 | /* VXLAN protocol header */ | ||
71 | struct vxlanhdr { | ||
72 | __be32 vx_flags; | ||
73 | __be32 vx_vni; | ||
74 | }; | ||
75 | |||
76 | /* UDP port for VXLAN traffic. | 70 | /* UDP port for VXLAN traffic. |
77 | * The IANA assigned port is 4789, but the Linux default is 8472 | 71 | * The IANA assigned port is 4789, but the Linux default is 8472 |
78 | * for compatibility with early adopters. | 72 | * for compatibility with early adopters. |
@@ -2312,9 +2306,9 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6, | |||
2312 | if (ipv6) { | 2306 | if (ipv6) { |
2313 | udp_conf.family = AF_INET6; | 2307 | udp_conf.family = AF_INET6; |
2314 | udp_conf.use_udp6_tx_checksums = | 2308 | udp_conf.use_udp6_tx_checksums = |
2315 | !!(flags & VXLAN_F_UDP_ZERO_CSUM6_TX); | 2309 | !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX); |
2316 | udp_conf.use_udp6_rx_checksums = | 2310 | udp_conf.use_udp6_rx_checksums = |
2317 | !!(flags & VXLAN_F_UDP_ZERO_CSUM6_RX); | 2311 | !(flags & VXLAN_F_UDP_ZERO_CSUM6_RX); |
2318 | } else { | 2312 | } else { |
2319 | udp_conf.family = AF_INET; | 2313 | udp_conf.family = AF_INET; |
2320 | udp_conf.local_ip.s_addr = INADDR_ANY; | 2314 | udp_conf.local_ip.s_addr = INADDR_ANY; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 697c4ae90af0..1e8ea5e4d4ca 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -664,6 +664,19 @@ static void ar9003_hw_override_ini(struct ath_hw *ah) | |||
664 | ah->enabled_cals |= TX_CL_CAL; | 664 | ah->enabled_cals |= TX_CL_CAL; |
665 | else | 665 | else |
666 | ah->enabled_cals &= ~TX_CL_CAL; | 666 | ah->enabled_cals &= ~TX_CL_CAL; |
667 | |||
668 | if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) { | ||
669 | if (ah->is_clk_25mhz) { | ||
670 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); | ||
671 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); | ||
672 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); | ||
673 | } else { | ||
674 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); | ||
675 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); | ||
676 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); | ||
677 | } | ||
678 | udelay(100); | ||
679 | } | ||
667 | } | 680 | } |
668 | 681 | ||
669 | static void ar9003_hw_prog_ini(struct ath_hw *ah, | 682 | static void ar9003_hw_prog_ini(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8be4b1453394..2ad605760e21 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -861,19 +861,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
861 | udelay(RTC_PLL_SETTLE_DELAY); | 861 | udelay(RTC_PLL_SETTLE_DELAY); |
862 | 862 | ||
863 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | 863 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); |
864 | |||
865 | if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) { | ||
866 | if (ah->is_clk_25mhz) { | ||
867 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); | ||
868 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); | ||
869 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); | ||
870 | } else { | ||
871 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); | ||
872 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); | ||
873 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); | ||
874 | } | ||
875 | udelay(100); | ||
876 | } | ||
877 | } | 864 | } |
878 | 865 | ||
879 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | 866 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 30c66dfcd7a0..4f18a6be0c7d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -974,9 +974,8 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, | |||
974 | struct ath_vif *avp; | 974 | struct ath_vif *avp; |
975 | 975 | ||
976 | /* | 976 | /* |
977 | * Pick the MAC address of the first interface as the new hardware | 977 | * The hardware will use primary station addr together with the |
978 | * MAC address. The hardware will use it together with the BSSID mask | 978 | * BSSID mask when matching addresses. |
979 | * when matching addresses. | ||
980 | */ | 979 | */ |
981 | memset(iter_data, 0, sizeof(*iter_data)); | 980 | memset(iter_data, 0, sizeof(*iter_data)); |
982 | memset(&iter_data->mask, 0xff, ETH_ALEN); | 981 | memset(&iter_data->mask, 0xff, ETH_ALEN); |
@@ -1205,6 +1204,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1205 | list_add_tail(&avp->list, &avp->chanctx->vifs); | 1204 | list_add_tail(&avp->list, &avp->chanctx->vifs); |
1206 | } | 1205 | } |
1207 | 1206 | ||
1207 | ath9k_calculate_summary_state(sc, avp->chanctx); | ||
1208 | |||
1208 | ath9k_assign_hw_queues(hw, vif); | 1209 | ath9k_assign_hw_queues(hw, vif); |
1209 | 1210 | ||
1210 | an->sc = sc; | 1211 | an->sc = sc; |
@@ -1274,6 +1275,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1274 | 1275 | ||
1275 | ath_tx_node_cleanup(sc, &avp->mcast_node); | 1276 | ath_tx_node_cleanup(sc, &avp->mcast_node); |
1276 | 1277 | ||
1278 | ath9k_calculate_summary_state(sc, avp->chanctx); | ||
1279 | |||
1277 | mutex_unlock(&sc->mutex); | 1280 | mutex_unlock(&sc->mutex); |
1278 | } | 1281 | } |
1279 | 1282 | ||
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 1dfc682a8055..ee27b06074e1 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -300,9 +300,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) | |||
300 | 300 | ||
301 | void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) | 301 | void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) |
302 | { | 302 | { |
303 | assert_mac_suspended(dev); | 303 | b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg)); |
304 | dev->phy.ops->phy_write(dev, destreg, | ||
305 | dev->phy.ops->phy_read(dev, srcreg)); | ||
306 | } | 304 | } |
307 | 305 | ||
308 | void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) | 306 | void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.c b/drivers/net/wireless/brcm80211/brcmfmac/of.c index f05f5270fec1..927bffd5be64 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c | |||
@@ -40,8 +40,8 @@ void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) | |||
40 | return; | 40 | return; |
41 | 41 | ||
42 | irq = irq_of_parse_and_map(np, 0); | 42 | irq = irq_of_parse_and_map(np, 0); |
43 | if (irq < 0) { | 43 | if (!irq) { |
44 | brcmf_err("interrupt could not be mapped: err=%d\n", irq); | 44 | brcmf_err("interrupt could not be mapped\n"); |
45 | devm_kfree(dev, sdiodev->pdata); | 45 | devm_kfree(dev, sdiodev->pdata); |
46 | return; | 46 | return; |
47 | } | 47 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c index 8c0632ec9f7a..16fef3382019 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c | |||
@@ -19,10 +19,10 @@ | |||
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/unaligned/access_ok.h> | ||
23 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
24 | #include <linux/bcma/bcma.h> | 23 | #include <linux/bcma/bcma.h> |
25 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <asm/unaligned.h> | ||
26 | 26 | ||
27 | #include <soc.h> | 27 | #include <soc.h> |
28 | #include <chipcommon.h> | 28 | #include <chipcommon.h> |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index dc135915470d..875d1142c8b0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -669,10 +669,12 @@ static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, | |||
669 | goto finalize; | 669 | goto finalize; |
670 | } | 670 | } |
671 | 671 | ||
672 | if (!brcmf_usb_ioctl_resp_wait(devinfo)) | 672 | if (!brcmf_usb_ioctl_resp_wait(devinfo)) { |
673 | usb_kill_urb(devinfo->ctl_urb); | ||
673 | ret = -ETIMEDOUT; | 674 | ret = -ETIMEDOUT; |
674 | else | 675 | } else { |
675 | memcpy(buffer, tmpbuf, buflen); | 676 | memcpy(buffer, tmpbuf, buflen); |
677 | } | ||
676 | 678 | ||
677 | finalize: | 679 | finalize: |
678 | kfree(tmpbuf); | 680 | kfree(tmpbuf); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28fa25b509db..39b45c038a93 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -299,6 +299,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, | |||
299 | primary_offset = ch->center_freq1 - ch->chan->center_freq; | 299 | primary_offset = ch->center_freq1 - ch->chan->center_freq; |
300 | switch (ch->width) { | 300 | switch (ch->width) { |
301 | case NL80211_CHAN_WIDTH_20: | 301 | case NL80211_CHAN_WIDTH_20: |
302 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
302 | ch_inf.bw = BRCMU_CHAN_BW_20; | 303 | ch_inf.bw = BRCMU_CHAN_BW_20; |
303 | WARN_ON(primary_offset != 0); | 304 | WARN_ON(primary_offset != 0); |
304 | break; | 305 | break; |
@@ -323,6 +324,10 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, | |||
323 | ch_inf.sb = BRCMU_CHAN_SB_LU; | 324 | ch_inf.sb = BRCMU_CHAN_SB_LU; |
324 | } | 325 | } |
325 | break; | 326 | break; |
327 | case NL80211_CHAN_WIDTH_80P80: | ||
328 | case NL80211_CHAN_WIDTH_160: | ||
329 | case NL80211_CHAN_WIDTH_5: | ||
330 | case NL80211_CHAN_WIDTH_10: | ||
326 | default: | 331 | default: |
327 | WARN_ON_ONCE(1); | 332 | WARN_ON_ONCE(1); |
328 | } | 333 | } |
@@ -333,6 +338,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, | |||
333 | case IEEE80211_BAND_5GHZ: | 338 | case IEEE80211_BAND_5GHZ: |
334 | ch_inf.band = BRCMU_CHAN_BAND_5G; | 339 | ch_inf.band = BRCMU_CHAN_BAND_5G; |
335 | break; | 340 | break; |
341 | case IEEE80211_BAND_60GHZ: | ||
336 | default: | 342 | default: |
337 | WARN_ON_ONCE(1); | 343 | WARN_ON_ONCE(1); |
338 | } | 344 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 4f6e66892acc..b894a84e8393 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -155,6 +155,7 @@ enum iwl_ucode_tlv_api { | |||
155 | * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests | 155 | * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests |
156 | * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA), | 156 | * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA), |
157 | * which also implies support for the scheduler configuration command | 157 | * which also implies support for the scheduler configuration command |
158 | * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command | ||
158 | */ | 159 | */ |
159 | enum iwl_ucode_tlv_capa { | 160 | enum iwl_ucode_tlv_capa { |
160 | IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), | 161 | IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), |
@@ -163,6 +164,7 @@ enum iwl_ucode_tlv_capa { | |||
163 | IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10), | 164 | IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10), |
164 | IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11), | 165 | IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11), |
165 | IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12), | 166 | IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12), |
167 | IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), | ||
166 | }; | 168 | }; |
167 | 169 | ||
168 | /* The default calibrate table size if not specified by firmware file */ | 170 | /* The default calibrate table size if not specified by firmware file */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index b62405865b25..b6d2683da3a9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -2448,9 +2448,15 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, | |||
2448 | 2448 | ||
2449 | switch (vif->type) { | 2449 | switch (vif->type) { |
2450 | case NL80211_IFTYPE_STATION: | 2450 | case NL80211_IFTYPE_STATION: |
2451 | /* Use aux roc framework (HS20) */ | 2451 | if (mvm->fw->ucode_capa.capa[0] & |
2452 | ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, | 2452 | IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT) { |
2453 | vif, duration); | 2453 | /* Use aux roc framework (HS20) */ |
2454 | ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, | ||
2455 | vif, duration); | ||
2456 | goto out_unlock; | ||
2457 | } | ||
2458 | IWL_ERR(mvm, "hotspot not supported\n"); | ||
2459 | ret = -EINVAL; | ||
2454 | goto out_unlock; | 2460 | goto out_unlock; |
2455 | case NL80211_IFTYPE_P2P_DEVICE: | 2461 | case NL80211_IFTYPE_P2P_DEVICE: |
2456 | /* handle below */ | 2462 | /* handle below */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index b280d5d87127..7554f7053830 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -602,16 +602,6 @@ static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm) | |||
602 | SCAN_COMPLETE_NOTIFICATION }; | 602 | SCAN_COMPLETE_NOTIFICATION }; |
603 | int ret; | 603 | int ret; |
604 | 604 | ||
605 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | ||
606 | return 0; | ||
607 | |||
608 | if (iwl_mvm_is_radio_killed(mvm)) { | ||
609 | ieee80211_scan_completed(mvm->hw, true); | ||
610 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); | ||
611 | mvm->scan_status = IWL_MVM_SCAN_NONE; | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, | 605 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, |
616 | scan_abort_notif, | 606 | scan_abort_notif, |
617 | ARRAY_SIZE(scan_abort_notif), | 607 | ARRAY_SIZE(scan_abort_notif), |
@@ -1400,6 +1390,16 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
1400 | 1390 | ||
1401 | int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) | 1391 | int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) |
1402 | { | 1392 | { |
1393 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | ||
1394 | return 0; | ||
1395 | |||
1396 | if (iwl_mvm_is_radio_killed(mvm)) { | ||
1397 | ieee80211_scan_completed(mvm->hw, true); | ||
1398 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); | ||
1399 | mvm->scan_status = IWL_MVM_SCAN_NONE; | ||
1400 | return 0; | ||
1401 | } | ||
1402 | |||
1403 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) | 1403 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) |
1404 | return iwl_mvm_scan_offload_stop(mvm, true); | 1404 | return iwl_mvm_scan_offload_stop(mvm, true); |
1405 | return iwl_mvm_cancel_regular_scan(mvm); | 1405 | return iwl_mvm_cancel_regular_scan(mvm); |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 160c3ebc48d0..dd2f3f8baa9d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1894,8 +1894,7 @@ static u32 iwl_trans_pcie_dump_prph(struct iwl_trans *trans, | |||
1894 | int reg; | 1894 | int reg; |
1895 | __le32 *val; | 1895 | __le32 *val; |
1896 | 1896 | ||
1897 | prph_len += sizeof(*data) + sizeof(*prph) + | 1897 | prph_len += sizeof(**data) + sizeof(*prph) + num_bytes_in_chunk; |
1898 | num_bytes_in_chunk; | ||
1899 | 1898 | ||
1900 | (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH); | 1899 | (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH); |
1901 | (*data)->len = cpu_to_le32(sizeof(*prph) + | 1900 | (*data)->len = cpu_to_le32(sizeof(*prph) + |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 8e68f87ab13c..66ff36447b94 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_buff *skb) | |||
158 | skb_trim(skb, frame_length); | 158 | skb_trim(skb, frame_length); |
159 | } | 159 | } |
160 | 160 | ||
161 | void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) | 161 | /* |
162 | * H/W needs L2 padding between the header and the paylod if header size | ||
163 | * is not 4 bytes aligned. | ||
164 | */ | ||
165 | void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len) | ||
162 | { | 166 | { |
163 | unsigned int payload_length = skb->len - header_length; | 167 | unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0; |
164 | unsigned int header_align = ALIGN_SIZE(skb, 0); | ||
165 | unsigned int payload_align = ALIGN_SIZE(skb, header_length); | ||
166 | unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0; | ||
167 | 168 | ||
168 | /* | 169 | if (!l2pad) |
169 | * Adjust the header alignment if the payload needs to be moved more | ||
170 | * than the header. | ||
171 | */ | ||
172 | if (payload_align > header_align) | ||
173 | header_align += 4; | ||
174 | |||
175 | /* There is nothing to do if no alignment is needed */ | ||
176 | if (!header_align) | ||
177 | return; | 170 | return; |
178 | 171 | ||
179 | /* Reserve the amount of space needed in front of the frame */ | 172 | skb_push(skb, l2pad); |
180 | skb_push(skb, header_align); | 173 | memmove(skb->data, skb->data + l2pad, hdr_len); |
181 | |||
182 | /* | ||
183 | * Move the header. | ||
184 | */ | ||
185 | memmove(skb->data, skb->data + header_align, header_length); | ||
186 | |||
187 | /* Move the payload, if present and if required */ | ||
188 | if (payload_length && payload_align) | ||
189 | memmove(skb->data + header_length + l2pad, | ||
190 | skb->data + header_length + l2pad + payload_align, | ||
191 | payload_length); | ||
192 | |||
193 | /* Trim the skb to the correct size */ | ||
194 | skb_trim(skb, header_length + l2pad + payload_length); | ||
195 | } | 174 | } |
196 | 175 | ||
197 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) | 176 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len) |
198 | { | 177 | { |
199 | /* | 178 | unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0; |
200 | * L2 padding is only present if the skb contains more than just the | ||
201 | * IEEE 802.11 header. | ||
202 | */ | ||
203 | unsigned int l2pad = (skb->len > header_length) ? | ||
204 | L2PAD_SIZE(header_length) : 0; | ||
205 | 179 | ||
206 | if (!l2pad) | 180 | if (!l2pad) |
207 | return; | 181 | return; |
208 | 182 | ||
209 | memmove(skb->data + l2pad, skb->data, header_length); | 183 | memmove(skb->data + l2pad, skb->data, hdr_len); |
210 | skb_pull(skb, l2pad); | 184 | skb_pull(skb, l2pad); |
211 | } | 185 | } |
212 | 186 | ||
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 25daa8715219..846a2e6e34d8 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -842,7 +842,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
842 | break; | 842 | break; |
843 | } | 843 | } |
844 | /* handle command packet here */ | 844 | /* handle command packet here */ |
845 | if (rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { | 845 | if (rtlpriv->cfg->ops->rx_command_packet && |
846 | rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { | ||
846 | dev_kfree_skb_any(skb); | 847 | dev_kfree_skb_any(skb); |
847 | goto end; | 848 | goto end; |
848 | } | 849 | } |
@@ -1127,9 +1128,14 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
1127 | 1128 | ||
1128 | __skb_queue_tail(&ring->queue, pskb); | 1129 | __skb_queue_tail(&ring->queue, pskb); |
1129 | 1130 | ||
1130 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN, | 1131 | if (rtlpriv->use_new_trx_flow) { |
1131 | &temp_one); | 1132 | temp_one = 4; |
1132 | 1133 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pbuffer_desc, true, | |
1134 | HW_DESC_OWN, (u8 *)&temp_one); | ||
1135 | } else { | ||
1136 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN, | ||
1137 | &temp_one); | ||
1138 | } | ||
1133 | return; | 1139 | return; |
1134 | } | 1140 | } |
1135 | 1141 | ||
@@ -1370,9 +1376,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, | |||
1370 | ring->desc = NULL; | 1376 | ring->desc = NULL; |
1371 | if (rtlpriv->use_new_trx_flow) { | 1377 | if (rtlpriv->use_new_trx_flow) { |
1372 | pci_free_consistent(rtlpci->pdev, | 1378 | pci_free_consistent(rtlpci->pdev, |
1373 | sizeof(*ring->desc) * ring->entries, | 1379 | sizeof(*ring->buffer_desc) * ring->entries, |
1374 | ring->buffer_desc, ring->buffer_desc_dma); | 1380 | ring->buffer_desc, ring->buffer_desc_dma); |
1375 | ring->desc = NULL; | 1381 | ring->buffer_desc = NULL; |
1376 | } | 1382 | } |
1377 | } | 1383 | } |
1378 | 1384 | ||
@@ -1543,7 +1549,6 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) | |||
1543 | true, | 1549 | true, |
1544 | HW_DESC_TXBUFF_ADDR), | 1550 | HW_DESC_TXBUFF_ADDR), |
1545 | skb->len, PCI_DMA_TODEVICE); | 1551 | skb->len, PCI_DMA_TODEVICE); |
1546 | ring->idx = (ring->idx + 1) % ring->entries; | ||
1547 | kfree_skb(skb); | 1552 | kfree_skb(skb); |
1548 | ring->idx = (ring->idx + 1) % ring->entries; | 1553 | ring->idx = (ring->idx + 1) % ring->entries; |
1549 | } | 1554 | } |
@@ -2244,6 +2249,16 @@ int rtl_pci_probe(struct pci_dev *pdev, | |||
2244 | /*like read eeprom and so on */ | 2249 | /*like read eeprom and so on */ |
2245 | rtlpriv->cfg->ops->read_eeprom_info(hw); | 2250 | rtlpriv->cfg->ops->read_eeprom_info(hw); |
2246 | 2251 | ||
2252 | if (rtlpriv->cfg->ops->init_sw_vars(hw)) { | ||
2253 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); | ||
2254 | err = -ENODEV; | ||
2255 | goto fail3; | ||
2256 | } | ||
2257 | rtlpriv->cfg->ops->init_sw_leds(hw); | ||
2258 | |||
2259 | /*aspm */ | ||
2260 | rtl_pci_init_aspm(hw); | ||
2261 | |||
2247 | /* Init mac80211 sw */ | 2262 | /* Init mac80211 sw */ |
2248 | err = rtl_init_core(hw); | 2263 | err = rtl_init_core(hw); |
2249 | if (err) { | 2264 | if (err) { |
@@ -2259,16 +2274,6 @@ int rtl_pci_probe(struct pci_dev *pdev, | |||
2259 | goto fail3; | 2274 | goto fail3; |
2260 | } | 2275 | } |
2261 | 2276 | ||
2262 | if (rtlpriv->cfg->ops->init_sw_vars(hw)) { | ||
2263 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); | ||
2264 | err = -ENODEV; | ||
2265 | goto fail3; | ||
2266 | } | ||
2267 | rtlpriv->cfg->ops->init_sw_leds(hw); | ||
2268 | |||
2269 | /*aspm */ | ||
2270 | rtl_pci_init_aspm(hw); | ||
2271 | |||
2272 | err = ieee80211_register_hw(hw); | 2277 | err = ieee80211_register_hw(hw); |
2273 | if (err) { | 2278 | if (err) { |
2274 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 2279 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 00e067044c08..5761d5b49e39 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
@@ -1201,6 +1201,9 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, | |||
1201 | 1201 | ||
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | if (type != NL80211_IFTYPE_AP && | ||
1205 | rtlpriv->mac80211.link_state < MAC80211_LINKED) | ||
1206 | bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK; | ||
1204 | rtl_write_byte(rtlpriv, (MSR), bt_msr); | 1207 | rtl_write_byte(rtlpriv, (MSR), bt_msr); |
1205 | 1208 | ||
1206 | temp = rtl_read_dword(rtlpriv, TCR); | 1209 | temp = rtl_read_dword(rtlpriv, TCR); |
@@ -1262,6 +1265,7 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw) | |||
1262 | rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); | 1265 | rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); |
1263 | /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ | 1266 | /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ |
1264 | rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); | 1267 | rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); |
1268 | rtlpci->irq_enabled = true; | ||
1265 | } | 1269 | } |
1266 | 1270 | ||
1267 | void rtl92se_disable_interrupt(struct ieee80211_hw *hw) | 1271 | void rtl92se_disable_interrupt(struct ieee80211_hw *hw) |
@@ -1276,8 +1280,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw) | |||
1276 | rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1280 | rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
1277 | rtl_write_dword(rtlpriv, INTA_MASK, 0); | 1281 | rtl_write_dword(rtlpriv, INTA_MASK, 0); |
1278 | rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); | 1282 | rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); |
1279 | 1283 | rtlpci->irq_enabled = false; | |
1280 | synchronize_irq(rtlpci->pdev->irq); | ||
1281 | } | 1284 | } |
1282 | 1285 | ||
1283 | static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) | 1286 | static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 77c5b5f35244..4b4612fe2fdb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
@@ -399,6 +399,8 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | |||
399 | case 2: | 399 | case 2: |
400 | currentcmd = &postcommoncmd[*step]; | 400 | currentcmd = &postcommoncmd[*step]; |
401 | break; | 401 | break; |
402 | default: | ||
403 | return true; | ||
402 | } | 404 | } |
403 | 405 | ||
404 | if (currentcmd->cmdid == CMDID_END) { | 406 | if (currentcmd->cmdid == CMDID_END) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index aadba29c167a..fb003868bdef 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c | |||
@@ -236,6 +236,19 @@ static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw) | |||
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | static bool rtl92se_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, | ||
240 | u16 index) | ||
241 | { | ||
242 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
243 | struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; | ||
244 | u8 *entry = (u8 *)(&ring->desc[ring->idx]); | ||
245 | u8 own = (u8)rtl92se_get_desc(entry, true, HW_DESC_OWN); | ||
246 | |||
247 | if (own) | ||
248 | return false; | ||
249 | return true; | ||
250 | } | ||
251 | |||
239 | static struct rtl_hal_ops rtl8192se_hal_ops = { | 252 | static struct rtl_hal_ops rtl8192se_hal_ops = { |
240 | .init_sw_vars = rtl92s_init_sw_vars, | 253 | .init_sw_vars = rtl92s_init_sw_vars, |
241 | .deinit_sw_vars = rtl92s_deinit_sw_vars, | 254 | .deinit_sw_vars = rtl92s_deinit_sw_vars, |
@@ -269,6 +282,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = { | |||
269 | .led_control = rtl92se_led_control, | 282 | .led_control = rtl92se_led_control, |
270 | .set_desc = rtl92se_set_desc, | 283 | .set_desc = rtl92se_set_desc, |
271 | .get_desc = rtl92se_get_desc, | 284 | .get_desc = rtl92se_get_desc, |
285 | .is_tx_desc_closed = rtl92se_is_tx_desc_closed, | ||
272 | .tx_polling = rtl92se_tx_polling, | 286 | .tx_polling = rtl92se_tx_polling, |
273 | .enable_hw_sec = rtl92se_enable_hw_security_config, | 287 | .enable_hw_sec = rtl92se_enable_hw_security_config, |
274 | .set_key = rtl92se_set_key, | 288 | .set_key = rtl92se_set_key, |
@@ -306,6 +320,8 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = { | |||
306 | .maps[MAC_RCR_ACRC32] = RCR_ACRC32, | 320 | .maps[MAC_RCR_ACRC32] = RCR_ACRC32, |
307 | .maps[MAC_RCR_ACF] = RCR_ACF, | 321 | .maps[MAC_RCR_ACF] = RCR_ACF, |
308 | .maps[MAC_RCR_AAP] = RCR_AAP, | 322 | .maps[MAC_RCR_AAP] = RCR_AAP, |
323 | .maps[MAC_HIMR] = INTA_MASK, | ||
324 | .maps[MAC_HIMRE] = INTA_MASK + 4, | ||
309 | 325 | ||
310 | .maps[EFUSE_TEST] = REG_EFUSE_TEST, | 326 | .maps[EFUSE_TEST] = REG_EFUSE_TEST, |
311 | .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, | 327 | .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c index 310d3163dc5b..8ec8200002c7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c | |||
@@ -3672,8 +3672,9 @@ static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw, | |||
3672 | mac->opmode == NL80211_IFTYPE_ADHOC) | 3672 | mac->opmode == NL80211_IFTYPE_ADHOC) |
3673 | macid = sta->aid + 1; | 3673 | macid = sta->aid + 1; |
3674 | if (wirelessmode == WIRELESS_MODE_N_5G || | 3674 | if (wirelessmode == WIRELESS_MODE_N_5G || |
3675 | wirelessmode == WIRELESS_MODE_AC_5G) | 3675 | wirelessmode == WIRELESS_MODE_AC_5G || |
3676 | ratr_bitmap = sta->supp_rates[NL80211_BAND_5GHZ]; | 3676 | wirelessmode == WIRELESS_MODE_A) |
3677 | ratr_bitmap = sta->supp_rates[NL80211_BAND_5GHZ] << 4; | ||
3677 | else | 3678 | else |
3678 | ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ]; | 3679 | ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ]; |
3679 | 3680 | ||
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 4e56a27f9689..fab0d4b42f58 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -39,7 +39,7 @@ struct backend_info { | |||
39 | static int connect_rings(struct backend_info *be, struct xenvif_queue *queue); | 39 | static int connect_rings(struct backend_info *be, struct xenvif_queue *queue); |
40 | static void connect(struct backend_info *be); | 40 | static void connect(struct backend_info *be); |
41 | static int read_xenbus_vif_flags(struct backend_info *be); | 41 | static int read_xenbus_vif_flags(struct backend_info *be); |
42 | static void backend_create_xenvif(struct backend_info *be); | 42 | static int backend_create_xenvif(struct backend_info *be); |
43 | static void unregister_hotplug_status_watch(struct backend_info *be); | 43 | static void unregister_hotplug_status_watch(struct backend_info *be); |
44 | static void set_backend_state(struct backend_info *be, | 44 | static void set_backend_state(struct backend_info *be, |
45 | enum xenbus_state state); | 45 | enum xenbus_state state); |
@@ -352,7 +352,9 @@ static int netback_probe(struct xenbus_device *dev, | |||
352 | be->state = XenbusStateInitWait; | 352 | be->state = XenbusStateInitWait; |
353 | 353 | ||
354 | /* This kicks hotplug scripts, so do it immediately. */ | 354 | /* This kicks hotplug scripts, so do it immediately. */ |
355 | backend_create_xenvif(be); | 355 | err = backend_create_xenvif(be); |
356 | if (err) | ||
357 | goto fail; | ||
356 | 358 | ||
357 | return 0; | 359 | return 0; |
358 | 360 | ||
@@ -397,19 +399,19 @@ static int netback_uevent(struct xenbus_device *xdev, | |||
397 | } | 399 | } |
398 | 400 | ||
399 | 401 | ||
400 | static void backend_create_xenvif(struct backend_info *be) | 402 | static int backend_create_xenvif(struct backend_info *be) |
401 | { | 403 | { |
402 | int err; | 404 | int err; |
403 | long handle; | 405 | long handle; |
404 | struct xenbus_device *dev = be->dev; | 406 | struct xenbus_device *dev = be->dev; |
405 | 407 | ||
406 | if (be->vif != NULL) | 408 | if (be->vif != NULL) |
407 | return; | 409 | return 0; |
408 | 410 | ||
409 | err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle); | 411 | err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle); |
410 | if (err != 1) { | 412 | if (err != 1) { |
411 | xenbus_dev_fatal(dev, err, "reading handle"); | 413 | xenbus_dev_fatal(dev, err, "reading handle"); |
412 | return; | 414 | return (err < 0) ? err : -EINVAL; |
413 | } | 415 | } |
414 | 416 | ||
415 | be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle); | 417 | be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle); |
@@ -417,10 +419,11 @@ static void backend_create_xenvif(struct backend_info *be) | |||
417 | err = PTR_ERR(be->vif); | 419 | err = PTR_ERR(be->vif); |
418 | be->vif = NULL; | 420 | be->vif = NULL; |
419 | xenbus_dev_fatal(dev, err, "creating interface"); | 421 | xenbus_dev_fatal(dev, err, "creating interface"); |
420 | return; | 422 | return err; |
421 | } | 423 | } |
422 | 424 | ||
423 | kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); | 425 | kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); |
426 | return 0; | ||
424 | } | 427 | } |
425 | 428 | ||
426 | static void backend_disconnect(struct backend_info *be) | 429 | static void backend_disconnect(struct backend_info *be) |
diff --git a/drivers/of/address.c b/drivers/of/address.c index afdb78299f61..06af494184d6 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -450,6 +450,21 @@ static struct of_bus *of_match_bus(struct device_node *np) | |||
450 | return NULL; | 450 | return NULL; |
451 | } | 451 | } |
452 | 452 | ||
453 | static int of_empty_ranges_quirk(void) | ||
454 | { | ||
455 | if (IS_ENABLED(CONFIG_PPC)) { | ||
456 | /* To save cycles, we cache the result */ | ||
457 | static int quirk_state = -1; | ||
458 | |||
459 | if (quirk_state < 0) | ||
460 | quirk_state = | ||
461 | of_machine_is_compatible("Power Macintosh") || | ||
462 | of_machine_is_compatible("MacRISC"); | ||
463 | return quirk_state; | ||
464 | } | ||
465 | return false; | ||
466 | } | ||
467 | |||
453 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, | 468 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, |
454 | struct of_bus *pbus, __be32 *addr, | 469 | struct of_bus *pbus, __be32 *addr, |
455 | int na, int ns, int pna, const char *rprop) | 470 | int na, int ns, int pna, const char *rprop) |
@@ -475,12 +490,10 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, | |||
475 | * This code is only enabled on powerpc. --gcl | 490 | * This code is only enabled on powerpc. --gcl |
476 | */ | 491 | */ |
477 | ranges = of_get_property(parent, rprop, &rlen); | 492 | ranges = of_get_property(parent, rprop, &rlen); |
478 | #if !defined(CONFIG_PPC) | 493 | if (ranges == NULL && !of_empty_ranges_quirk()) { |
479 | if (ranges == NULL) { | ||
480 | pr_err("OF: no ranges; cannot translate\n"); | 494 | pr_err("OF: no ranges; cannot translate\n"); |
481 | return 1; | 495 | return 1; |
482 | } | 496 | } |
483 | #endif /* !defined(CONFIG_PPC) */ | ||
484 | if (ranges == NULL || rlen == 0) { | 497 | if (ranges == NULL || rlen == 0) { |
485 | offset = of_read_number(addr, na); | 498 | offset = of_read_number(addr, na); |
486 | memset(addr, 0, pna * 4); | 499 | memset(addr, 0, pna * 4); |
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index f297891d8529..d4994177dec2 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c | |||
@@ -247,7 +247,7 @@ void of_node_release(struct kobject *kobj) | |||
247 | * @allocflags: Allocation flags (typically pass GFP_KERNEL) | 247 | * @allocflags: Allocation flags (typically pass GFP_KERNEL) |
248 | * | 248 | * |
249 | * Copy a property by dynamically allocating the memory of both the | 249 | * Copy a property by dynamically allocating the memory of both the |
250 | * property stucture and the property name & contents. The property's | 250 | * property structure and the property name & contents. The property's |
251 | * flags have the OF_DYNAMIC bit set so that we can differentiate between | 251 | * flags have the OF_DYNAMIC bit set so that we can differentiate between |
252 | * dynamically allocated properties and not. | 252 | * dynamically allocated properties and not. |
253 | * Returns the newly allocated property or NULL on out of memory error. | 253 | * Returns the newly allocated property or NULL on out of memory error. |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index d1ffca8b34ea..30e97bcc4f88 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -773,7 +773,7 @@ int __init early_init_dt_scan_chosen_serial(void) | |||
773 | if (offset < 0) | 773 | if (offset < 0) |
774 | return -ENODEV; | 774 | return -ENODEV; |
775 | 775 | ||
776 | while (match->compatible) { | 776 | while (match->compatible[0]) { |
777 | unsigned long addr; | 777 | unsigned long addr; |
778 | if (fdt_node_check_compatible(fdt, offset, match->compatible)) { | 778 | if (fdt_node_check_compatible(fdt, offset, match->compatible)) { |
779 | match++; | 779 | match++; |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 11b873c54a77..e2d79afa9dc6 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -896,10 +896,14 @@ static void selftest_data_remove(void) | |||
896 | return; | 896 | return; |
897 | } | 897 | } |
898 | 898 | ||
899 | while (last_node_index >= 0) { | 899 | while (last_node_index-- > 0) { |
900 | if (nodes[last_node_index]) { | 900 | if (nodes[last_node_index]) { |
901 | np = of_find_node_by_path(nodes[last_node_index]->full_name); | 901 | np = of_find_node_by_path(nodes[last_node_index]->full_name); |
902 | if (strcmp(np->full_name, "/aliases") != 0) { | 902 | if (np == nodes[last_node_index]) { |
903 | if (of_aliases == np) { | ||
904 | of_node_put(of_aliases); | ||
905 | of_aliases = NULL; | ||
906 | } | ||
903 | detach_node_and_children(np); | 907 | detach_node_and_children(np); |
904 | } else { | 908 | } else { |
905 | for_each_property_of_node(np, prop) { | 909 | for_each_property_of_node(np, prop) { |
@@ -908,7 +912,6 @@ static void selftest_data_remove(void) | |||
908 | } | 912 | } |
909 | } | 913 | } |
910 | } | 914 | } |
911 | last_node_index--; | ||
912 | } | 915 | } |
913 | } | 916 | } |
914 | 917 | ||
@@ -921,6 +924,8 @@ static int __init of_selftest(void) | |||
921 | res = selftest_data_add(); | 924 | res = selftest_data_add(); |
922 | if (res) | 925 | if (res) |
923 | return res; | 926 | return res; |
927 | if (!of_aliases) | ||
928 | of_aliases = of_find_node_by_path("/aliases"); | ||
924 | 929 | ||
925 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | 930 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); |
926 | if (!np) { | 931 | if (!np) { |
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d292d7cb3417..49dd766852ba 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -444,7 +444,7 @@ static inline int pcie_cap_version(const struct pci_dev *dev) | |||
444 | return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS; | 444 | return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS; |
445 | } | 445 | } |
446 | 446 | ||
447 | static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) | 447 | bool pcie_cap_has_lnkctl(const struct pci_dev *dev) |
448 | { | 448 | { |
449 | int type = pci_pcie_type(dev); | 449 | int type = pci_pcie_type(dev); |
450 | 450 | ||
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index 9ecabfa8c634..2988fe136c1e 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -631,10 +631,15 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev) | |||
631 | if (ret) | 631 | if (ret) |
632 | return ret; | 632 | return ret; |
633 | 633 | ||
634 | bus = pci_scan_root_bus(&pdev->dev, 0, &xgene_pcie_ops, port, &res); | 634 | bus = pci_create_root_bus(&pdev->dev, 0, |
635 | &xgene_pcie_ops, port, &res); | ||
635 | if (!bus) | 636 | if (!bus) |
636 | return -ENOMEM; | 637 | return -ENOMEM; |
637 | 638 | ||
639 | pci_scan_child_bus(bus); | ||
640 | pci_assign_unassigned_bus_resources(bus); | ||
641 | pci_bus_add_devices(bus); | ||
642 | |||
638 | platform_set_drvdata(pdev, port); | 643 | platform_set_drvdata(pdev, port); |
639 | return 0; | 644 | return 0; |
640 | } | 645 | } |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 9fab30af0e75..084587d7cd13 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -590,6 +590,20 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev) | |||
590 | return entry; | 590 | return entry; |
591 | } | 591 | } |
592 | 592 | ||
593 | static int msi_verify_entries(struct pci_dev *dev) | ||
594 | { | ||
595 | struct msi_desc *entry; | ||
596 | |||
597 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
598 | if (!dev->no_64bit_msi || !entry->msg.address_hi) | ||
599 | continue; | ||
600 | dev_err(&dev->dev, "Device has broken 64-bit MSI but arch" | ||
601 | " tried to assign one above 4G\n"); | ||
602 | return -EIO; | ||
603 | } | ||
604 | return 0; | ||
605 | } | ||
606 | |||
593 | /** | 607 | /** |
594 | * msi_capability_init - configure device's MSI capability structure | 608 | * msi_capability_init - configure device's MSI capability structure |
595 | * @dev: pointer to the pci_dev data structure of MSI device function | 609 | * @dev: pointer to the pci_dev data structure of MSI device function |
@@ -627,6 +641,13 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
627 | return ret; | 641 | return ret; |
628 | } | 642 | } |
629 | 643 | ||
644 | ret = msi_verify_entries(dev); | ||
645 | if (ret) { | ||
646 | msi_mask_irq(entry, mask, ~mask); | ||
647 | free_msi_irqs(dev); | ||
648 | return ret; | ||
649 | } | ||
650 | |||
630 | ret = populate_msi_sysfs(dev); | 651 | ret = populate_msi_sysfs(dev); |
631 | if (ret) { | 652 | if (ret) { |
632 | msi_mask_irq(entry, mask, ~mask); | 653 | msi_mask_irq(entry, mask, ~mask); |
@@ -739,6 +760,11 @@ static int msix_capability_init(struct pci_dev *dev, | |||
739 | if (ret) | 760 | if (ret) |
740 | goto out_avail; | 761 | goto out_avail; |
741 | 762 | ||
763 | /* Check if all MSI entries honor device restrictions */ | ||
764 | ret = msi_verify_entries(dev); | ||
765 | if (ret) | ||
766 | goto out_free; | ||
767 | |||
742 | /* | 768 | /* |
743 | * Some devices require MSI-X to be enabled before we can touch the | 769 | * Some devices require MSI-X to be enabled before we can touch the |
744 | * MSI-X registers. We need to mask all the vectors to prevent | 770 | * MSI-X registers. We need to mask all the vectors to prevent |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0601890db22d..4a3902d8e6fe 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -6,6 +6,8 @@ | |||
6 | 6 | ||
7 | extern const unsigned char pcie_link_speed[]; | 7 | extern const unsigned char pcie_link_speed[]; |
8 | 8 | ||
9 | bool pcie_cap_has_lnkctl(const struct pci_dev *dev); | ||
10 | |||
9 | /* Functions internal to the PCI core code */ | 11 | /* Functions internal to the PCI core code */ |
10 | 12 | ||
11 | int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 13 | int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5ed99309c758..c8ca98c2b480 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -407,15 +407,16 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
407 | { | 407 | { |
408 | struct pci_dev *dev = child->self; | 408 | struct pci_dev *dev = child->self; |
409 | u16 mem_base_lo, mem_limit_lo; | 409 | u16 mem_base_lo, mem_limit_lo; |
410 | unsigned long base, limit; | 410 | u64 base64, limit64; |
411 | dma_addr_t base, limit; | ||
411 | struct pci_bus_region region; | 412 | struct pci_bus_region region; |
412 | struct resource *res; | 413 | struct resource *res; |
413 | 414 | ||
414 | res = child->resource[2]; | 415 | res = child->resource[2]; |
415 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | 416 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); |
416 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); | 417 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); |
417 | base = ((unsigned long) mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | 418 | base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; |
418 | limit = ((unsigned long) mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | 419 | limit64 = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; |
419 | 420 | ||
420 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | 421 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { |
421 | u32 mem_base_hi, mem_limit_hi; | 422 | u32 mem_base_hi, mem_limit_hi; |
@@ -429,17 +430,20 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
429 | * this, just assume they are not being used. | 430 | * this, just assume they are not being used. |
430 | */ | 431 | */ |
431 | if (mem_base_hi <= mem_limit_hi) { | 432 | if (mem_base_hi <= mem_limit_hi) { |
432 | #if BITS_PER_LONG == 64 | 433 | base64 |= (u64) mem_base_hi << 32; |
433 | base |= ((unsigned long) mem_base_hi) << 32; | 434 | limit64 |= (u64) mem_limit_hi << 32; |
434 | limit |= ((unsigned long) mem_limit_hi) << 32; | ||
435 | #else | ||
436 | if (mem_base_hi || mem_limit_hi) { | ||
437 | dev_err(&dev->dev, "can't handle 64-bit address space for bridge\n"); | ||
438 | return; | ||
439 | } | ||
440 | #endif | ||
441 | } | 435 | } |
442 | } | 436 | } |
437 | |||
438 | base = (dma_addr_t) base64; | ||
439 | limit = (dma_addr_t) limit64; | ||
440 | |||
441 | if (base != base64) { | ||
442 | dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n", | ||
443 | (unsigned long long) base64); | ||
444 | return; | ||
445 | } | ||
446 | |||
443 | if (base <= limit) { | 447 | if (base <= limit) { |
444 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | | 448 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | |
445 | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 449 | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
@@ -1323,7 +1327,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
1323 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); | 1327 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); |
1324 | 1328 | ||
1325 | /* Initialize Link Control Register */ | 1329 | /* Initialize Link Control Register */ |
1326 | if (dev->subordinate) | 1330 | if (pcie_cap_has_lnkctl(dev)) |
1327 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, | 1331 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, |
1328 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); | 1332 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); |
1329 | 1333 | ||
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 79e5c94107a9..72533c58c1f3 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -412,6 +412,7 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
412 | struct fc_frame_header *fh; | 412 | struct fc_frame_header *fh; |
413 | struct fcoe_rcv_info *fr; | 413 | struct fcoe_rcv_info *fr; |
414 | struct fcoe_percpu_s *bg; | 414 | struct fcoe_percpu_s *bg; |
415 | struct sk_buff *tmp_skb; | ||
415 | unsigned short oxid; | 416 | unsigned short oxid; |
416 | 417 | ||
417 | interface = container_of(ptype, struct bnx2fc_interface, | 418 | interface = container_of(ptype, struct bnx2fc_interface, |
@@ -424,6 +425,12 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
424 | goto err; | 425 | goto err; |
425 | } | 426 | } |
426 | 427 | ||
428 | tmp_skb = skb_share_check(skb, GFP_ATOMIC); | ||
429 | if (!tmp_skb) | ||
430 | goto err; | ||
431 | |||
432 | skb = tmp_skb; | ||
433 | |||
427 | if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { | 434 | if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { |
428 | printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n"); | 435 | printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n"); |
429 | goto err; | 436 | goto err; |
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 81bb3bd7909d..15081257cfc8 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | |||
@@ -828,6 +828,8 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb) | |||
828 | if (status == CPL_ERR_RTX_NEG_ADVICE) | 828 | if (status == CPL_ERR_RTX_NEG_ADVICE) |
829 | goto rel_skb; | 829 | goto rel_skb; |
830 | 830 | ||
831 | module_put(THIS_MODULE); | ||
832 | |||
831 | if (status && status != CPL_ERR_TCAM_FULL && | 833 | if (status && status != CPL_ERR_TCAM_FULL && |
832 | status != CPL_ERR_CONN_EXIST && | 834 | status != CPL_ERR_CONN_EXIST && |
833 | status != CPL_ERR_ARP_MISS) | 835 | status != CPL_ERR_ARP_MISS) |
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 13d869a92248..7da59c38a69e 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c | |||
@@ -816,7 +816,7 @@ static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk) | |||
816 | read_lock_bh(&csk->callback_lock); | 816 | read_lock_bh(&csk->callback_lock); |
817 | if (csk->user_data) | 817 | if (csk->user_data) |
818 | iscsi_conn_failure(csk->user_data, | 818 | iscsi_conn_failure(csk->user_data, |
819 | ISCSI_ERR_CONN_FAILED); | 819 | ISCSI_ERR_TCP_CONN_CLOSE); |
820 | read_unlock_bh(&csk->callback_lock); | 820 | read_unlock_bh(&csk->callback_lock); |
821 | } | 821 | } |
822 | } | 822 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 49014a143c6a..c1d04d4d3c6c 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -202,6 +202,7 @@ static struct { | |||
202 | {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, | 202 | {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, |
203 | {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, | 203 | {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, |
204 | {"INSITE", "I325VM", NULL, BLIST_KEY}, | 204 | {"INSITE", "I325VM", NULL, BLIST_KEY}, |
205 | {"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC}, | ||
205 | {"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36}, | 206 | {"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36}, |
206 | {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN}, | 207 | {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN}, |
207 | {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, | 208 | {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, |
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 8adf067ff019..1c3467b82566 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c | |||
@@ -102,7 +102,6 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) | |||
102 | clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq), | 102 | clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq), |
103 | GFP_KERNEL); | 103 | GFP_KERNEL); |
104 | if (!clkfreq) { | 104 | if (!clkfreq) { |
105 | dev_err(dev, "%s: no memory\n", "freq-table-hz"); | ||
106 | ret = -ENOMEM; | 105 | ret = -ENOMEM; |
107 | goto out; | 106 | goto out; |
108 | } | 107 | } |
@@ -112,19 +111,19 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) | |||
112 | if (ret && (ret != -EINVAL)) { | 111 | if (ret && (ret != -EINVAL)) { |
113 | dev_err(dev, "%s: error reading array %d\n", | 112 | dev_err(dev, "%s: error reading array %d\n", |
114 | "freq-table-hz", ret); | 113 | "freq-table-hz", ret); |
115 | goto free_clkfreq; | 114 | return ret; |
116 | } | 115 | } |
117 | 116 | ||
118 | for (i = 0; i < sz; i += 2) { | 117 | for (i = 0; i < sz; i += 2) { |
119 | ret = of_property_read_string_index(np, | 118 | ret = of_property_read_string_index(np, |
120 | "clock-names", i/2, (const char **)&name); | 119 | "clock-names", i/2, (const char **)&name); |
121 | if (ret) | 120 | if (ret) |
122 | goto free_clkfreq; | 121 | goto out; |
123 | 122 | ||
124 | clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); | 123 | clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); |
125 | if (!clki) { | 124 | if (!clki) { |
126 | ret = -ENOMEM; | 125 | ret = -ENOMEM; |
127 | goto free_clkfreq; | 126 | goto out; |
128 | } | 127 | } |
129 | 128 | ||
130 | clki->min_freq = clkfreq[i]; | 129 | clki->min_freq = clkfreq[i]; |
@@ -134,8 +133,6 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) | |||
134 | clki->min_freq, clki->max_freq, clki->name); | 133 | clki->min_freq, clki->max_freq, clki->name); |
135 | list_add_tail(&clki->list, &hba->clk_list_head); | 134 | list_add_tail(&clki->list, &hba->clk_list_head); |
136 | } | 135 | } |
137 | free_clkfreq: | ||
138 | kfree(clkfreq); | ||
139 | out: | 136 | out: |
140 | return ret; | 137 | return ret; |
141 | } | 138 | } |
@@ -162,10 +159,8 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, | |||
162 | } | 159 | } |
163 | 160 | ||
164 | vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); | 161 | vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); |
165 | if (!vreg) { | 162 | if (!vreg) |
166 | dev_err(dev, "No memory for %s regulator\n", name); | 163 | return -ENOMEM; |
167 | goto out; | ||
168 | } | ||
169 | 164 | ||
170 | vreg->name = kstrdup(name, GFP_KERNEL); | 165 | vreg->name = kstrdup(name, GFP_KERNEL); |
171 | 166 | ||
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 497c38a4a866..605ca60e8a10 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -744,6 +744,8 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba) | |||
744 | if (!ufshcd_is_clkgating_allowed(hba)) | 744 | if (!ufshcd_is_clkgating_allowed(hba)) |
745 | return; | 745 | return; |
746 | device_remove_file(hba->dev, &hba->clk_gating.delay_attr); | 746 | device_remove_file(hba->dev, &hba->clk_gating.delay_attr); |
747 | cancel_work_sync(&hba->clk_gating.ungate_work); | ||
748 | cancel_delayed_work_sync(&hba->clk_gating.gate_work); | ||
747 | } | 749 | } |
748 | 750 | ||
749 | /* Must be called with host lock acquired */ | 751 | /* Must be called with host lock acquired */ |
@@ -2246,6 +2248,22 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) | |||
2246 | return ret; | 2248 | return ret; |
2247 | } | 2249 | } |
2248 | 2250 | ||
2251 | /** | ||
2252 | * ufshcd_init_pwr_info - setting the POR (power on reset) | ||
2253 | * values in hba power info | ||
2254 | * @hba: per-adapter instance | ||
2255 | */ | ||
2256 | static void ufshcd_init_pwr_info(struct ufs_hba *hba) | ||
2257 | { | ||
2258 | hba->pwr_info.gear_rx = UFS_PWM_G1; | ||
2259 | hba->pwr_info.gear_tx = UFS_PWM_G1; | ||
2260 | hba->pwr_info.lane_rx = 1; | ||
2261 | hba->pwr_info.lane_tx = 1; | ||
2262 | hba->pwr_info.pwr_rx = SLOWAUTO_MODE; | ||
2263 | hba->pwr_info.pwr_tx = SLOWAUTO_MODE; | ||
2264 | hba->pwr_info.hs_rate = 0; | ||
2265 | } | ||
2266 | |||
2249 | /** | 2267 | /** |
2250 | * ufshcd_get_max_pwr_mode - reads the max power mode negotiated with device | 2268 | * ufshcd_get_max_pwr_mode - reads the max power mode negotiated with device |
2251 | * @hba: per-adapter instance | 2269 | * @hba: per-adapter instance |
@@ -2844,8 +2862,13 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev) | |||
2844 | hba = shost_priv(sdev->host); | 2862 | hba = shost_priv(sdev->host); |
2845 | scsi_deactivate_tcq(sdev, hba->nutrs); | 2863 | scsi_deactivate_tcq(sdev, hba->nutrs); |
2846 | /* Drop the reference as it won't be needed anymore */ | 2864 | /* Drop the reference as it won't be needed anymore */ |
2847 | if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) | 2865 | if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { |
2866 | unsigned long flags; | ||
2867 | |||
2868 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
2848 | hba->sdev_ufs_device = NULL; | 2869 | hba->sdev_ufs_device = NULL; |
2870 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
2871 | } | ||
2849 | } | 2872 | } |
2850 | 2873 | ||
2851 | /** | 2874 | /** |
@@ -4062,6 +4085,8 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba) | |||
4062 | static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) | 4085 | static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) |
4063 | { | 4086 | { |
4064 | int ret = 0; | 4087 | int ret = 0; |
4088 | struct scsi_device *sdev_rpmb; | ||
4089 | struct scsi_device *sdev_boot; | ||
4065 | 4090 | ||
4066 | hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0, | 4091 | hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0, |
4067 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL); | 4092 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL); |
@@ -4070,26 +4095,27 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) | |||
4070 | hba->sdev_ufs_device = NULL; | 4095 | hba->sdev_ufs_device = NULL; |
4071 | goto out; | 4096 | goto out; |
4072 | } | 4097 | } |
4098 | scsi_device_put(hba->sdev_ufs_device); | ||
4073 | 4099 | ||
4074 | hba->sdev_boot = __scsi_add_device(hba->host, 0, 0, | 4100 | sdev_boot = __scsi_add_device(hba->host, 0, 0, |
4075 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL); | 4101 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL); |
4076 | if (IS_ERR(hba->sdev_boot)) { | 4102 | if (IS_ERR(sdev_boot)) { |
4077 | ret = PTR_ERR(hba->sdev_boot); | 4103 | ret = PTR_ERR(sdev_boot); |
4078 | hba->sdev_boot = NULL; | ||
4079 | goto remove_sdev_ufs_device; | 4104 | goto remove_sdev_ufs_device; |
4080 | } | 4105 | } |
4106 | scsi_device_put(sdev_boot); | ||
4081 | 4107 | ||
4082 | hba->sdev_rpmb = __scsi_add_device(hba->host, 0, 0, | 4108 | sdev_rpmb = __scsi_add_device(hba->host, 0, 0, |
4083 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); | 4109 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); |
4084 | if (IS_ERR(hba->sdev_rpmb)) { | 4110 | if (IS_ERR(sdev_rpmb)) { |
4085 | ret = PTR_ERR(hba->sdev_rpmb); | 4111 | ret = PTR_ERR(sdev_rpmb); |
4086 | hba->sdev_rpmb = NULL; | ||
4087 | goto remove_sdev_boot; | 4112 | goto remove_sdev_boot; |
4088 | } | 4113 | } |
4114 | scsi_device_put(sdev_rpmb); | ||
4089 | goto out; | 4115 | goto out; |
4090 | 4116 | ||
4091 | remove_sdev_boot: | 4117 | remove_sdev_boot: |
4092 | scsi_remove_device(hba->sdev_boot); | 4118 | scsi_remove_device(sdev_boot); |
4093 | remove_sdev_ufs_device: | 4119 | remove_sdev_ufs_device: |
4094 | scsi_remove_device(hba->sdev_ufs_device); | 4120 | scsi_remove_device(hba->sdev_ufs_device); |
4095 | out: | 4121 | out: |
@@ -4097,30 +4123,6 @@ out: | |||
4097 | } | 4123 | } |
4098 | 4124 | ||
4099 | /** | 4125 | /** |
4100 | * ufshcd_scsi_remove_wlus - Removes the W-LUs which were added by | ||
4101 | * ufshcd_scsi_add_wlus() | ||
4102 | * @hba: per-adapter instance | ||
4103 | * | ||
4104 | */ | ||
4105 | static void ufshcd_scsi_remove_wlus(struct ufs_hba *hba) | ||
4106 | { | ||
4107 | if (hba->sdev_ufs_device) { | ||
4108 | scsi_remove_device(hba->sdev_ufs_device); | ||
4109 | hba->sdev_ufs_device = NULL; | ||
4110 | } | ||
4111 | |||
4112 | if (hba->sdev_boot) { | ||
4113 | scsi_remove_device(hba->sdev_boot); | ||
4114 | hba->sdev_boot = NULL; | ||
4115 | } | ||
4116 | |||
4117 | if (hba->sdev_rpmb) { | ||
4118 | scsi_remove_device(hba->sdev_rpmb); | ||
4119 | hba->sdev_rpmb = NULL; | ||
4120 | } | ||
4121 | } | ||
4122 | |||
4123 | /** | ||
4124 | * ufshcd_probe_hba - probe hba to detect device and initialize | 4126 | * ufshcd_probe_hba - probe hba to detect device and initialize |
4125 | * @hba: per-adapter instance | 4127 | * @hba: per-adapter instance |
4126 | * | 4128 | * |
@@ -4134,6 +4136,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) | |||
4134 | if (ret) | 4136 | if (ret) |
4135 | goto out; | 4137 | goto out; |
4136 | 4138 | ||
4139 | ufshcd_init_pwr_info(hba); | ||
4140 | |||
4137 | /* UniPro link is active now */ | 4141 | /* UniPro link is active now */ |
4138 | ufshcd_set_link_active(hba); | 4142 | ufshcd_set_link_active(hba); |
4139 | 4143 | ||
@@ -4264,12 +4268,18 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, | |||
4264 | static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba, | 4268 | static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba, |
4265 | struct ufs_vreg *vreg) | 4269 | struct ufs_vreg *vreg) |
4266 | { | 4270 | { |
4271 | if (!vreg) | ||
4272 | return 0; | ||
4273 | |||
4267 | return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA); | 4274 | return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA); |
4268 | } | 4275 | } |
4269 | 4276 | ||
4270 | static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, | 4277 | static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, |
4271 | struct ufs_vreg *vreg) | 4278 | struct ufs_vreg *vreg) |
4272 | { | 4279 | { |
4280 | if (!vreg) | ||
4281 | return 0; | ||
4282 | |||
4273 | return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA); | 4283 | return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA); |
4274 | } | 4284 | } |
4275 | 4285 | ||
@@ -4471,7 +4481,7 @@ out: | |||
4471 | if (!IS_ERR_OR_NULL(clki->clk) && clki->enabled) | 4481 | if (!IS_ERR_OR_NULL(clki->clk) && clki->enabled) |
4472 | clk_disable_unprepare(clki->clk); | 4482 | clk_disable_unprepare(clki->clk); |
4473 | } | 4483 | } |
4474 | } else if (!ret && on) { | 4484 | } else if (on) { |
4475 | spin_lock_irqsave(hba->host->host_lock, flags); | 4485 | spin_lock_irqsave(hba->host->host_lock, flags); |
4476 | hba->clk_gating.state = CLKS_ON; | 4486 | hba->clk_gating.state = CLKS_ON; |
4477 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 4487 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
@@ -4675,11 +4685,25 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, | |||
4675 | { | 4685 | { |
4676 | unsigned char cmd[6] = { START_STOP }; | 4686 | unsigned char cmd[6] = { START_STOP }; |
4677 | struct scsi_sense_hdr sshdr; | 4687 | struct scsi_sense_hdr sshdr; |
4678 | struct scsi_device *sdp = hba->sdev_ufs_device; | 4688 | struct scsi_device *sdp; |
4689 | unsigned long flags; | ||
4679 | int ret; | 4690 | int ret; |
4680 | 4691 | ||
4681 | if (!sdp || !scsi_device_online(sdp)) | 4692 | spin_lock_irqsave(hba->host->host_lock, flags); |
4682 | return -ENODEV; | 4693 | sdp = hba->sdev_ufs_device; |
4694 | if (sdp) { | ||
4695 | ret = scsi_device_get(sdp); | ||
4696 | if (!ret && !scsi_device_online(sdp)) { | ||
4697 | ret = -ENODEV; | ||
4698 | scsi_device_put(sdp); | ||
4699 | } | ||
4700 | } else { | ||
4701 | ret = -ENODEV; | ||
4702 | } | ||
4703 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
4704 | |||
4705 | if (ret) | ||
4706 | return ret; | ||
4683 | 4707 | ||
4684 | /* | 4708 | /* |
4685 | * If scsi commands fail, the scsi mid-layer schedules scsi error- | 4709 | * If scsi commands fail, the scsi mid-layer schedules scsi error- |
@@ -4718,6 +4742,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, | |||
4718 | if (!ret) | 4742 | if (!ret) |
4719 | hba->curr_dev_pwr_mode = pwr_mode; | 4743 | hba->curr_dev_pwr_mode = pwr_mode; |
4720 | out: | 4744 | out: |
4745 | scsi_device_put(sdp); | ||
4721 | hba->host->eh_noresume = 0; | 4746 | hba->host->eh_noresume = 0; |
4722 | return ret; | 4747 | return ret; |
4723 | } | 4748 | } |
@@ -5087,7 +5112,7 @@ int ufshcd_system_suspend(struct ufs_hba *hba) | |||
5087 | int ret = 0; | 5112 | int ret = 0; |
5088 | 5113 | ||
5089 | if (!hba || !hba->is_powered) | 5114 | if (!hba || !hba->is_powered) |
5090 | goto out; | 5115 | return 0; |
5091 | 5116 | ||
5092 | if (pm_runtime_suspended(hba->dev)) { | 5117 | if (pm_runtime_suspended(hba->dev)) { |
5093 | if (hba->rpm_lvl == hba->spm_lvl) | 5118 | if (hba->rpm_lvl == hba->spm_lvl) |
@@ -5231,7 +5256,6 @@ EXPORT_SYMBOL(ufshcd_shutdown); | |||
5231 | void ufshcd_remove(struct ufs_hba *hba) | 5256 | void ufshcd_remove(struct ufs_hba *hba) |
5232 | { | 5257 | { |
5233 | scsi_remove_host(hba->host); | 5258 | scsi_remove_host(hba->host); |
5234 | ufshcd_scsi_remove_wlus(hba); | ||
5235 | /* disable interrupts */ | 5259 | /* disable interrupts */ |
5236 | ufshcd_disable_intr(hba, hba->intr_mask); | 5260 | ufshcd_disable_intr(hba, hba->intr_mask); |
5237 | ufshcd_hba_stop(hba); | 5261 | ufshcd_hba_stop(hba); |
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 58ecdff5065c..4a574aa45855 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h | |||
@@ -392,8 +392,6 @@ struct ufs_hba { | |||
392 | * "UFS device" W-LU. | 392 | * "UFS device" W-LU. |
393 | */ | 393 | */ |
394 | struct scsi_device *sdev_ufs_device; | 394 | struct scsi_device *sdev_ufs_device; |
395 | struct scsi_device *sdev_rpmb; | ||
396 | struct scsi_device *sdev_boot; | ||
397 | 395 | ||
398 | enum ufs_dev_pwr_mode curr_dev_pwr_mode; | 396 | enum ufs_dev_pwr_mode curr_dev_pwr_mode; |
399 | enum uic_link_state uic_link_state; | 397 | enum uic_link_state uic_link_state; |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 72e12bad14b9..d0d5542efc06 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
@@ -376,9 +376,6 @@ static void pump_transfers(unsigned long data) | |||
376 | chip = dws->cur_chip; | 376 | chip = dws->cur_chip; |
377 | spi = message->spi; | 377 | spi = message->spi; |
378 | 378 | ||
379 | if (unlikely(!chip->clk_div)) | ||
380 | chip->clk_div = dws->max_freq / chip->speed_hz; | ||
381 | |||
382 | if (message->state == ERROR_STATE) { | 379 | if (message->state == ERROR_STATE) { |
383 | message->status = -EIO; | 380 | message->status = -EIO; |
384 | goto early_exit; | 381 | goto early_exit; |
@@ -419,7 +416,7 @@ static void pump_transfers(unsigned long data) | |||
419 | if (transfer->speed_hz) { | 416 | if (transfer->speed_hz) { |
420 | speed = chip->speed_hz; | 417 | speed = chip->speed_hz; |
421 | 418 | ||
422 | if (transfer->speed_hz != speed) { | 419 | if ((transfer->speed_hz != speed) || (!chip->clk_div)) { |
423 | speed = transfer->speed_hz; | 420 | speed = transfer->speed_hz; |
424 | 421 | ||
425 | /* clk_div doesn't support odd number */ | 422 | /* clk_div doesn't support odd number */ |
@@ -581,7 +578,6 @@ static int dw_spi_setup(struct spi_device *spi) | |||
581 | dev_err(&spi->dev, "No max speed HZ parameter\n"); | 578 | dev_err(&spi->dev, "No max speed HZ parameter\n"); |
582 | return -EINVAL; | 579 | return -EINVAL; |
583 | } | 580 | } |
584 | chip->speed_hz = spi->max_speed_hz; | ||
585 | 581 | ||
586 | chip->tmode = 0; /* Tx & Rx */ | 582 | chip->tmode = 0; /* Tx & Rx */ |
587 | /* Default SPI mode is SCPOL = 0, SCPH = 0 */ | 583 | /* Default SPI mode is SCPOL = 0, SCPH = 0 */ |
diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 39e2c0a55a28..f63de781c729 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c | |||
@@ -562,9 +562,9 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
562 | 562 | ||
563 | sspi->word_width = DIV_ROUND_UP(bits_per_word, 8); | 563 | sspi->word_width = DIV_ROUND_UP(bits_per_word, 8); |
564 | txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | 564 | txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | |
565 | sspi->word_width; | 565 | (sspi->word_width >> 1); |
566 | rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | 566 | rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | |
567 | sspi->word_width; | 567 | (sspi->word_width >> 1); |
568 | 568 | ||
569 | if (!(spi->mode & SPI_CS_HIGH)) | 569 | if (!(spi->mode & SPI_CS_HIGH)) |
570 | regval |= SIRFSOC_SPI_CS_IDLE_STAT; | 570 | regval |= SIRFSOC_SPI_CS_IDLE_STAT; |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ebcb33df2eb2..50f20f243981 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -615,13 +615,13 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
615 | sg_free_table(sgt); | 615 | sg_free_table(sgt); |
616 | return -ENOMEM; | 616 | return -ENOMEM; |
617 | } | 617 | } |
618 | sg_buf = page_address(vm_page) + | 618 | sg_set_page(&sgt->sgl[i], vm_page, |
619 | ((size_t)buf & ~PAGE_MASK); | 619 | min, offset_in_page(buf)); |
620 | } else { | 620 | } else { |
621 | sg_buf = buf; | 621 | sg_buf = buf; |
622 | sg_set_buf(&sgt->sgl[i], sg_buf, min); | ||
622 | } | 623 | } |
623 | 624 | ||
624 | sg_set_buf(&sgt->sgl[i], sg_buf, min); | ||
625 | 625 | ||
626 | buf += min; | 626 | buf += min; |
627 | len -= min; | 627 | len -= min; |
diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 9935e66935af..eddef9cd2e16 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c | |||
@@ -275,11 +275,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, | |||
275 | if (check_fwstate(pmlmepriv, _FW_LINKED) == true) | 275 | if (check_fwstate(pmlmepriv, _FW_LINKED) == true) |
276 | rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); | 276 | rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); |
277 | 277 | ||
278 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 278 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
279 | if (ph2c == NULL) | 279 | if (ph2c == NULL) |
280 | return _FAIL; | 280 | return _FAIL; |
281 | 281 | ||
282 | psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL); | 282 | psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); |
283 | if (psurveyPara == NULL) { | 283 | if (psurveyPara == NULL) { |
284 | kfree(ph2c); | 284 | kfree(ph2c); |
285 | return _FAIL; | 285 | return _FAIL; |
@@ -405,7 +405,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) | |||
405 | else | 405 | else |
406 | RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); | 406 | RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); |
407 | 407 | ||
408 | pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 408 | pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
409 | if (pcmd == NULL) { | 409 | if (pcmd == NULL) { |
410 | res = _FAIL; | 410 | res = _FAIL; |
411 | RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); | 411 | RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); |
@@ -755,13 +755,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) | |||
755 | u8 res = _SUCCESS; | 755 | u8 res = _SUCCESS; |
756 | 756 | ||
757 | 757 | ||
758 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 758 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
759 | if (ph2c == NULL) { | 759 | if (ph2c == NULL) { |
760 | res = _FAIL; | 760 | res = _FAIL; |
761 | goto exit; | 761 | goto exit; |
762 | } | 762 | } |
763 | 763 | ||
764 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); | 764 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); |
765 | if (pdrvextra_cmd_parm == NULL) { | 765 | if (pdrvextra_cmd_parm == NULL) { |
766 | kfree(ph2c); | 766 | kfree(ph2c); |
767 | res = _FAIL; | 767 | res = _FAIL; |
@@ -967,13 +967,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) | |||
967 | u8 res = _SUCCESS; | 967 | u8 res = _SUCCESS; |
968 | 968 | ||
969 | if (enqueue) { | 969 | if (enqueue) { |
970 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 970 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
971 | if (ph2c == NULL) { | 971 | if (ph2c == NULL) { |
972 | res = _FAIL; | 972 | res = _FAIL; |
973 | goto exit; | 973 | goto exit; |
974 | } | 974 | } |
975 | 975 | ||
976 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); | 976 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); |
977 | if (pdrvextra_cmd_parm == NULL) { | 977 | if (pdrvextra_cmd_parm == NULL) { |
978 | kfree(ph2c); | 978 | kfree(ph2c); |
979 | res = _FAIL; | 979 | res = _FAIL; |
@@ -1010,13 +1010,13 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time) | |||
1010 | 1010 | ||
1011 | u8 res = _SUCCESS; | 1011 | u8 res = _SUCCESS; |
1012 | 1012 | ||
1013 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 1013 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
1014 | if (ph2c == NULL) { | 1014 | if (ph2c == NULL) { |
1015 | res = _FAIL; | 1015 | res = _FAIL; |
1016 | goto exit; | 1016 | goto exit; |
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); | 1019 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); |
1020 | if (pdrvextra_cmd_parm == NULL) { | 1020 | if (pdrvextra_cmd_parm == NULL) { |
1021 | kfree(ph2c); | 1021 | kfree(ph2c); |
1022 | res = _FAIL; | 1022 | res = _FAIL; |
@@ -1088,13 +1088,13 @@ u8 rtw_ps_cmd(struct adapter *padapter) | |||
1088 | 1088 | ||
1089 | u8 res = _SUCCESS; | 1089 | u8 res = _SUCCESS; |
1090 | 1090 | ||
1091 | ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 1091 | ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
1092 | if (ppscmd == NULL) { | 1092 | if (ppscmd == NULL) { |
1093 | res = _FAIL; | 1093 | res = _FAIL; |
1094 | goto exit; | 1094 | goto exit; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); | 1097 | pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); |
1098 | if (pdrvextra_cmd_parm == NULL) { | 1098 | if (pdrvextra_cmd_parm == NULL) { |
1099 | kfree(ppscmd); | 1099 | kfree(ppscmd); |
1100 | res = _FAIL; | 1100 | res = _FAIL; |
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 5ba5099ec20d..70b1bc3e0e63 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | |||
@@ -4241,12 +4241,12 @@ void report_survey_event(struct adapter *padapter, | |||
4241 | pcmdpriv = &padapter->cmdpriv; | 4241 | pcmdpriv = &padapter->cmdpriv; |
4242 | 4242 | ||
4243 | 4243 | ||
4244 | pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 4244 | pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
4245 | if (pcmd_obj == NULL) | 4245 | if (pcmd_obj == NULL) |
4246 | return; | 4246 | return; |
4247 | 4247 | ||
4248 | cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); | 4248 | cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); |
4249 | pevtcmd = kzalloc(cmdsz, GFP_KERNEL); | 4249 | pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); |
4250 | if (pevtcmd == NULL) { | 4250 | if (pevtcmd == NULL) { |
4251 | kfree(pcmd_obj); | 4251 | kfree(pcmd_obj); |
4252 | return; | 4252 | return; |
@@ -4339,12 +4339,12 @@ void report_join_res(struct adapter *padapter, int res) | |||
4339 | struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); | 4339 | struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); |
4340 | struct cmd_priv *pcmdpriv = &padapter->cmdpriv; | 4340 | struct cmd_priv *pcmdpriv = &padapter->cmdpriv; |
4341 | 4341 | ||
4342 | pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 4342 | pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
4343 | if (pcmd_obj == NULL) | 4343 | if (pcmd_obj == NULL) |
4344 | return; | 4344 | return; |
4345 | 4345 | ||
4346 | cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); | 4346 | cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); |
4347 | pevtcmd = kzalloc(cmdsz, GFP_KERNEL); | 4347 | pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); |
4348 | if (pevtcmd == NULL) { | 4348 | if (pevtcmd == NULL) { |
4349 | kfree(pcmd_obj); | 4349 | kfree(pcmd_obj); |
4350 | return; | 4350 | return; |
@@ -4854,11 +4854,11 @@ void survey_timer_hdl(void *function_context) | |||
4854 | pmlmeext->scan_abort = false;/* reset */ | 4854 | pmlmeext->scan_abort = false;/* reset */ |
4855 | } | 4855 | } |
4856 | 4856 | ||
4857 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); | 4857 | ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); |
4858 | if (ph2c == NULL) | 4858 | if (ph2c == NULL) |
4859 | goto exit_survey_timer_hdl; | 4859 | goto exit_survey_timer_hdl; |
4860 | 4860 | ||
4861 | psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL); | 4861 | psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); |
4862 | if (psurveyPara == NULL) { | 4862 | if (psurveyPara == NULL) { |
4863 | kfree(ph2c); | 4863 | kfree(ph2c); |
4864 | goto exit_survey_timer_hdl; | 4864 | goto exit_survey_timer_hdl; |
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 33ccbbbd8ed6..d300369977fa 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c | |||
@@ -935,7 +935,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) | |||
935 | return true; | 935 | return true; |
936 | } | 936 | } |
937 | 937 | ||
938 | bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_KERNEL); | 938 | bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); |
939 | 939 | ||
940 | subtype = GetFrameSubType(pframe) >> 4; | 940 | subtype = GetFrameSubType(pframe) >> 4; |
941 | 941 | ||
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 407a318b09db..2f87150a21b7 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c | |||
@@ -47,6 +47,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = { | |||
47 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ | 47 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ |
48 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ | 48 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ |
49 | {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ | 49 | {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ |
50 | {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ | ||
50 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ | 51 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ |
51 | {} /* Terminating entry */ | 52 | {} /* Terminating entry */ |
52 | }; | 53 | }; |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index b19e4329ba00..73e58d22e325 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -3491,7 +3491,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3491 | len = sprintf(buf, "TargetAddress=" | 3491 | len = sprintf(buf, "TargetAddress=" |
3492 | "%s:%hu,%hu", | 3492 | "%s:%hu,%hu", |
3493 | inaddr_any ? conn->local_ip : np->np_ip, | 3493 | inaddr_any ? conn->local_ip : np->np_ip, |
3494 | inaddr_any ? conn->local_port : np->np_port, | 3494 | np->np_port, |
3495 | tpg->tpgt); | 3495 | tpg->tpgt); |
3496 | len += 1; | 3496 | len += 1; |
3497 | 3497 | ||
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 8c60a1a1ae8d..9f93b8234095 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -2738,7 +2738,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2738 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; | 2738 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; |
2739 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2739 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2740 | u32 pr_res_mapped_lun = 0; | 2740 | u32 pr_res_mapped_lun = 0; |
2741 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; | 2741 | int all_reg = 0, calling_it_nexus = 0; |
2742 | bool sa_res_key_unmatched = sa_res_key != 0; | ||
2742 | int prh_type = 0, prh_scope = 0; | 2743 | int prh_type = 0, prh_scope = 0; |
2743 | 2744 | ||
2744 | if (!se_sess) | 2745 | if (!se_sess) |
@@ -2813,6 +2814,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2813 | if (!all_reg) { | 2814 | if (!all_reg) { |
2814 | if (pr_reg->pr_res_key != sa_res_key) | 2815 | if (pr_reg->pr_res_key != sa_res_key) |
2815 | continue; | 2816 | continue; |
2817 | sa_res_key_unmatched = false; | ||
2816 | 2818 | ||
2817 | calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; | 2819 | calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; |
2818 | pr_reg_nacl = pr_reg->pr_reg_nacl; | 2820 | pr_reg_nacl = pr_reg->pr_reg_nacl; |
@@ -2820,7 +2822,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2820 | __core_scsi3_free_registration(dev, pr_reg, | 2822 | __core_scsi3_free_registration(dev, pr_reg, |
2821 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : | 2823 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : |
2822 | NULL, calling_it_nexus); | 2824 | NULL, calling_it_nexus); |
2823 | released_regs++; | ||
2824 | } else { | 2825 | } else { |
2825 | /* | 2826 | /* |
2826 | * Case for any existing all registrants type | 2827 | * Case for any existing all registrants type |
@@ -2838,6 +2839,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2838 | if ((sa_res_key) && | 2839 | if ((sa_res_key) && |
2839 | (pr_reg->pr_res_key != sa_res_key)) | 2840 | (pr_reg->pr_res_key != sa_res_key)) |
2840 | continue; | 2841 | continue; |
2842 | sa_res_key_unmatched = false; | ||
2841 | 2843 | ||
2842 | calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; | 2844 | calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; |
2843 | if (calling_it_nexus) | 2845 | if (calling_it_nexus) |
@@ -2848,7 +2850,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2848 | __core_scsi3_free_registration(dev, pr_reg, | 2850 | __core_scsi3_free_registration(dev, pr_reg, |
2849 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : | 2851 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : |
2850 | NULL, 0); | 2852 | NULL, 0); |
2851 | released_regs++; | ||
2852 | } | 2853 | } |
2853 | if (!calling_it_nexus) | 2854 | if (!calling_it_nexus) |
2854 | core_scsi3_ua_allocate(pr_reg_nacl, | 2855 | core_scsi3_ua_allocate(pr_reg_nacl, |
@@ -2863,7 +2864,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2863 | * registered reservation key, then the device server shall | 2864 | * registered reservation key, then the device server shall |
2864 | * complete the command with RESERVATION CONFLICT status. | 2865 | * complete the command with RESERVATION CONFLICT status. |
2865 | */ | 2866 | */ |
2866 | if (!released_regs) { | 2867 | if (sa_res_key_unmatched) { |
2867 | spin_unlock(&dev->dev_reservation_lock); | 2868 | spin_unlock(&dev->dev_reservation_lock); |
2868 | core_scsi3_put_pr_reg(pr_reg_n); | 2869 | core_scsi3_put_pr_reg(pr_reg_n); |
2869 | return TCM_RESERVATION_CONFLICT; | 2870 | return TCM_RESERVATION_CONFLICT; |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 9ea0d5f03f7a..be877bf6f730 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -2292,7 +2292,7 @@ transport_generic_new_cmd(struct se_cmd *cmd) | |||
2292 | * and let it call back once the write buffers are ready. | 2292 | * and let it call back once the write buffers are ready. |
2293 | */ | 2293 | */ |
2294 | target_add_to_state_list(cmd); | 2294 | target_add_to_state_list(cmd); |
2295 | if (cmd->data_direction != DMA_TO_DEVICE) { | 2295 | if (cmd->data_direction != DMA_TO_DEVICE || cmd->data_length == 0) { |
2296 | target_execute_cmd(cmd); | 2296 | target_execute_cmd(cmd); |
2297 | return 0; | 2297 | return 0; |
2298 | } | 2298 | } |
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 1ab0018271c5..ad09e51ffae4 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
@@ -50,15 +50,14 @@ struct cpufreq_cooling_device { | |||
50 | unsigned int cpufreq_state; | 50 | unsigned int cpufreq_state; |
51 | unsigned int cpufreq_val; | 51 | unsigned int cpufreq_val; |
52 | struct cpumask allowed_cpus; | 52 | struct cpumask allowed_cpus; |
53 | struct list_head node; | ||
53 | }; | 54 | }; |
54 | static DEFINE_IDR(cpufreq_idr); | 55 | static DEFINE_IDR(cpufreq_idr); |
55 | static DEFINE_MUTEX(cooling_cpufreq_lock); | 56 | static DEFINE_MUTEX(cooling_cpufreq_lock); |
56 | 57 | ||
57 | static unsigned int cpufreq_dev_count; | 58 | static unsigned int cpufreq_dev_count; |
58 | 59 | ||
59 | /* notify_table passes value to the CPUFREQ_ADJUST callback function. */ | 60 | static LIST_HEAD(cpufreq_dev_list); |
60 | #define NOTIFY_INVALID NULL | ||
61 | static struct cpufreq_cooling_device *notify_device; | ||
62 | 61 | ||
63 | /** | 62 | /** |
64 | * get_idr - function to get a unique id. | 63 | * get_idr - function to get a unique id. |
@@ -287,15 +286,12 @@ static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device, | |||
287 | 286 | ||
288 | cpufreq_device->cpufreq_state = cooling_state; | 287 | cpufreq_device->cpufreq_state = cooling_state; |
289 | cpufreq_device->cpufreq_val = clip_freq; | 288 | cpufreq_device->cpufreq_val = clip_freq; |
290 | notify_device = cpufreq_device; | ||
291 | 289 | ||
292 | for_each_cpu(cpuid, mask) { | 290 | for_each_cpu(cpuid, mask) { |
293 | if (is_cpufreq_valid(cpuid)) | 291 | if (is_cpufreq_valid(cpuid)) |
294 | cpufreq_update_policy(cpuid); | 292 | cpufreq_update_policy(cpuid); |
295 | } | 293 | } |
296 | 294 | ||
297 | notify_device = NOTIFY_INVALID; | ||
298 | |||
299 | return 0; | 295 | return 0; |
300 | } | 296 | } |
301 | 297 | ||
@@ -316,21 +312,28 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, | |||
316 | { | 312 | { |
317 | struct cpufreq_policy *policy = data; | 313 | struct cpufreq_policy *policy = data; |
318 | unsigned long max_freq = 0; | 314 | unsigned long max_freq = 0; |
315 | struct cpufreq_cooling_device *cpufreq_dev; | ||
319 | 316 | ||
320 | if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID) | 317 | if (event != CPUFREQ_ADJUST) |
321 | return 0; | 318 | return 0; |
322 | 319 | ||
323 | if (cpumask_test_cpu(policy->cpu, ¬ify_device->allowed_cpus)) | 320 | mutex_lock(&cooling_cpufreq_lock); |
324 | max_freq = notify_device->cpufreq_val; | 321 | list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { |
325 | else | 322 | if (!cpumask_test_cpu(policy->cpu, |
326 | return 0; | 323 | &cpufreq_dev->allowed_cpus)) |
324 | continue; | ||
325 | |||
326 | if (!cpufreq_dev->cpufreq_val) | ||
327 | cpufreq_dev->cpufreq_val = get_cpu_frequency( | ||
328 | cpumask_any(&cpufreq_dev->allowed_cpus), | ||
329 | cpufreq_dev->cpufreq_state); | ||
327 | 330 | ||
328 | /* Never exceed user_policy.max */ | 331 | max_freq = cpufreq_dev->cpufreq_val; |
329 | if (max_freq > policy->user_policy.max) | ||
330 | max_freq = policy->user_policy.max; | ||
331 | 332 | ||
332 | if (policy->max != max_freq) | 333 | if (policy->max != max_freq) |
333 | cpufreq_verify_within_limits(policy, 0, max_freq); | 334 | cpufreq_verify_within_limits(policy, 0, max_freq); |
335 | } | ||
336 | mutex_unlock(&cooling_cpufreq_lock); | ||
334 | 337 | ||
335 | return 0; | 338 | return 0; |
336 | } | 339 | } |
@@ -486,6 +489,7 @@ __cpufreq_cooling_register(struct device_node *np, | |||
486 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, | 489 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, |
487 | CPUFREQ_POLICY_NOTIFIER); | 490 | CPUFREQ_POLICY_NOTIFIER); |
488 | cpufreq_dev_count++; | 491 | cpufreq_dev_count++; |
492 | list_add(&cpufreq_dev->node, &cpufreq_dev_list); | ||
489 | 493 | ||
490 | mutex_unlock(&cooling_cpufreq_lock); | 494 | mutex_unlock(&cooling_cpufreq_lock); |
491 | 495 | ||
@@ -549,6 +553,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) | |||
549 | 553 | ||
550 | cpufreq_dev = cdev->devdata; | 554 | cpufreq_dev = cdev->devdata; |
551 | mutex_lock(&cooling_cpufreq_lock); | 555 | mutex_lock(&cooling_cpufreq_lock); |
556 | list_del(&cpufreq_dev->node); | ||
552 | cpufreq_dev_count--; | 557 | cpufreq_dev_count--; |
553 | 558 | ||
554 | /* Unregister the notifier for the last cpufreq cooling device */ | 559 | /* Unregister the notifier for the last cpufreq cooling device */ |
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c index 3f5ad25ddca8..b6be572704a4 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.c +++ b/drivers/thermal/samsung/exynos_thermal_common.c | |||
@@ -417,13 +417,10 @@ void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf) | |||
417 | 417 | ||
418 | th_zone = sensor_conf->pzone_data; | 418 | th_zone = sensor_conf->pzone_data; |
419 | 419 | ||
420 | if (th_zone->therm_dev) | 420 | thermal_zone_device_unregister(th_zone->therm_dev); |
421 | thermal_zone_device_unregister(th_zone->therm_dev); | ||
422 | 421 | ||
423 | for (i = 0; i < th_zone->cool_dev_size; i++) { | 422 | for (i = 0; i < th_zone->cool_dev_size; ++i) |
424 | if (th_zone->cool_dev[i]) | 423 | cpufreq_cooling_unregister(th_zone->cool_dev[i]); |
425 | cpufreq_cooling_unregister(th_zone->cool_dev[i]); | ||
426 | } | ||
427 | 424 | ||
428 | dev_info(sensor_conf->dev, | 425 | dev_info(sensor_conf->dev, |
429 | "Exynos: Kernel Thermal management unregistered\n"); | 426 | "Exynos: Kernel Thermal management unregistered\n"); |
diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c index 90163b384660..d1ec5804c0bb 100644 --- a/drivers/thermal/st/st_thermal.c +++ b/drivers/thermal/st/st_thermal.c | |||
@@ -275,6 +275,7 @@ int st_thermal_unregister(struct platform_device *pdev) | |||
275 | } | 275 | } |
276 | EXPORT_SYMBOL_GPL(st_thermal_unregister); | 276 | EXPORT_SYMBOL_GPL(st_thermal_unregister); |
277 | 277 | ||
278 | #ifdef CONFIG_PM_SLEEP | ||
278 | static int st_thermal_suspend(struct device *dev) | 279 | static int st_thermal_suspend(struct device *dev) |
279 | { | 280 | { |
280 | struct platform_device *pdev = to_platform_device(dev); | 281 | struct platform_device *pdev = to_platform_device(dev); |
@@ -305,6 +306,8 @@ static int st_thermal_resume(struct device *dev) | |||
305 | 306 | ||
306 | return 0; | 307 | return 0; |
307 | } | 308 | } |
309 | #endif | ||
310 | |||
308 | SIMPLE_DEV_PM_OPS(st_thermal_pm_ops, st_thermal_suspend, st_thermal_resume); | 311 | SIMPLE_DEV_PM_OPS(st_thermal_pm_ops, st_thermal_suspend, st_thermal_resume); |
309 | EXPORT_SYMBOL_GPL(st_thermal_pm_ops); | 312 | EXPORT_SYMBOL_GPL(st_thermal_pm_ops); |
310 | 313 | ||
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 56982da4a9e9..bf355050eab6 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -240,32 +240,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev) | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | #ifdef CONFIG_PM_SLEEP | ||
244 | static int of_serial_suspend(struct device *dev) | ||
245 | { | ||
246 | struct of_serial_info *info = dev_get_drvdata(dev); | ||
247 | |||
248 | serial8250_suspend_port(info->line); | ||
249 | if (info->clk) | ||
250 | clk_disable_unprepare(info->clk); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int of_serial_resume(struct device *dev) | ||
256 | { | ||
257 | struct of_serial_info *info = dev_get_drvdata(dev); | ||
258 | |||
259 | if (info->clk) | ||
260 | clk_prepare_enable(info->clk); | ||
261 | |||
262 | serial8250_resume_port(info->line); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | #endif | ||
267 | static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); | ||
268 | |||
269 | /* | 243 | /* |
270 | * A few common types, add more as needed. | 244 | * A few common types, add more as needed. |
271 | */ | 245 | */ |
@@ -297,7 +271,6 @@ static struct platform_driver of_platform_serial_driver = { | |||
297 | .name = "of_serial", | 271 | .name = "of_serial", |
298 | .owner = THIS_MODULE, | 272 | .owner = THIS_MODULE, |
299 | .of_match_table = of_platform_serial_table, | 273 | .of_match_table = of_platform_serial_table, |
300 | .pm = &of_serial_pm_ops, | ||
301 | }, | 274 | }, |
302 | .probe = of_platform_serial_probe, | 275 | .probe = of_platform_serial_probe, |
303 | .remove = of_platform_serial_remove, | 276 | .remove = of_platform_serial_remove, |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 39b4081b632d..96fafed92b76 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -44,6 +44,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
44 | /* Creative SB Audigy 2 NX */ | 44 | /* Creative SB Audigy 2 NX */ |
45 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, | 45 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, |
46 | 46 | ||
47 | /* Microsoft Wireless Laser Mouse 6000 Receiver */ | ||
48 | { USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
49 | |||
47 | /* Microsoft LifeCam-VX700 v2.0 */ | 50 | /* Microsoft LifeCam-VX700 v2.0 */ |
48 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, | 51 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, |
49 | 52 | ||
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 711b23019d54..df38e7ef4976 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -791,6 +791,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
791 | 791 | ||
792 | trb = dwc->ep0_trb; | 792 | trb = dwc->ep0_trb; |
793 | 793 | ||
794 | r = next_request(&ep0->request_list); | ||
795 | if (!r) | ||
796 | return; | ||
797 | |||
794 | status = DWC3_TRB_SIZE_TRBSTS(trb->size); | 798 | status = DWC3_TRB_SIZE_TRBSTS(trb->size); |
795 | if (status == DWC3_TRBSTS_SETUP_PENDING) { | 799 | if (status == DWC3_TRBSTS_SETUP_PENDING) { |
796 | dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); | 800 | dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); |
@@ -801,10 +805,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
801 | return; | 805 | return; |
802 | } | 806 | } |
803 | 807 | ||
804 | r = next_request(&ep0->request_list); | ||
805 | if (!r) | ||
806 | return; | ||
807 | |||
808 | ur = &r->request; | 808 | ur = &r->request; |
809 | 809 | ||
810 | length = trb->size & DWC3_TRB_SIZE_MASK; | 810 | length = trb->size & DWC3_TRB_SIZE_MASK; |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 696160d48ae8..388cfd83b6b6 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | 23 | ||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/device.h> | ||
26 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
27 | 26 | ||
28 | #include "xhci.h" | 27 | #include "xhci.h" |
@@ -1149,9 +1148,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
1149 | * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME | 1148 | * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME |
1150 | * is enabled, so also enable remote wake here. | 1149 | * is enabled, so also enable remote wake here. |
1151 | */ | 1150 | */ |
1152 | if (hcd->self.root_hub->do_remote_wakeup | 1151 | if (hcd->self.root_hub->do_remote_wakeup) { |
1153 | && device_may_wakeup(hcd->self.controller)) { | ||
1154 | |||
1155 | if (t1 & PORT_CONNECT) { | 1152 | if (t1 & PORT_CONNECT) { |
1156 | t2 |= PORT_WKOC_E | PORT_WKDISC_E; | 1153 | t2 |= PORT_WKOC_E | PORT_WKDISC_E; |
1157 | t2 &= ~PORT_WKCONN_E; | 1154 | t2 &= ~PORT_WKCONN_E; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 9a69b1f1b300..142b601f9563 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -281,7 +281,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
281 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) | 281 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) |
282 | pdev->no_d3cold = true; | 282 | pdev->no_d3cold = true; |
283 | 283 | ||
284 | return xhci_suspend(xhci); | 284 | return xhci_suspend(xhci, do_wakeup); |
285 | } | 285 | } |
286 | 286 | ||
287 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 287 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 3d78b0cd674b..646300cbe5f7 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -204,7 +204,15 @@ static int xhci_plat_suspend(struct device *dev) | |||
204 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 204 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
205 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 205 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
206 | 206 | ||
207 | return xhci_suspend(xhci); | 207 | /* |
208 | * xhci_suspend() needs `do_wakeup` to know whether host is allowed | ||
209 | * to do wakeup during suspend. Since xhci_plat_suspend is currently | ||
210 | * only designed for system suspend, device_may_wakeup() is enough | ||
211 | * to dertermine whether host is allowed to do wakeup. Need to | ||
212 | * reconsider this when xhci_plat_suspend enlarges its scope, e.g., | ||
213 | * also applies to runtime suspend. | ||
214 | */ | ||
215 | return xhci_suspend(xhci, device_may_wakeup(dev)); | ||
208 | } | 216 | } |
209 | 217 | ||
210 | static int xhci_plat_resume(struct device *dev) | 218 | static int xhci_plat_resume(struct device *dev) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bc6fcbc16f61..06433aec81d7 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1067,9 +1067,8 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id, | |||
1067 | false); | 1067 | false); |
1068 | xhci_ring_cmd_db(xhci); | 1068 | xhci_ring_cmd_db(xhci); |
1069 | } else { | 1069 | } else { |
1070 | /* Clear our internal halted state and restart the ring(s) */ | 1070 | /* Clear our internal halted state */ |
1071 | xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED; | 1071 | xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED; |
1072 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); | ||
1073 | } | 1072 | } |
1074 | } | 1073 | } |
1075 | 1074 | ||
@@ -1823,22 +1822,13 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1823 | ep->stopped_td = td; | 1822 | ep->stopped_td = td; |
1824 | return 0; | 1823 | return 0; |
1825 | } else { | 1824 | } else { |
1826 | if (trb_comp_code == COMP_STALL) { | 1825 | if (trb_comp_code == COMP_STALL || |
1827 | /* The transfer is completed from the driver's | 1826 | xhci_requires_manual_halt_cleanup(xhci, ep_ctx, |
1828 | * perspective, but we need to issue a set dequeue | 1827 | trb_comp_code)) { |
1829 | * command for this stalled endpoint to move the dequeue | 1828 | /* Issue a reset endpoint command to clear the host side |
1830 | * pointer past the TD. We can't do that here because | 1829 | * halt, followed by a set dequeue command to move the |
1831 | * the halt condition must be cleared first. Let the | 1830 | * dequeue pointer past the TD. |
1832 | * USB class driver clear the stall later. | 1831 | * The class driver clears the device side halt later. |
1833 | */ | ||
1834 | ep->stopped_td = td; | ||
1835 | ep->stopped_stream = ep_ring->stream_id; | ||
1836 | } else if (xhci_requires_manual_halt_cleanup(xhci, | ||
1837 | ep_ctx, trb_comp_code)) { | ||
1838 | /* Other types of errors halt the endpoint, but the | ||
1839 | * class driver doesn't call usb_reset_endpoint() unless | ||
1840 | * the error is -EPIPE. Clear the halted status in the | ||
1841 | * xHCI hardware manually. | ||
1842 | */ | 1832 | */ |
1843 | xhci_cleanup_halted_endpoint(xhci, | 1833 | xhci_cleanup_halted_endpoint(xhci, |
1844 | slot_id, ep_index, ep_ring->stream_id, | 1834 | slot_id, ep_index, ep_ring->stream_id, |
@@ -1958,9 +1948,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1958 | else | 1948 | else |
1959 | td->urb->actual_length = 0; | 1949 | td->urb->actual_length = 0; |
1960 | 1950 | ||
1961 | xhci_cleanup_halted_endpoint(xhci, | 1951 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
1962 | slot_id, ep_index, 0, td, event_trb); | ||
1963 | return finish_td(xhci, td, event_trb, event, ep, status, true); | ||
1964 | } | 1952 | } |
1965 | /* | 1953 | /* |
1966 | * Did we transfer any data, despite the errors that might have | 1954 | * Did we transfer any data, despite the errors that might have |
@@ -2519,17 +2507,8 @@ cleanup: | |||
2519 | if (ret) { | 2507 | if (ret) { |
2520 | urb = td->urb; | 2508 | urb = td->urb; |
2521 | urb_priv = urb->hcpriv; | 2509 | urb_priv = urb->hcpriv; |
2522 | /* Leave the TD around for the reset endpoint function | 2510 | |
2523 | * to use(but only if it's not a control endpoint, | 2511 | xhci_urb_free_priv(xhci, urb_priv); |
2524 | * since we already queued the Set TR dequeue pointer | ||
2525 | * command for stalled control endpoints). | ||
2526 | */ | ||
2527 | if (usb_endpoint_xfer_control(&urb->ep->desc) || | ||
2528 | (trb_comp_code != COMP_STALL && | ||
2529 | trb_comp_code != COMP_BABBLE)) | ||
2530 | xhci_urb_free_priv(xhci, urb_priv); | ||
2531 | else | ||
2532 | kfree(urb_priv); | ||
2533 | 2512 | ||
2534 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); | 2513 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
2535 | if ((urb->actual_length != urb->transfer_buffer_length && | 2514 | if ((urb->actual_length != urb->transfer_buffer_length && |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2a5d45b4cb15..033b46c470bd 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #define DRIVER_AUTHOR "Sarah Sharp" | 35 | #define DRIVER_AUTHOR "Sarah Sharp" |
36 | #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" | 36 | #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" |
37 | 37 | ||
38 | #define PORT_WAKE_BITS (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E) | ||
39 | |||
38 | /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ | 40 | /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ |
39 | static int link_quirk; | 41 | static int link_quirk; |
40 | module_param(link_quirk, int, S_IRUGO | S_IWUSR); | 42 | module_param(link_quirk, int, S_IRUGO | S_IWUSR); |
@@ -851,13 +853,47 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) | |||
851 | xhci_set_cmd_ring_deq(xhci); | 853 | xhci_set_cmd_ring_deq(xhci); |
852 | } | 854 | } |
853 | 855 | ||
856 | static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci) | ||
857 | { | ||
858 | int port_index; | ||
859 | __le32 __iomem **port_array; | ||
860 | unsigned long flags; | ||
861 | u32 t1, t2; | ||
862 | |||
863 | spin_lock_irqsave(&xhci->lock, flags); | ||
864 | |||
865 | /* disble usb3 ports Wake bits*/ | ||
866 | port_index = xhci->num_usb3_ports; | ||
867 | port_array = xhci->usb3_ports; | ||
868 | while (port_index--) { | ||
869 | t1 = readl(port_array[port_index]); | ||
870 | t1 = xhci_port_state_to_neutral(t1); | ||
871 | t2 = t1 & ~PORT_WAKE_BITS; | ||
872 | if (t1 != t2) | ||
873 | writel(t2, port_array[port_index]); | ||
874 | } | ||
875 | |||
876 | /* disble usb2 ports Wake bits*/ | ||
877 | port_index = xhci->num_usb2_ports; | ||
878 | port_array = xhci->usb2_ports; | ||
879 | while (port_index--) { | ||
880 | t1 = readl(port_array[port_index]); | ||
881 | t1 = xhci_port_state_to_neutral(t1); | ||
882 | t2 = t1 & ~PORT_WAKE_BITS; | ||
883 | if (t1 != t2) | ||
884 | writel(t2, port_array[port_index]); | ||
885 | } | ||
886 | |||
887 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
888 | } | ||
889 | |||
854 | /* | 890 | /* |
855 | * Stop HC (not bus-specific) | 891 | * Stop HC (not bus-specific) |
856 | * | 892 | * |
857 | * This is called when the machine transition into S3/S4 mode. | 893 | * This is called when the machine transition into S3/S4 mode. |
858 | * | 894 | * |
859 | */ | 895 | */ |
860 | int xhci_suspend(struct xhci_hcd *xhci) | 896 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) |
861 | { | 897 | { |
862 | int rc = 0; | 898 | int rc = 0; |
863 | unsigned int delay = XHCI_MAX_HALT_USEC; | 899 | unsigned int delay = XHCI_MAX_HALT_USEC; |
@@ -868,6 +904,10 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
868 | xhci->shared_hcd->state != HC_STATE_SUSPENDED) | 904 | xhci->shared_hcd->state != HC_STATE_SUSPENDED) |
869 | return -EINVAL; | 905 | return -EINVAL; |
870 | 906 | ||
907 | /* Clear root port wake on bits if wakeup not allowed. */ | ||
908 | if (!do_wakeup) | ||
909 | xhci_disable_port_wake_on_bits(xhci); | ||
910 | |||
871 | /* Don't poll the roothubs on bus suspend. */ | 911 | /* Don't poll the roothubs on bus suspend. */ |
872 | xhci_dbg(xhci, "%s: stopping port polling.\n", __func__); | 912 | xhci_dbg(xhci, "%s: stopping port polling.\n", __func__); |
873 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | 913 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); |
@@ -2912,68 +2952,33 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, | |||
2912 | } | 2952 | } |
2913 | } | 2953 | } |
2914 | 2954 | ||
2915 | /* Deal with stalled endpoints. The core should have sent the control message | 2955 | /* Called when clearing halted device. The core should have sent the control |
2916 | * to clear the halt condition. However, we need to make the xHCI hardware | 2956 | * message to clear the device halt condition. The host side of the halt should |
2917 | * reset its sequence number, since a device will expect a sequence number of | 2957 | * already be cleared with a reset endpoint command issued when the STALL tx |
2918 | * zero after the halt condition is cleared. | 2958 | * event was received. |
2959 | * | ||
2919 | * Context: in_interrupt | 2960 | * Context: in_interrupt |
2920 | */ | 2961 | */ |
2962 | |||
2921 | void xhci_endpoint_reset(struct usb_hcd *hcd, | 2963 | void xhci_endpoint_reset(struct usb_hcd *hcd, |
2922 | struct usb_host_endpoint *ep) | 2964 | struct usb_host_endpoint *ep) |
2923 | { | 2965 | { |
2924 | struct xhci_hcd *xhci; | 2966 | struct xhci_hcd *xhci; |
2925 | struct usb_device *udev; | ||
2926 | unsigned int ep_index; | ||
2927 | unsigned long flags; | ||
2928 | int ret; | ||
2929 | struct xhci_virt_ep *virt_ep; | ||
2930 | struct xhci_command *command; | ||
2931 | 2967 | ||
2932 | xhci = hcd_to_xhci(hcd); | 2968 | xhci = hcd_to_xhci(hcd); |
2933 | udev = (struct usb_device *) ep->hcpriv; | ||
2934 | /* Called with a root hub endpoint (or an endpoint that wasn't added | ||
2935 | * with xhci_add_endpoint() | ||
2936 | */ | ||
2937 | if (!ep->hcpriv) | ||
2938 | return; | ||
2939 | ep_index = xhci_get_endpoint_index(&ep->desc); | ||
2940 | virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; | ||
2941 | if (!virt_ep->stopped_td) { | ||
2942 | xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, | ||
2943 | "Endpoint 0x%x not halted, refusing to reset.", | ||
2944 | ep->desc.bEndpointAddress); | ||
2945 | return; | ||
2946 | } | ||
2947 | if (usb_endpoint_xfer_control(&ep->desc)) { | ||
2948 | xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, | ||
2949 | "Control endpoint stall already handled."); | ||
2950 | return; | ||
2951 | } | ||
2952 | 2969 | ||
2953 | command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); | ||
2954 | if (!command) | ||
2955 | return; | ||
2956 | |||
2957 | xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, | ||
2958 | "Queueing reset endpoint command"); | ||
2959 | spin_lock_irqsave(&xhci->lock, flags); | ||
2960 | ret = xhci_queue_reset_ep(xhci, command, udev->slot_id, ep_index); | ||
2961 | /* | 2970 | /* |
2962 | * Can't change the ring dequeue pointer until it's transitioned to the | 2971 | * We might need to implement the config ep cmd in xhci 4.8.1 note: |
2963 | * stopped state, which is only upon a successful reset endpoint | 2972 | * The Reset Endpoint Command may only be issued to endpoints in the |
2964 | * command. Better hope that last command worked! | 2973 | * Halted state. If software wishes reset the Data Toggle or Sequence |
2974 | * Number of an endpoint that isn't in the Halted state, then software | ||
2975 | * may issue a Configure Endpoint Command with the Drop and Add bits set | ||
2976 | * for the target endpoint. that is in the Stopped state. | ||
2965 | */ | 2977 | */ |
2966 | if (!ret) { | ||
2967 | xhci_cleanup_stalled_ring(xhci, udev, ep_index); | ||
2968 | kfree(virt_ep->stopped_td); | ||
2969 | xhci_ring_cmd_db(xhci); | ||
2970 | } | ||
2971 | virt_ep->stopped_td = NULL; | ||
2972 | virt_ep->stopped_stream = 0; | ||
2973 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2974 | 2978 | ||
2975 | if (ret) | 2979 | /* For now just print debug to follow the situation */ |
2976 | xhci_warn(xhci, "FIXME allocate a new ring segment\n"); | 2980 | xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n", |
2981 | ep->desc.bEndpointAddress); | ||
2977 | } | 2982 | } |
2978 | 2983 | ||
2979 | static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, | 2984 | static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index df76d642e719..d745715a1e2f 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1746,7 +1746,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); | |||
1746 | void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *)); | 1746 | void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *)); |
1747 | 1747 | ||
1748 | #ifdef CONFIG_PM | 1748 | #ifdef CONFIG_PM |
1749 | int xhci_suspend(struct xhci_hcd *xhci); | 1749 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); |
1750 | int xhci_resume(struct xhci_hcd *xhci, bool hibernated); | 1750 | int xhci_resume(struct xhci_hcd *xhci, bool hibernated); |
1751 | #else | 1751 | #else |
1752 | #define xhci_suspend NULL | 1752 | #define xhci_suspend NULL |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index cfd009dc4018..6c4eb3cf5efd 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -120,6 +120,7 @@ static const struct usb_device_id id_table[] = { | |||
120 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ | 120 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ |
121 | { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ | 121 | { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ |
122 | { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ | 122 | { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ |
123 | { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */ | ||
123 | { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ | 124 | { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ |
124 | { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ | 125 | { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ |
125 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ | 126 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0dad8ce5a609..1ebb351b9e9a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -470,6 +470,39 @@ static const struct usb_device_id id_table_combined[] = { | |||
470 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) }, | 470 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) }, |
471 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) }, | 471 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) }, |
472 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) }, | 472 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) }, |
473 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_4701_PID) }, | ||
474 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9300_PID) }, | ||
475 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9301_PID) }, | ||
476 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9302_PID) }, | ||
477 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9303_PID) }, | ||
478 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9304_PID) }, | ||
479 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9305_PID) }, | ||
480 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9306_PID) }, | ||
481 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9307_PID) }, | ||
482 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9308_PID) }, | ||
483 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9309_PID) }, | ||
484 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930A_PID) }, | ||
485 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930B_PID) }, | ||
486 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930C_PID) }, | ||
487 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930D_PID) }, | ||
488 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930E_PID) }, | ||
489 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930F_PID) }, | ||
490 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9310_PID) }, | ||
491 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9311_PID) }, | ||
492 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9312_PID) }, | ||
493 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9313_PID) }, | ||
494 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9314_PID) }, | ||
495 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9315_PID) }, | ||
496 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9316_PID) }, | ||
497 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9317_PID) }, | ||
498 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9318_PID) }, | ||
499 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9319_PID) }, | ||
500 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931A_PID) }, | ||
501 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931B_PID) }, | ||
502 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931C_PID) }, | ||
503 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931D_PID) }, | ||
504 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931E_PID) }, | ||
505 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931F_PID) }, | ||
473 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, | 506 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, |
474 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, | 507 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, |
475 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, | 508 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 6786b705ccf6..e52409c9be99 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -926,8 +926,8 @@ | |||
926 | #define BAYER_CONTOUR_CABLE_PID 0x6001 | 926 | #define BAYER_CONTOUR_CABLE_PID 0x6001 |
927 | 927 | ||
928 | /* | 928 | /* |
929 | * The following are the values for the Matrix Orbital FTDI Range | 929 | * Matrix Orbital Intelligent USB displays. |
930 | * Anything in this range will use an FT232RL. | 930 | * http://www.matrixorbital.com |
931 | */ | 931 | */ |
932 | #define MTXORB_VID 0x1B3D | 932 | #define MTXORB_VID 0x1B3D |
933 | #define MTXORB_FTDI_RANGE_0100_PID 0x0100 | 933 | #define MTXORB_FTDI_RANGE_0100_PID 0x0100 |
@@ -1186,8 +1186,39 @@ | |||
1186 | #define MTXORB_FTDI_RANGE_01FD_PID 0x01FD | 1186 | #define MTXORB_FTDI_RANGE_01FD_PID 0x01FD |
1187 | #define MTXORB_FTDI_RANGE_01FE_PID 0x01FE | 1187 | #define MTXORB_FTDI_RANGE_01FE_PID 0x01FE |
1188 | #define MTXORB_FTDI_RANGE_01FF_PID 0x01FF | 1188 | #define MTXORB_FTDI_RANGE_01FF_PID 0x01FF |
1189 | 1189 | #define MTXORB_FTDI_RANGE_4701_PID 0x4701 | |
1190 | 1190 | #define MTXORB_FTDI_RANGE_9300_PID 0x9300 | |
1191 | #define MTXORB_FTDI_RANGE_9301_PID 0x9301 | ||
1192 | #define MTXORB_FTDI_RANGE_9302_PID 0x9302 | ||
1193 | #define MTXORB_FTDI_RANGE_9303_PID 0x9303 | ||
1194 | #define MTXORB_FTDI_RANGE_9304_PID 0x9304 | ||
1195 | #define MTXORB_FTDI_RANGE_9305_PID 0x9305 | ||
1196 | #define MTXORB_FTDI_RANGE_9306_PID 0x9306 | ||
1197 | #define MTXORB_FTDI_RANGE_9307_PID 0x9307 | ||
1198 | #define MTXORB_FTDI_RANGE_9308_PID 0x9308 | ||
1199 | #define MTXORB_FTDI_RANGE_9309_PID 0x9309 | ||
1200 | #define MTXORB_FTDI_RANGE_930A_PID 0x930A | ||
1201 | #define MTXORB_FTDI_RANGE_930B_PID 0x930B | ||
1202 | #define MTXORB_FTDI_RANGE_930C_PID 0x930C | ||
1203 | #define MTXORB_FTDI_RANGE_930D_PID 0x930D | ||
1204 | #define MTXORB_FTDI_RANGE_930E_PID 0x930E | ||
1205 | #define MTXORB_FTDI_RANGE_930F_PID 0x930F | ||
1206 | #define MTXORB_FTDI_RANGE_9310_PID 0x9310 | ||
1207 | #define MTXORB_FTDI_RANGE_9311_PID 0x9311 | ||
1208 | #define MTXORB_FTDI_RANGE_9312_PID 0x9312 | ||
1209 | #define MTXORB_FTDI_RANGE_9313_PID 0x9313 | ||
1210 | #define MTXORB_FTDI_RANGE_9314_PID 0x9314 | ||
1211 | #define MTXORB_FTDI_RANGE_9315_PID 0x9315 | ||
1212 | #define MTXORB_FTDI_RANGE_9316_PID 0x9316 | ||
1213 | #define MTXORB_FTDI_RANGE_9317_PID 0x9317 | ||
1214 | #define MTXORB_FTDI_RANGE_9318_PID 0x9318 | ||
1215 | #define MTXORB_FTDI_RANGE_9319_PID 0x9319 | ||
1216 | #define MTXORB_FTDI_RANGE_931A_PID 0x931A | ||
1217 | #define MTXORB_FTDI_RANGE_931B_PID 0x931B | ||
1218 | #define MTXORB_FTDI_RANGE_931C_PID 0x931C | ||
1219 | #define MTXORB_FTDI_RANGE_931D_PID 0x931D | ||
1220 | #define MTXORB_FTDI_RANGE_931E_PID 0x931E | ||
1221 | #define MTXORB_FTDI_RANGE_931F_PID 0x931F | ||
1191 | 1222 | ||
1192 | /* | 1223 | /* |
1193 | * The Mobility Lab (TML) | 1224 | * The Mobility Lab (TML) |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 93cb7cebda62..077c714f1285 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -311,24 +311,30 @@ static void usa26_indat_callback(struct urb *urb) | |||
311 | if ((data[0] & 0x80) == 0) { | 311 | if ((data[0] & 0x80) == 0) { |
312 | /* no errors on individual bytes, only | 312 | /* no errors on individual bytes, only |
313 | possible overrun err */ | 313 | possible overrun err */ |
314 | if (data[0] & RXERROR_OVERRUN) | 314 | if (data[0] & RXERROR_OVERRUN) { |
315 | err = TTY_OVERRUN; | 315 | tty_insert_flip_char(&port->port, 0, |
316 | else | 316 | TTY_OVERRUN); |
317 | err = 0; | 317 | } |
318 | for (i = 1; i < urb->actual_length ; ++i) | 318 | for (i = 1; i < urb->actual_length ; ++i) |
319 | tty_insert_flip_char(&port->port, data[i], err); | 319 | tty_insert_flip_char(&port->port, data[i], |
320 | TTY_NORMAL); | ||
320 | } else { | 321 | } else { |
321 | /* some bytes had errors, every byte has status */ | 322 | /* some bytes had errors, every byte has status */ |
322 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); | 323 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); |
323 | for (i = 0; i + 1 < urb->actual_length; i += 2) { | 324 | for (i = 0; i + 1 < urb->actual_length; i += 2) { |
324 | int stat = data[i], flag = 0; | 325 | int stat = data[i]; |
325 | if (stat & RXERROR_OVERRUN) | 326 | int flag = TTY_NORMAL; |
326 | flag |= TTY_OVERRUN; | 327 | |
327 | if (stat & RXERROR_FRAMING) | 328 | if (stat & RXERROR_OVERRUN) { |
328 | flag |= TTY_FRAME; | 329 | tty_insert_flip_char(&port->port, 0, |
329 | if (stat & RXERROR_PARITY) | 330 | TTY_OVERRUN); |
330 | flag |= TTY_PARITY; | 331 | } |
331 | /* XXX should handle break (0x10) */ | 332 | /* XXX should handle break (0x10) */ |
333 | if (stat & RXERROR_PARITY) | ||
334 | flag = TTY_PARITY; | ||
335 | else if (stat & RXERROR_FRAMING) | ||
336 | flag = TTY_FRAME; | ||
337 | |||
332 | tty_insert_flip_char(&port->port, data[i+1], | 338 | tty_insert_flip_char(&port->port, data[i+1], |
333 | flag); | 339 | flag); |
334 | } | 340 | } |
@@ -649,14 +655,19 @@ static void usa49_indat_callback(struct urb *urb) | |||
649 | } else { | 655 | } else { |
650 | /* some bytes had errors, every byte has status */ | 656 | /* some bytes had errors, every byte has status */ |
651 | for (i = 0; i + 1 < urb->actual_length; i += 2) { | 657 | for (i = 0; i + 1 < urb->actual_length; i += 2) { |
652 | int stat = data[i], flag = 0; | 658 | int stat = data[i]; |
653 | if (stat & RXERROR_OVERRUN) | 659 | int flag = TTY_NORMAL; |
654 | flag |= TTY_OVERRUN; | 660 | |
655 | if (stat & RXERROR_FRAMING) | 661 | if (stat & RXERROR_OVERRUN) { |
656 | flag |= TTY_FRAME; | 662 | tty_insert_flip_char(&port->port, 0, |
657 | if (stat & RXERROR_PARITY) | 663 | TTY_OVERRUN); |
658 | flag |= TTY_PARITY; | 664 | } |
659 | /* XXX should handle break (0x10) */ | 665 | /* XXX should handle break (0x10) */ |
666 | if (stat & RXERROR_PARITY) | ||
667 | flag = TTY_PARITY; | ||
668 | else if (stat & RXERROR_FRAMING) | ||
669 | flag = TTY_FRAME; | ||
670 | |||
660 | tty_insert_flip_char(&port->port, data[i+1], | 671 | tty_insert_flip_char(&port->port, data[i+1], |
661 | flag); | 672 | flag); |
662 | } | 673 | } |
@@ -713,15 +724,19 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
713 | */ | 724 | */ |
714 | for (x = 0; x + 1 < len && | 725 | for (x = 0; x + 1 < len && |
715 | i + 1 < urb->actual_length; x += 2) { | 726 | i + 1 < urb->actual_length; x += 2) { |
716 | int stat = data[i], flag = 0; | 727 | int stat = data[i]; |
728 | int flag = TTY_NORMAL; | ||
717 | 729 | ||
718 | if (stat & RXERROR_OVERRUN) | 730 | if (stat & RXERROR_OVERRUN) { |
719 | flag |= TTY_OVERRUN; | 731 | tty_insert_flip_char(&port->port, 0, |
720 | if (stat & RXERROR_FRAMING) | 732 | TTY_OVERRUN); |
721 | flag |= TTY_FRAME; | 733 | } |
722 | if (stat & RXERROR_PARITY) | ||
723 | flag |= TTY_PARITY; | ||
724 | /* XXX should handle break (0x10) */ | 734 | /* XXX should handle break (0x10) */ |
735 | if (stat & RXERROR_PARITY) | ||
736 | flag = TTY_PARITY; | ||
737 | else if (stat & RXERROR_FRAMING) | ||
738 | flag = TTY_FRAME; | ||
739 | |||
725 | tty_insert_flip_char(&port->port, data[i+1], | 740 | tty_insert_flip_char(&port->port, data[i+1], |
726 | flag); | 741 | flag); |
727 | i += 2; | 742 | i += 2; |
@@ -773,25 +788,31 @@ static void usa90_indat_callback(struct urb *urb) | |||
773 | if ((data[0] & 0x80) == 0) { | 788 | if ((data[0] & 0x80) == 0) { |
774 | /* no errors on individual bytes, only | 789 | /* no errors on individual bytes, only |
775 | possible overrun err*/ | 790 | possible overrun err*/ |
776 | if (data[0] & RXERROR_OVERRUN) | 791 | if (data[0] & RXERROR_OVERRUN) { |
777 | err = TTY_OVERRUN; | 792 | tty_insert_flip_char(&port->port, 0, |
778 | else | 793 | TTY_OVERRUN); |
779 | err = 0; | 794 | } |
780 | for (i = 1; i < urb->actual_length ; ++i) | 795 | for (i = 1; i < urb->actual_length ; ++i) |
781 | tty_insert_flip_char(&port->port, | 796 | tty_insert_flip_char(&port->port, |
782 | data[i], err); | 797 | data[i], TTY_NORMAL); |
783 | } else { | 798 | } else { |
784 | /* some bytes had errors, every byte has status */ | 799 | /* some bytes had errors, every byte has status */ |
785 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); | 800 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); |
786 | for (i = 0; i + 1 < urb->actual_length; i += 2) { | 801 | for (i = 0; i + 1 < urb->actual_length; i += 2) { |
787 | int stat = data[i], flag = 0; | 802 | int stat = data[i]; |
788 | if (stat & RXERROR_OVERRUN) | 803 | int flag = TTY_NORMAL; |
789 | flag |= TTY_OVERRUN; | 804 | |
790 | if (stat & RXERROR_FRAMING) | 805 | if (stat & RXERROR_OVERRUN) { |
791 | flag |= TTY_FRAME; | 806 | tty_insert_flip_char( |
792 | if (stat & RXERROR_PARITY) | 807 | &port->port, 0, |
793 | flag |= TTY_PARITY; | 808 | TTY_OVERRUN); |
809 | } | ||
794 | /* XXX should handle break (0x10) */ | 810 | /* XXX should handle break (0x10) */ |
811 | if (stat & RXERROR_PARITY) | ||
812 | flag = TTY_PARITY; | ||
813 | else if (stat & RXERROR_FRAMING) | ||
814 | flag = TTY_FRAME; | ||
815 | |||
795 | tty_insert_flip_char(&port->port, | 816 | tty_insert_flip_char(&port->port, |
796 | data[i+1], flag); | 817 | data[i+1], flag); |
797 | } | 818 | } |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index a7fe664b6b7d..70a098de429f 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -490,10 +490,9 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | |||
490 | if (*tty_flag == TTY_NORMAL) | 490 | if (*tty_flag == TTY_NORMAL) |
491 | *tty_flag = TTY_FRAME; | 491 | *tty_flag = TTY_FRAME; |
492 | } | 492 | } |
493 | if (lsr & UART_LSR_OE){ | 493 | if (lsr & UART_LSR_OE) { |
494 | port->icount.overrun++; | 494 | port->icount.overrun++; |
495 | if (*tty_flag == TTY_NORMAL) | 495 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
496 | *tty_flag = TTY_OVERRUN; | ||
497 | } | 496 | } |
498 | } | 497 | } |
499 | 498 | ||
@@ -511,12 +510,8 @@ static void ssu100_process_read_urb(struct urb *urb) | |||
511 | if ((len >= 4) && | 510 | if ((len >= 4) && |
512 | (packet[0] == 0x1b) && (packet[1] == 0x1b) && | 511 | (packet[0] == 0x1b) && (packet[1] == 0x1b) && |
513 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { | 512 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { |
514 | if (packet[2] == 0x00) { | 513 | if (packet[2] == 0x00) |
515 | ssu100_update_lsr(port, packet[3], &flag); | 514 | ssu100_update_lsr(port, packet[3], &flag); |
516 | if (flag == TTY_OVERRUN) | ||
517 | tty_insert_flip_char(&port->port, 0, | ||
518 | TTY_OVERRUN); | ||
519 | } | ||
520 | if (packet[2] == 0x01) | 515 | if (packet[2] == 0x01) |
521 | ssu100_update_msr(port, packet[3]); | 516 | ssu100_update_msr(port, packet[3]); |
522 | 517 | ||
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 2fefaf923e4a..18a283d6de1c 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h | |||
@@ -103,3 +103,10 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, | |||
103 | "VL711", | 103 | "VL711", |
104 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 104 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
105 | US_FL_NO_ATA_1X), | 105 | US_FL_NO_ATA_1X), |
106 | |||
107 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ | ||
108 | UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, | ||
109 | "Hitachi", | ||
110 | "External HDD", | ||
111 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
112 | US_FL_IGNORE_UAS), | ||
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 69906cacd04f..a17f11850669 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -1312,6 +1312,7 @@ static int | |||
1312 | vhost_scsi_set_endpoint(struct vhost_scsi *vs, | 1312 | vhost_scsi_set_endpoint(struct vhost_scsi *vs, |
1313 | struct vhost_scsi_target *t) | 1313 | struct vhost_scsi_target *t) |
1314 | { | 1314 | { |
1315 | struct se_portal_group *se_tpg; | ||
1315 | struct tcm_vhost_tport *tv_tport; | 1316 | struct tcm_vhost_tport *tv_tport; |
1316 | struct tcm_vhost_tpg *tpg; | 1317 | struct tcm_vhost_tpg *tpg; |
1317 | struct tcm_vhost_tpg **vs_tpg; | 1318 | struct tcm_vhost_tpg **vs_tpg; |
@@ -1359,6 +1360,21 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs, | |||
1359 | ret = -EEXIST; | 1360 | ret = -EEXIST; |
1360 | goto out; | 1361 | goto out; |
1361 | } | 1362 | } |
1363 | /* | ||
1364 | * In order to ensure individual vhost-scsi configfs | ||
1365 | * groups cannot be removed while in use by vhost ioctl, | ||
1366 | * go ahead and take an explicit se_tpg->tpg_group.cg_item | ||
1367 | * dependency now. | ||
1368 | */ | ||
1369 | se_tpg = &tpg->se_tpg; | ||
1370 | ret = configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys, | ||
1371 | &se_tpg->tpg_group.cg_item); | ||
1372 | if (ret) { | ||
1373 | pr_warn("configfs_depend_item() failed: %d\n", ret); | ||
1374 | kfree(vs_tpg); | ||
1375 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1376 | goto out; | ||
1377 | } | ||
1362 | tpg->tv_tpg_vhost_count++; | 1378 | tpg->tv_tpg_vhost_count++; |
1363 | tpg->vhost_scsi = vs; | 1379 | tpg->vhost_scsi = vs; |
1364 | vs_tpg[tpg->tport_tpgt] = tpg; | 1380 | vs_tpg[tpg->tport_tpgt] = tpg; |
@@ -1401,6 +1417,7 @@ static int | |||
1401 | vhost_scsi_clear_endpoint(struct vhost_scsi *vs, | 1417 | vhost_scsi_clear_endpoint(struct vhost_scsi *vs, |
1402 | struct vhost_scsi_target *t) | 1418 | struct vhost_scsi_target *t) |
1403 | { | 1419 | { |
1420 | struct se_portal_group *se_tpg; | ||
1404 | struct tcm_vhost_tport *tv_tport; | 1421 | struct tcm_vhost_tport *tv_tport; |
1405 | struct tcm_vhost_tpg *tpg; | 1422 | struct tcm_vhost_tpg *tpg; |
1406 | struct vhost_virtqueue *vq; | 1423 | struct vhost_virtqueue *vq; |
@@ -1449,6 +1466,13 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs, | |||
1449 | vs->vs_tpg[target] = NULL; | 1466 | vs->vs_tpg[target] = NULL; |
1450 | match = true; | 1467 | match = true; |
1451 | mutex_unlock(&tpg->tv_tpg_mutex); | 1468 | mutex_unlock(&tpg->tv_tpg_mutex); |
1469 | /* | ||
1470 | * Release se_tpg->tpg_group.cg_item configfs dependency now | ||
1471 | * to allow vhost-scsi WWPN se_tpg->tpg_group shutdown to occur. | ||
1472 | */ | ||
1473 | se_tpg = &tpg->se_tpg; | ||
1474 | configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys, | ||
1475 | &se_tpg->tpg_group.cg_item); | ||
1452 | } | 1476 | } |
1453 | if (match) { | 1477 | if (match) { |
1454 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { | 1478 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { |
diff --git a/fs/Makefile b/fs/Makefile index 34a1b9dea6dd..da0bbb456d3f 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -104,7 +104,7 @@ obj-$(CONFIG_QNX6FS_FS) += qnx6/ | |||
104 | obj-$(CONFIG_AUTOFS4_FS) += autofs4/ | 104 | obj-$(CONFIG_AUTOFS4_FS) += autofs4/ |
105 | obj-$(CONFIG_ADFS_FS) += adfs/ | 105 | obj-$(CONFIG_ADFS_FS) += adfs/ |
106 | obj-$(CONFIG_FUSE_FS) += fuse/ | 106 | obj-$(CONFIG_FUSE_FS) += fuse/ |
107 | obj-$(CONFIG_OVERLAYFS_FS) += overlayfs/ | 107 | obj-$(CONFIG_OVERLAY_FS) += overlayfs/ |
108 | obj-$(CONFIG_UDF_FS) += udf/ | 108 | obj-$(CONFIG_UDF_FS) += udf/ |
109 | obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ | 109 | obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ |
110 | obj-$(CONFIG_OMFS_FS) += omfs/ | 110 | obj-$(CONFIG_OMFS_FS) += omfs/ |
@@ -165,6 +165,15 @@ static struct vfsmount *aio_mnt; | |||
165 | static const struct file_operations aio_ring_fops; | 165 | static const struct file_operations aio_ring_fops; |
166 | static const struct address_space_operations aio_ctx_aops; | 166 | static const struct address_space_operations aio_ctx_aops; |
167 | 167 | ||
168 | /* Backing dev info for aio fs. | ||
169 | * -no dirty page accounting or writeback happens | ||
170 | */ | ||
171 | static struct backing_dev_info aio_fs_backing_dev_info = { | ||
172 | .name = "aiofs", | ||
173 | .state = 0, | ||
174 | .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_MAP_COPY, | ||
175 | }; | ||
176 | |||
168 | static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | 177 | static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) |
169 | { | 178 | { |
170 | struct qstr this = QSTR_INIT("[aio]", 5); | 179 | struct qstr this = QSTR_INIT("[aio]", 5); |
@@ -176,6 +185,7 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | |||
176 | 185 | ||
177 | inode->i_mapping->a_ops = &aio_ctx_aops; | 186 | inode->i_mapping->a_ops = &aio_ctx_aops; |
178 | inode->i_mapping->private_data = ctx; | 187 | inode->i_mapping->private_data = ctx; |
188 | inode->i_mapping->backing_dev_info = &aio_fs_backing_dev_info; | ||
179 | inode->i_size = PAGE_SIZE * nr_pages; | 189 | inode->i_size = PAGE_SIZE * nr_pages; |
180 | 190 | ||
181 | path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this); | 191 | path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this); |
@@ -220,6 +230,9 @@ static int __init aio_setup(void) | |||
220 | if (IS_ERR(aio_mnt)) | 230 | if (IS_ERR(aio_mnt)) |
221 | panic("Failed to create aio fs mount."); | 231 | panic("Failed to create aio fs mount."); |
222 | 232 | ||
233 | if (bdi_init(&aio_fs_backing_dev_info)) | ||
234 | panic("Failed to init aio fs backing dev info."); | ||
235 | |||
223 | kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC); | 236 | kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
224 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); | 237 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
225 | 238 | ||
@@ -281,11 +294,6 @@ static const struct file_operations aio_ring_fops = { | |||
281 | .mmap = aio_ring_mmap, | 294 | .mmap = aio_ring_mmap, |
282 | }; | 295 | }; |
283 | 296 | ||
284 | static int aio_set_page_dirty(struct page *page) | ||
285 | { | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | #if IS_ENABLED(CONFIG_MIGRATION) | 297 | #if IS_ENABLED(CONFIG_MIGRATION) |
290 | static int aio_migratepage(struct address_space *mapping, struct page *new, | 298 | static int aio_migratepage(struct address_space *mapping, struct page *new, |
291 | struct page *old, enum migrate_mode mode) | 299 | struct page *old, enum migrate_mode mode) |
@@ -357,7 +365,7 @@ out: | |||
357 | #endif | 365 | #endif |
358 | 366 | ||
359 | static const struct address_space_operations aio_ctx_aops = { | 367 | static const struct address_space_operations aio_ctx_aops = { |
360 | .set_page_dirty = aio_set_page_dirty, | 368 | .set_page_dirty = __set_page_dirty_no_writeback, |
361 | #if IS_ENABLED(CONFIG_MIGRATION) | 369 | #if IS_ENABLED(CONFIG_MIGRATION) |
362 | .migratepage = aio_migratepage, | 370 | .migratepage = aio_migratepage, |
363 | #endif | 371 | #endif |
@@ -412,7 +420,6 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
412 | pr_debug("pid(%d) page[%d]->count=%d\n", | 420 | pr_debug("pid(%d) page[%d]->count=%d\n", |
413 | current->pid, i, page_count(page)); | 421 | current->pid, i, page_count(page)); |
414 | SetPageUptodate(page); | 422 | SetPageUptodate(page); |
415 | SetPageDirty(page); | ||
416 | unlock_page(page); | 423 | unlock_page(page); |
417 | 424 | ||
418 | ctx->ring_pages[i] = page; | 425 | ctx->ring_pages[i] = page; |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index d3220d31d3cb..dcd9be32ac57 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -1011,8 +1011,6 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, | |||
1011 | bytes = min(bytes, working_bytes); | 1011 | bytes = min(bytes, working_bytes); |
1012 | kaddr = kmap_atomic(page_out); | 1012 | kaddr = kmap_atomic(page_out); |
1013 | memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); | 1013 | memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); |
1014 | if (*pg_index == (vcnt - 1) && *pg_offset == 0) | ||
1015 | memset(kaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); | ||
1016 | kunmap_atomic(kaddr); | 1014 | kunmap_atomic(kaddr); |
1017 | flush_dcache_page(page_out); | 1015 | flush_dcache_page(page_out); |
1018 | 1016 | ||
@@ -1054,3 +1052,34 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, | |||
1054 | 1052 | ||
1055 | return 1; | 1053 | return 1; |
1056 | } | 1054 | } |
1055 | |||
1056 | /* | ||
1057 | * When uncompressing data, we need to make sure and zero any parts of | ||
1058 | * the biovec that were not filled in by the decompression code. pg_index | ||
1059 | * and pg_offset indicate the last page and the last offset of that page | ||
1060 | * that have been filled in. This will zero everything remaining in the | ||
1061 | * biovec. | ||
1062 | */ | ||
1063 | void btrfs_clear_biovec_end(struct bio_vec *bvec, int vcnt, | ||
1064 | unsigned long pg_index, | ||
1065 | unsigned long pg_offset) | ||
1066 | { | ||
1067 | while (pg_index < vcnt) { | ||
1068 | struct page *page = bvec[pg_index].bv_page; | ||
1069 | unsigned long off = bvec[pg_index].bv_offset; | ||
1070 | unsigned long len = bvec[pg_index].bv_len; | ||
1071 | |||
1072 | if (pg_offset < off) | ||
1073 | pg_offset = off; | ||
1074 | if (pg_offset < off + len) { | ||
1075 | unsigned long bytes = off + len - pg_offset; | ||
1076 | char *kaddr; | ||
1077 | |||
1078 | kaddr = kmap_atomic(page); | ||
1079 | memset(kaddr + pg_offset, 0, bytes); | ||
1080 | kunmap_atomic(kaddr); | ||
1081 | } | ||
1082 | pg_index++; | ||
1083 | pg_offset = 0; | ||
1084 | } | ||
1085 | } | ||
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 0c803b4fbf93..d181f70caae0 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h | |||
@@ -45,7 +45,9 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, | |||
45 | unsigned long nr_pages); | 45 | unsigned long nr_pages); |
46 | int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | 46 | int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, |
47 | int mirror_num, unsigned long bio_flags); | 47 | int mirror_num, unsigned long bio_flags); |
48 | 48 | void btrfs_clear_biovec_end(struct bio_vec *bvec, int vcnt, | |
49 | unsigned long pg_index, | ||
50 | unsigned long pg_offset); | ||
49 | struct btrfs_compress_op { | 51 | struct btrfs_compress_op { |
50 | struct list_head *(*alloc_workspace)(void); | 52 | struct list_head *(*alloc_workspace)(void); |
51 | 53 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 19bc6162fb8e..150822ee0a0b 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -80,13 +80,6 @@ noinline void btrfs_clear_path_blocking(struct btrfs_path *p, | |||
80 | { | 80 | { |
81 | int i; | 81 | int i; |
82 | 82 | ||
83 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
84 | /* lockdep really cares that we take all of these spinlocks | ||
85 | * in the right order. If any of the locks in the path are not | ||
86 | * currently blocking, it is going to complain. So, make really | ||
87 | * really sure by forcing the path to blocking before we clear | ||
88 | * the path blocking. | ||
89 | */ | ||
90 | if (held) { | 83 | if (held) { |
91 | btrfs_set_lock_blocking_rw(held, held_rw); | 84 | btrfs_set_lock_blocking_rw(held, held_rw); |
92 | if (held_rw == BTRFS_WRITE_LOCK) | 85 | if (held_rw == BTRFS_WRITE_LOCK) |
@@ -95,7 +88,6 @@ noinline void btrfs_clear_path_blocking(struct btrfs_path *p, | |||
95 | held_rw = BTRFS_READ_LOCK_BLOCKING; | 88 | held_rw = BTRFS_READ_LOCK_BLOCKING; |
96 | } | 89 | } |
97 | btrfs_set_path_blocking(p); | 90 | btrfs_set_path_blocking(p); |
98 | #endif | ||
99 | 91 | ||
100 | for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) { | 92 | for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) { |
101 | if (p->nodes[i] && p->locks[i]) { | 93 | if (p->nodes[i] && p->locks[i]) { |
@@ -107,10 +99,8 @@ noinline void btrfs_clear_path_blocking(struct btrfs_path *p, | |||
107 | } | 99 | } |
108 | } | 100 | } |
109 | 101 | ||
110 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
111 | if (held) | 102 | if (held) |
112 | btrfs_clear_lock_blocking_rw(held, held_rw); | 103 | btrfs_clear_lock_blocking_rw(held, held_rw); |
113 | #endif | ||
114 | } | 104 | } |
115 | 105 | ||
116 | /* this also releases the path */ | 106 | /* this also releases the path */ |
@@ -2893,7 +2883,7 @@ cow_done: | |||
2893 | } | 2883 | } |
2894 | p->locks[level] = BTRFS_WRITE_LOCK; | 2884 | p->locks[level] = BTRFS_WRITE_LOCK; |
2895 | } else { | 2885 | } else { |
2896 | err = btrfs_try_tree_read_lock(b); | 2886 | err = btrfs_tree_read_lock_atomic(b); |
2897 | if (!err) { | 2887 | if (!err) { |
2898 | btrfs_set_path_blocking(p); | 2888 | btrfs_set_path_blocking(p); |
2899 | btrfs_tree_read_lock(b); | 2889 | btrfs_tree_read_lock(b); |
@@ -3025,7 +3015,7 @@ again: | |||
3025 | } | 3015 | } |
3026 | 3016 | ||
3027 | level = btrfs_header_level(b); | 3017 | level = btrfs_header_level(b); |
3028 | err = btrfs_try_tree_read_lock(b); | 3018 | err = btrfs_tree_read_lock_atomic(b); |
3029 | if (!err) { | 3019 | if (!err) { |
3030 | btrfs_set_path_blocking(p); | 3020 | btrfs_set_path_blocking(p); |
3031 | btrfs_tree_read_lock(b); | 3021 | btrfs_tree_read_lock(b); |
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 5665d2149249..f8229ef1b46d 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
@@ -128,6 +128,26 @@ again: | |||
128 | } | 128 | } |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * take a spinning read lock. | ||
132 | * returns 1 if we get the read lock and 0 if we don't | ||
133 | * this won't wait for blocking writers | ||
134 | */ | ||
135 | int btrfs_tree_read_lock_atomic(struct extent_buffer *eb) | ||
136 | { | ||
137 | if (atomic_read(&eb->blocking_writers)) | ||
138 | return 0; | ||
139 | |||
140 | read_lock(&eb->lock); | ||
141 | if (atomic_read(&eb->blocking_writers)) { | ||
142 | read_unlock(&eb->lock); | ||
143 | return 0; | ||
144 | } | ||
145 | atomic_inc(&eb->read_locks); | ||
146 | atomic_inc(&eb->spinning_readers); | ||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | /* | ||
131 | * returns 1 if we get the read lock and 0 if we don't | 151 | * returns 1 if we get the read lock and 0 if we don't |
132 | * this won't wait for blocking writers | 152 | * this won't wait for blocking writers |
133 | */ | 153 | */ |
@@ -158,9 +178,7 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) | |||
158 | atomic_read(&eb->blocking_readers)) | 178 | atomic_read(&eb->blocking_readers)) |
159 | return 0; | 179 | return 0; |
160 | 180 | ||
161 | if (!write_trylock(&eb->lock)) | 181 | write_lock(&eb->lock); |
162 | return 0; | ||
163 | |||
164 | if (atomic_read(&eb->blocking_writers) || | 182 | if (atomic_read(&eb->blocking_writers) || |
165 | atomic_read(&eb->blocking_readers)) { | 183 | atomic_read(&eb->blocking_readers)) { |
166 | write_unlock(&eb->lock); | 184 | write_unlock(&eb->lock); |
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index b81e0e9a4894..c44a9d5f5362 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h | |||
@@ -35,6 +35,8 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw); | |||
35 | void btrfs_assert_tree_locked(struct extent_buffer *eb); | 35 | void btrfs_assert_tree_locked(struct extent_buffer *eb); |
36 | int btrfs_try_tree_read_lock(struct extent_buffer *eb); | 36 | int btrfs_try_tree_read_lock(struct extent_buffer *eb); |
37 | int btrfs_try_tree_write_lock(struct extent_buffer *eb); | 37 | int btrfs_try_tree_write_lock(struct extent_buffer *eb); |
38 | int btrfs_tree_read_lock_atomic(struct extent_buffer *eb); | ||
39 | |||
38 | 40 | ||
39 | static inline void btrfs_tree_unlock_rw(struct extent_buffer *eb, int rw) | 41 | static inline void btrfs_tree_unlock_rw(struct extent_buffer *eb, int rw) |
40 | { | 42 | { |
diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 78285f30909e..617553cdb7d3 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c | |||
@@ -373,6 +373,8 @@ cont: | |||
373 | } | 373 | } |
374 | done: | 374 | done: |
375 | kunmap(pages_in[page_in_index]); | 375 | kunmap(pages_in[page_in_index]); |
376 | if (!ret) | ||
377 | btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset); | ||
376 | return ret; | 378 | return ret; |
377 | } | 379 | } |
378 | 380 | ||
@@ -410,10 +412,23 @@ static int lzo_decompress(struct list_head *ws, unsigned char *data_in, | |||
410 | goto out; | 412 | goto out; |
411 | } | 413 | } |
412 | 414 | ||
415 | /* | ||
416 | * the caller is already checking against PAGE_SIZE, but lets | ||
417 | * move this check closer to the memcpy/memset | ||
418 | */ | ||
419 | destlen = min_t(unsigned long, destlen, PAGE_SIZE); | ||
413 | bytes = min_t(unsigned long, destlen, out_len - start_byte); | 420 | bytes = min_t(unsigned long, destlen, out_len - start_byte); |
414 | 421 | ||
415 | kaddr = kmap_atomic(dest_page); | 422 | kaddr = kmap_atomic(dest_page); |
416 | memcpy(kaddr, workspace->buf + start_byte, bytes); | 423 | memcpy(kaddr, workspace->buf + start_byte, bytes); |
424 | |||
425 | /* | ||
426 | * btrfs_getblock is doing a zero on the tail of the page too, | ||
427 | * but this will cover anything missing from the decompressed | ||
428 | * data. | ||
429 | */ | ||
430 | if (bytes < destlen) | ||
431 | memset(kaddr+bytes, 0, destlen-bytes); | ||
417 | kunmap_atomic(kaddr); | 432 | kunmap_atomic(kaddr); |
418 | out: | 433 | out: |
419 | return ret; | 434 | return ret; |
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 759fa4e2de8f..fb22fd8d8fb8 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c | |||
@@ -299,6 +299,8 @@ done: | |||
299 | zlib_inflateEnd(&workspace->strm); | 299 | zlib_inflateEnd(&workspace->strm); |
300 | if (data_in) | 300 | if (data_in) |
301 | kunmap(pages_in[page_in_index]); | 301 | kunmap(pages_in[page_in_index]); |
302 | if (!ret) | ||
303 | btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset); | ||
302 | return ret; | 304 | return ret; |
303 | } | 305 | } |
304 | 306 | ||
@@ -310,10 +312,14 @@ static int zlib_decompress(struct list_head *ws, unsigned char *data_in, | |||
310 | struct workspace *workspace = list_entry(ws, struct workspace, list); | 312 | struct workspace *workspace = list_entry(ws, struct workspace, list); |
311 | int ret = 0; | 313 | int ret = 0; |
312 | int wbits = MAX_WBITS; | 314 | int wbits = MAX_WBITS; |
313 | unsigned long bytes_left = destlen; | 315 | unsigned long bytes_left; |
314 | unsigned long total_out = 0; | 316 | unsigned long total_out = 0; |
317 | unsigned long pg_offset = 0; | ||
315 | char *kaddr; | 318 | char *kaddr; |
316 | 319 | ||
320 | destlen = min_t(unsigned long, destlen, PAGE_SIZE); | ||
321 | bytes_left = destlen; | ||
322 | |||
317 | workspace->strm.next_in = data_in; | 323 | workspace->strm.next_in = data_in; |
318 | workspace->strm.avail_in = srclen; | 324 | workspace->strm.avail_in = srclen; |
319 | workspace->strm.total_in = 0; | 325 | workspace->strm.total_in = 0; |
@@ -341,7 +347,6 @@ static int zlib_decompress(struct list_head *ws, unsigned char *data_in, | |||
341 | unsigned long buf_start; | 347 | unsigned long buf_start; |
342 | unsigned long buf_offset; | 348 | unsigned long buf_offset; |
343 | unsigned long bytes; | 349 | unsigned long bytes; |
344 | unsigned long pg_offset = 0; | ||
345 | 350 | ||
346 | ret = zlib_inflate(&workspace->strm, Z_NO_FLUSH); | 351 | ret = zlib_inflate(&workspace->strm, Z_NO_FLUSH); |
347 | if (ret != Z_OK && ret != Z_STREAM_END) | 352 | if (ret != Z_OK && ret != Z_STREAM_END) |
@@ -384,6 +389,17 @@ next: | |||
384 | ret = 0; | 389 | ret = 0; |
385 | 390 | ||
386 | zlib_inflateEnd(&workspace->strm); | 391 | zlib_inflateEnd(&workspace->strm); |
392 | |||
393 | /* | ||
394 | * this should only happen if zlib returned fewer bytes than we | ||
395 | * expected. btrfs_get_block is responsible for zeroing from the | ||
396 | * end of the inline extent (destlen) to the end of the page | ||
397 | */ | ||
398 | if (pg_offset < destlen) { | ||
399 | kaddr = kmap_atomic(dest_page); | ||
400 | memset(kaddr + pg_offset, 0, destlen - pg_offset); | ||
401 | kunmap_atomic(kaddr); | ||
402 | } | ||
387 | return ret; | 403 | return ret; |
388 | } | 404 | } |
389 | 405 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index 3ffef7f4e5cd..5bc72b07fde2 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -778,6 +778,7 @@ restart: | |||
778 | struct dentry *parent = lock_parent(dentry); | 778 | struct dentry *parent = lock_parent(dentry); |
779 | if (likely(!dentry->d_lockref.count)) { | 779 | if (likely(!dentry->d_lockref.count)) { |
780 | __dentry_kill(dentry); | 780 | __dentry_kill(dentry); |
781 | dput(parent); | ||
781 | goto restart; | 782 | goto restart; |
782 | } | 783 | } |
783 | if (parent) | 784 | if (parent) |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index fe839b915116..d67a16f2a45d 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -174,27 +174,6 @@ struct iso9660_options{ | |||
174 | * Compute the hash for the isofs name corresponding to the dentry. | 174 | * Compute the hash for the isofs name corresponding to the dentry. |
175 | */ | 175 | */ |
176 | static int | 176 | static int |
177 | isofs_hash_common(struct qstr *qstr, int ms) | ||
178 | { | ||
179 | const char *name; | ||
180 | int len; | ||
181 | |||
182 | len = qstr->len; | ||
183 | name = qstr->name; | ||
184 | if (ms) { | ||
185 | while (len && name[len-1] == '.') | ||
186 | len--; | ||
187 | } | ||
188 | |||
189 | qstr->hash = full_name_hash(name, len); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Compute the hash for the isofs name corresponding to the dentry. | ||
196 | */ | ||
197 | static int | ||
198 | isofs_hashi_common(struct qstr *qstr, int ms) | 177 | isofs_hashi_common(struct qstr *qstr, int ms) |
199 | { | 178 | { |
200 | const char *name; | 179 | const char *name; |
@@ -263,6 +242,27 @@ isofs_dentry_cmpi(const struct dentry *parent, const struct dentry *dentry, | |||
263 | } | 242 | } |
264 | 243 | ||
265 | #ifdef CONFIG_JOLIET | 244 | #ifdef CONFIG_JOLIET |
245 | /* | ||
246 | * Compute the hash for the isofs name corresponding to the dentry. | ||
247 | */ | ||
248 | static int | ||
249 | isofs_hash_common(struct qstr *qstr, int ms) | ||
250 | { | ||
251 | const char *name; | ||
252 | int len; | ||
253 | |||
254 | len = qstr->len; | ||
255 | name = qstr->name; | ||
256 | if (ms) { | ||
257 | while (len && name[len-1] == '.') | ||
258 | len--; | ||
259 | } | ||
260 | |||
261 | qstr->hash = full_name_hash(name, len); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int | 266 | static int |
267 | isofs_hash_ms(const struct dentry *dentry, struct qstr *qstr) | 267 | isofs_hash_ms(const struct dentry *dentry, struct qstr *qstr) |
268 | { | 268 | { |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index ed2b1151b171..7cbdf1b2e4ab 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -774,8 +774,12 @@ static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task) | |||
774 | { | 774 | { |
775 | if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { | 775 | if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { |
776 | rpc_sleep_on(&clp->cl_cb_waitq, task, NULL); | 776 | rpc_sleep_on(&clp->cl_cb_waitq, task, NULL); |
777 | dprintk("%s slot is busy\n", __func__); | 777 | /* Race breaker */ |
778 | return false; | 778 | if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { |
779 | dprintk("%s slot is busy\n", __func__); | ||
780 | return false; | ||
781 | } | ||
782 | rpc_wake_up_queued_task(&clp->cl_cb_waitq, task); | ||
779 | } | 783 | } |
780 | return true; | 784 | return true; |
781 | } | 785 | } |
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 747f3b95bd11..33a46a8dfaf7 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h | |||
@@ -335,12 +335,15 @@ void nfsd_lockd_shutdown(void); | |||
335 | (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) | 335 | (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) |
336 | 336 | ||
337 | #ifdef CONFIG_NFSD_V4_SECURITY_LABEL | 337 | #ifdef CONFIG_NFSD_V4_SECURITY_LABEL |
338 | #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ | 338 | #define NFSD4_2_SECURITY_ATTRS FATTR4_WORD2_SECURITY_LABEL |
339 | (NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL) | ||
340 | #else | 339 | #else |
341 | #define NFSD4_2_SUPPORTED_ATTRS_WORD2 0 | 340 | #define NFSD4_2_SECURITY_ATTRS 0 |
342 | #endif | 341 | #endif |
343 | 342 | ||
343 | #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ | ||
344 | (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ | ||
345 | NFSD4_2_SECURITY_ATTRS) | ||
346 | |||
344 | static inline u32 nfsd_suppattrs0(u32 minorversion) | 347 | static inline u32 nfsd_suppattrs0(u32 minorversion) |
345 | { | 348 | { |
346 | return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 | 349 | return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 |
diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig index e60125976873..34355818a2e0 100644 --- a/fs/overlayfs/Kconfig +++ b/fs/overlayfs/Kconfig | |||
@@ -1,4 +1,4 @@ | |||
1 | config OVERLAYFS_FS | 1 | config OVERLAY_FS |
2 | tristate "Overlay filesystem support" | 2 | tristate "Overlay filesystem support" |
3 | help | 3 | help |
4 | An overlay filesystem combines two filesystems - an 'upper' filesystem | 4 | An overlay filesystem combines two filesystems - an 'upper' filesystem |
diff --git a/fs/overlayfs/Makefile b/fs/overlayfs/Makefile index 8f91889480d0..900daed3e91d 100644 --- a/fs/overlayfs/Makefile +++ b/fs/overlayfs/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for the overlay filesystem. | 2 | # Makefile for the overlay filesystem. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_OVERLAYFS_FS) += overlayfs.o | 5 | obj-$(CONFIG_OVERLAY_FS) += overlay.o |
6 | 6 | ||
7 | overlayfs-objs := super.o inode.o dir.o readdir.o copy_up.o | 7 | overlay-objs := super.o inode.o dir.o readdir.o copy_up.o |
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 15cd91ad9940..8ffc4b980f1b 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c | |||
@@ -284,8 +284,7 @@ out: | |||
284 | return ERR_PTR(err); | 284 | return ERR_PTR(err); |
285 | } | 285 | } |
286 | 286 | ||
287 | static struct dentry *ovl_check_empty_and_clear(struct dentry *dentry, | 287 | static struct dentry *ovl_check_empty_and_clear(struct dentry *dentry) |
288 | enum ovl_path_type type) | ||
289 | { | 288 | { |
290 | int err; | 289 | int err; |
291 | struct dentry *ret = NULL; | 290 | struct dentry *ret = NULL; |
@@ -294,8 +293,17 @@ static struct dentry *ovl_check_empty_and_clear(struct dentry *dentry, | |||
294 | err = ovl_check_empty_dir(dentry, &list); | 293 | err = ovl_check_empty_dir(dentry, &list); |
295 | if (err) | 294 | if (err) |
296 | ret = ERR_PTR(err); | 295 | ret = ERR_PTR(err); |
297 | else if (type == OVL_PATH_MERGE) | 296 | else { |
298 | ret = ovl_clear_empty(dentry, &list); | 297 | /* |
298 | * If no upperdentry then skip clearing whiteouts. | ||
299 | * | ||
300 | * Can race with copy-up, since we don't hold the upperdir | ||
301 | * mutex. Doesn't matter, since copy-up can't create a | ||
302 | * non-empty directory from an empty one. | ||
303 | */ | ||
304 | if (ovl_dentry_upper(dentry)) | ||
305 | ret = ovl_clear_empty(dentry, &list); | ||
306 | } | ||
299 | 307 | ||
300 | ovl_cache_free(&list); | 308 | ovl_cache_free(&list); |
301 | 309 | ||
@@ -487,8 +495,7 @@ out: | |||
487 | return err; | 495 | return err; |
488 | } | 496 | } |
489 | 497 | ||
490 | static int ovl_remove_and_whiteout(struct dentry *dentry, | 498 | static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) |
491 | enum ovl_path_type type, bool is_dir) | ||
492 | { | 499 | { |
493 | struct dentry *workdir = ovl_workdir(dentry); | 500 | struct dentry *workdir = ovl_workdir(dentry); |
494 | struct inode *wdir = workdir->d_inode; | 501 | struct inode *wdir = workdir->d_inode; |
@@ -500,7 +507,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, | |||
500 | int err; | 507 | int err; |
501 | 508 | ||
502 | if (is_dir) { | 509 | if (is_dir) { |
503 | opaquedir = ovl_check_empty_and_clear(dentry, type); | 510 | opaquedir = ovl_check_empty_and_clear(dentry); |
504 | err = PTR_ERR(opaquedir); | 511 | err = PTR_ERR(opaquedir); |
505 | if (IS_ERR(opaquedir)) | 512 | if (IS_ERR(opaquedir)) |
506 | goto out; | 513 | goto out; |
@@ -515,9 +522,10 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, | |||
515 | if (IS_ERR(whiteout)) | 522 | if (IS_ERR(whiteout)) |
516 | goto out_unlock; | 523 | goto out_unlock; |
517 | 524 | ||
518 | if (type == OVL_PATH_LOWER) { | 525 | upper = ovl_dentry_upper(dentry); |
526 | if (!upper) { | ||
519 | upper = lookup_one_len(dentry->d_name.name, upperdir, | 527 | upper = lookup_one_len(dentry->d_name.name, upperdir, |
520 | dentry->d_name.len); | 528 | dentry->d_name.len); |
521 | err = PTR_ERR(upper); | 529 | err = PTR_ERR(upper); |
522 | if (IS_ERR(upper)) | 530 | if (IS_ERR(upper)) |
523 | goto kill_whiteout; | 531 | goto kill_whiteout; |
@@ -529,7 +537,6 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, | |||
529 | } else { | 537 | } else { |
530 | int flags = 0; | 538 | int flags = 0; |
531 | 539 | ||
532 | upper = ovl_dentry_upper(dentry); | ||
533 | if (opaquedir) | 540 | if (opaquedir) |
534 | upper = opaquedir; | 541 | upper = opaquedir; |
535 | err = -ESTALE; | 542 | err = -ESTALE; |
@@ -648,7 +655,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) | |||
648 | cap_raise(override_cred->cap_effective, CAP_CHOWN); | 655 | cap_raise(override_cred->cap_effective, CAP_CHOWN); |
649 | old_cred = override_creds(override_cred); | 656 | old_cred = override_creds(override_cred); |
650 | 657 | ||
651 | err = ovl_remove_and_whiteout(dentry, type, is_dir); | 658 | err = ovl_remove_and_whiteout(dentry, is_dir); |
652 | 659 | ||
653 | revert_creds(old_cred); | 660 | revert_creds(old_cred); |
654 | put_cred(override_cred); | 661 | put_cred(override_cred); |
@@ -781,7 +788,7 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, | |||
781 | } | 788 | } |
782 | 789 | ||
783 | if (overwrite && (new_type == OVL_PATH_LOWER || new_type == OVL_PATH_MERGE) && new_is_dir) { | 790 | if (overwrite && (new_type == OVL_PATH_LOWER || new_type == OVL_PATH_MERGE) && new_is_dir) { |
784 | opaquedir = ovl_check_empty_and_clear(new, new_type); | 791 | opaquedir = ovl_check_empty_and_clear(new); |
785 | err = PTR_ERR(opaquedir); | 792 | err = PTR_ERR(opaquedir); |
786 | if (IS_ERR(opaquedir)) { | 793 | if (IS_ERR(opaquedir)) { |
787 | opaquedir = NULL; | 794 | opaquedir = NULL; |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index af2d18c9fcee..07d74b24913b 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -235,26 +235,36 @@ out: | |||
235 | return err; | 235 | return err; |
236 | } | 236 | } |
237 | 237 | ||
238 | static bool ovl_need_xattr_filter(struct dentry *dentry, | ||
239 | enum ovl_path_type type) | ||
240 | { | ||
241 | return type == OVL_PATH_UPPER && S_ISDIR(dentry->d_inode->i_mode); | ||
242 | } | ||
243 | |||
238 | ssize_t ovl_getxattr(struct dentry *dentry, const char *name, | 244 | ssize_t ovl_getxattr(struct dentry *dentry, const char *name, |
239 | void *value, size_t size) | 245 | void *value, size_t size) |
240 | { | 246 | { |
241 | if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE && | 247 | struct path realpath; |
242 | ovl_is_private_xattr(name)) | 248 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); |
249 | |||
250 | if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) | ||
243 | return -ENODATA; | 251 | return -ENODATA; |
244 | 252 | ||
245 | return vfs_getxattr(ovl_dentry_real(dentry), name, value, size); | 253 | return vfs_getxattr(realpath.dentry, name, value, size); |
246 | } | 254 | } |
247 | 255 | ||
248 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) | 256 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) |
249 | { | 257 | { |
258 | struct path realpath; | ||
259 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); | ||
250 | ssize_t res; | 260 | ssize_t res; |
251 | int off; | 261 | int off; |
252 | 262 | ||
253 | res = vfs_listxattr(ovl_dentry_real(dentry), list, size); | 263 | res = vfs_listxattr(realpath.dentry, list, size); |
254 | if (res <= 0 || size == 0) | 264 | if (res <= 0 || size == 0) |
255 | return res; | 265 | return res; |
256 | 266 | ||
257 | if (ovl_path_type(dentry->d_parent) != OVL_PATH_MERGE) | 267 | if (!ovl_need_xattr_filter(dentry, type)) |
258 | return res; | 268 | return res; |
259 | 269 | ||
260 | /* filter out private xattrs */ | 270 | /* filter out private xattrs */ |
@@ -279,17 +289,16 @@ int ovl_removexattr(struct dentry *dentry, const char *name) | |||
279 | { | 289 | { |
280 | int err; | 290 | int err; |
281 | struct path realpath; | 291 | struct path realpath; |
282 | enum ovl_path_type type; | 292 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); |
283 | 293 | ||
284 | err = ovl_want_write(dentry); | 294 | err = ovl_want_write(dentry); |
285 | if (err) | 295 | if (err) |
286 | goto out; | 296 | goto out; |
287 | 297 | ||
288 | if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE && | 298 | err = -ENODATA; |
289 | ovl_is_private_xattr(name)) | 299 | if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) |
290 | goto out_drop_write; | 300 | goto out_drop_write; |
291 | 301 | ||
292 | type = ovl_path_real(dentry, &realpath); | ||
293 | if (type == OVL_PATH_LOWER) { | 302 | if (type == OVL_PATH_LOWER) { |
294 | err = vfs_getxattr(realpath.dentry, name, NULL, 0); | 303 | err = vfs_getxattr(realpath.dentry, name, NULL, 0); |
295 | if (err < 0) | 304 | if (err < 0) |
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 2a7ef4f8e2a6..ab1e3dcbed95 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c | |||
@@ -274,11 +274,11 @@ static int ovl_dir_mark_whiteouts(struct dentry *dir, | |||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
277 | static inline int ovl_dir_read_merged(struct path *upperpath, | 277 | static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list) |
278 | struct path *lowerpath, | ||
279 | struct list_head *list) | ||
280 | { | 278 | { |
281 | int err; | 279 | int err; |
280 | struct path lowerpath; | ||
281 | struct path upperpath; | ||
282 | struct ovl_readdir_data rdd = { | 282 | struct ovl_readdir_data rdd = { |
283 | .ctx.actor = ovl_fill_merge, | 283 | .ctx.actor = ovl_fill_merge, |
284 | .list = list, | 284 | .list = list, |
@@ -286,25 +286,28 @@ static inline int ovl_dir_read_merged(struct path *upperpath, | |||
286 | .is_merge = false, | 286 | .is_merge = false, |
287 | }; | 287 | }; |
288 | 288 | ||
289 | if (upperpath->dentry) { | 289 | ovl_path_lower(dentry, &lowerpath); |
290 | err = ovl_dir_read(upperpath, &rdd); | 290 | ovl_path_upper(dentry, &upperpath); |
291 | |||
292 | if (upperpath.dentry) { | ||
293 | err = ovl_dir_read(&upperpath, &rdd); | ||
291 | if (err) | 294 | if (err) |
292 | goto out; | 295 | goto out; |
293 | 296 | ||
294 | if (lowerpath->dentry) { | 297 | if (lowerpath.dentry) { |
295 | err = ovl_dir_mark_whiteouts(upperpath->dentry, &rdd); | 298 | err = ovl_dir_mark_whiteouts(upperpath.dentry, &rdd); |
296 | if (err) | 299 | if (err) |
297 | goto out; | 300 | goto out; |
298 | } | 301 | } |
299 | } | 302 | } |
300 | if (lowerpath->dentry) { | 303 | if (lowerpath.dentry) { |
301 | /* | 304 | /* |
302 | * Insert lowerpath entries before upperpath ones, this allows | 305 | * Insert lowerpath entries before upperpath ones, this allows |
303 | * offsets to be reasonably constant | 306 | * offsets to be reasonably constant |
304 | */ | 307 | */ |
305 | list_add(&rdd.middle, rdd.list); | 308 | list_add(&rdd.middle, rdd.list); |
306 | rdd.is_merge = true; | 309 | rdd.is_merge = true; |
307 | err = ovl_dir_read(lowerpath, &rdd); | 310 | err = ovl_dir_read(&lowerpath, &rdd); |
308 | list_del(&rdd.middle); | 311 | list_del(&rdd.middle); |
309 | } | 312 | } |
310 | out: | 313 | out: |
@@ -329,8 +332,6 @@ static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos) | |||
329 | static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) | 332 | static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) |
330 | { | 333 | { |
331 | int res; | 334 | int res; |
332 | struct path lowerpath; | ||
333 | struct path upperpath; | ||
334 | struct ovl_dir_cache *cache; | 335 | struct ovl_dir_cache *cache; |
335 | 336 | ||
336 | cache = ovl_dir_cache(dentry); | 337 | cache = ovl_dir_cache(dentry); |
@@ -347,10 +348,7 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) | |||
347 | cache->refcount = 1; | 348 | cache->refcount = 1; |
348 | INIT_LIST_HEAD(&cache->entries); | 349 | INIT_LIST_HEAD(&cache->entries); |
349 | 350 | ||
350 | ovl_path_lower(dentry, &lowerpath); | 351 | res = ovl_dir_read_merged(dentry, &cache->entries); |
351 | ovl_path_upper(dentry, &upperpath); | ||
352 | |||
353 | res = ovl_dir_read_merged(&upperpath, &lowerpath, &cache->entries); | ||
354 | if (res) { | 352 | if (res) { |
355 | ovl_cache_free(&cache->entries); | 353 | ovl_cache_free(&cache->entries); |
356 | kfree(cache); | 354 | kfree(cache); |
@@ -452,10 +450,10 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, | |||
452 | /* | 450 | /* |
453 | * Need to check if we started out being a lower dir, but got copied up | 451 | * Need to check if we started out being a lower dir, but got copied up |
454 | */ | 452 | */ |
455 | if (!od->is_upper && ovl_path_type(dentry) == OVL_PATH_MERGE) { | 453 | if (!od->is_upper && ovl_path_type(dentry) != OVL_PATH_LOWER) { |
456 | struct inode *inode = file_inode(file); | 454 | struct inode *inode = file_inode(file); |
457 | 455 | ||
458 | realfile =lockless_dereference(od->upperfile); | 456 | realfile = lockless_dereference(od->upperfile); |
459 | if (!realfile) { | 457 | if (!realfile) { |
460 | struct path upperpath; | 458 | struct path upperpath; |
461 | 459 | ||
@@ -538,14 +536,9 @@ const struct file_operations ovl_dir_operations = { | |||
538 | int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) | 536 | int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) |
539 | { | 537 | { |
540 | int err; | 538 | int err; |
541 | struct path lowerpath; | ||
542 | struct path upperpath; | ||
543 | struct ovl_cache_entry *p; | 539 | struct ovl_cache_entry *p; |
544 | 540 | ||
545 | ovl_path_upper(dentry, &upperpath); | 541 | err = ovl_dir_read_merged(dentry, list); |
546 | ovl_path_lower(dentry, &lowerpath); | ||
547 | |||
548 | err = ovl_dir_read_merged(&upperpath, &lowerpath, list); | ||
549 | if (err) | 542 | if (err) |
550 | return err; | 543 | return err; |
551 | 544 | ||
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 08b704cebfc4..f16d318b71f8 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -24,7 +24,7 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |||
24 | MODULE_DESCRIPTION("Overlay filesystem"); | 24 | MODULE_DESCRIPTION("Overlay filesystem"); |
25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
26 | 26 | ||
27 | #define OVERLAYFS_SUPER_MAGIC 0x794c764f | 27 | #define OVERLAYFS_SUPER_MAGIC 0x794c7630 |
28 | 28 | ||
29 | struct ovl_config { | 29 | struct ovl_config { |
30 | char *lowerdir; | 30 | char *lowerdir; |
@@ -84,12 +84,7 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry) | |||
84 | 84 | ||
85 | static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) | 85 | static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) |
86 | { | 86 | { |
87 | struct dentry *upperdentry = ACCESS_ONCE(oe->__upperdentry); | 87 | return lockless_dereference(oe->__upperdentry); |
88 | /* | ||
89 | * Make sure to order reads to upperdentry wrt ovl_dentry_update() | ||
90 | */ | ||
91 | smp_read_barrier_depends(); | ||
92 | return upperdentry; | ||
93 | } | 88 | } |
94 | 89 | ||
95 | void ovl_path_upper(struct dentry *dentry, struct path *path) | 90 | void ovl_path_upper(struct dentry *dentry, struct path *path) |
@@ -462,11 +457,34 @@ static const match_table_t ovl_tokens = { | |||
462 | {OPT_ERR, NULL} | 457 | {OPT_ERR, NULL} |
463 | }; | 458 | }; |
464 | 459 | ||
460 | static char *ovl_next_opt(char **s) | ||
461 | { | ||
462 | char *sbegin = *s; | ||
463 | char *p; | ||
464 | |||
465 | if (sbegin == NULL) | ||
466 | return NULL; | ||
467 | |||
468 | for (p = sbegin; *p; p++) { | ||
469 | if (*p == '\\') { | ||
470 | p++; | ||
471 | if (!*p) | ||
472 | break; | ||
473 | } else if (*p == ',') { | ||
474 | *p = '\0'; | ||
475 | *s = p + 1; | ||
476 | return sbegin; | ||
477 | } | ||
478 | } | ||
479 | *s = NULL; | ||
480 | return sbegin; | ||
481 | } | ||
482 | |||
465 | static int ovl_parse_opt(char *opt, struct ovl_config *config) | 483 | static int ovl_parse_opt(char *opt, struct ovl_config *config) |
466 | { | 484 | { |
467 | char *p; | 485 | char *p; |
468 | 486 | ||
469 | while ((p = strsep(&opt, ",")) != NULL) { | 487 | while ((p = ovl_next_opt(&opt)) != NULL) { |
470 | int token; | 488 | int token; |
471 | substring_t args[MAX_OPT_ARGS]; | 489 | substring_t args[MAX_OPT_ARGS]; |
472 | 490 | ||
@@ -554,15 +572,34 @@ out_dput: | |||
554 | goto out_unlock; | 572 | goto out_unlock; |
555 | } | 573 | } |
556 | 574 | ||
575 | static void ovl_unescape(char *s) | ||
576 | { | ||
577 | char *d = s; | ||
578 | |||
579 | for (;; s++, d++) { | ||
580 | if (*s == '\\') | ||
581 | s++; | ||
582 | *d = *s; | ||
583 | if (!*s) | ||
584 | break; | ||
585 | } | ||
586 | } | ||
587 | |||
557 | static int ovl_mount_dir(const char *name, struct path *path) | 588 | static int ovl_mount_dir(const char *name, struct path *path) |
558 | { | 589 | { |
559 | int err; | 590 | int err; |
591 | char *tmp = kstrdup(name, GFP_KERNEL); | ||
592 | |||
593 | if (!tmp) | ||
594 | return -ENOMEM; | ||
560 | 595 | ||
561 | err = kern_path(name, LOOKUP_FOLLOW, path); | 596 | ovl_unescape(tmp); |
597 | err = kern_path(tmp, LOOKUP_FOLLOW, path); | ||
562 | if (err) { | 598 | if (err) { |
563 | pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); | 599 | pr_err("overlayfs: failed to resolve '%s': %i\n", tmp, err); |
564 | err = -EINVAL; | 600 | err = -EINVAL; |
565 | } | 601 | } |
602 | kfree(tmp); | ||
566 | return err; | 603 | return err; |
567 | } | 604 | } |
568 | 605 | ||
@@ -776,11 +813,11 @@ static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags, | |||
776 | 813 | ||
777 | static struct file_system_type ovl_fs_type = { | 814 | static struct file_system_type ovl_fs_type = { |
778 | .owner = THIS_MODULE, | 815 | .owner = THIS_MODULE, |
779 | .name = "overlayfs", | 816 | .name = "overlay", |
780 | .mount = ovl_mount, | 817 | .mount = ovl_mount, |
781 | .kill_sb = kill_anon_super, | 818 | .kill_sb = kill_anon_super, |
782 | }; | 819 | }; |
783 | MODULE_ALIAS_FS("overlayfs"); | 820 | MODULE_ALIAS_FS("overlay"); |
784 | 821 | ||
785 | static int __init ovl_init(void) | 822 | static int __init ovl_init(void) |
786 | { | 823 | { |
diff --git a/include/dt-bindings/clock/qcom,mmcc-apq8084.h b/include/dt-bindings/clock/qcom,mmcc-apq8084.h index a929f86d0ddd..d72b5b35f15e 100644 --- a/include/dt-bindings/clock/qcom,mmcc-apq8084.h +++ b/include/dt-bindings/clock/qcom,mmcc-apq8084.h | |||
@@ -60,7 +60,7 @@ | |||
60 | #define ESC1_CLK_SRC 43 | 60 | #define ESC1_CLK_SRC 43 |
61 | #define HDMI_CLK_SRC 44 | 61 | #define HDMI_CLK_SRC 44 |
62 | #define VSYNC_CLK_SRC 45 | 62 | #define VSYNC_CLK_SRC 45 |
63 | #define RBCPR_CLK_SRC 46 | 63 | #define MMSS_RBCPR_CLK_SRC 46 |
64 | #define RBBMTIMER_CLK_SRC 47 | 64 | #define RBBMTIMER_CLK_SRC 47 |
65 | #define MAPLE_CLK_SRC 48 | 65 | #define MAPLE_CLK_SRC 48 |
66 | #define VDP_CLK_SRC 49 | 66 | #define VDP_CLK_SRC 49 |
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index be5fd38bd5a0..5d858e02997f 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h | |||
@@ -18,8 +18,11 @@ | |||
18 | * position @h. For example | 18 | * position @h. For example |
19 | * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. | 19 | * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. |
20 | */ | 20 | */ |
21 | #define GENMASK(h, l) (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l)) | 21 | #define GENMASK(h, l) \ |
22 | #define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l)) | 22 | (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) |
23 | |||
24 | #define GENMASK_ULL(h, l) \ | ||
25 | (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) | ||
23 | 26 | ||
24 | extern unsigned int __sw_hweight8(unsigned int w); | 27 | extern unsigned int __sw_hweight8(unsigned int w); |
25 | extern unsigned int __sw_hweight16(unsigned int w); | 28 | extern unsigned int __sw_hweight16(unsigned int w); |
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 6992afc6ba7f..b37ea95bc348 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h | |||
@@ -99,6 +99,12 @@ inval_skb: | |||
99 | return 1; | 99 | return 1; |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline bool can_is_canfd_skb(const struct sk_buff *skb) | ||
103 | { | ||
104 | /* the CAN specific type of skb is identified by its data length */ | ||
105 | return skb->len == CANFD_MTU; | ||
106 | } | ||
107 | |||
102 | /* get data length from can_dlc with sanitized can_dlc */ | 108 | /* get data length from can_dlc with sanitized can_dlc */ |
103 | u8 can_dlc2len(u8 can_dlc); | 109 | u8 can_dlc2len(u8 can_dlc); |
104 | 110 | ||
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index be21af149f11..2839c639f092 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -352,7 +352,6 @@ struct clk_divider { | |||
352 | #define CLK_DIVIDER_READ_ONLY BIT(5) | 352 | #define CLK_DIVIDER_READ_ONLY BIT(5) |
353 | 353 | ||
354 | extern const struct clk_ops clk_divider_ops; | 354 | extern const struct clk_ops clk_divider_ops; |
355 | extern const struct clk_ops clk_divider_ro_ops; | ||
356 | struct clk *clk_register_divider(struct device *dev, const char *name, | 355 | struct clk *clk_register_divider(struct device *dev, const char *name, |
357 | const char *parent_name, unsigned long flags, | 356 | const char *parent_name, unsigned long flags, |
358 | void __iomem *reg, u8 shift, u8 width, | 357 | void __iomem *reg, u8 shift, u8 width, |
diff --git a/include/linux/iio/events.h b/include/linux/iio/events.h index 8bbd7bc1043d..03fa332ad2a8 100644 --- a/include/linux/iio/events.h +++ b/include/linux/iio/events.h | |||
@@ -72,7 +72,7 @@ struct iio_event_data { | |||
72 | 72 | ||
73 | #define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) | 73 | #define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) |
74 | 74 | ||
75 | #define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF) | 75 | #define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F) |
76 | 76 | ||
77 | #define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) | 77 | #define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) |
78 | 78 | ||
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 0068708161ff..0a21fbefdfbe 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h | |||
@@ -242,7 +242,7 @@ static inline void in_dev_put(struct in_device *idev) | |||
242 | static __inline__ __be32 inet_make_mask(int logmask) | 242 | static __inline__ __be32 inet_make_mask(int logmask) |
243 | { | 243 | { |
244 | if (logmask) | 244 | if (logmask) |
245 | return htonl(~((1<<(32-logmask))-1)); | 245 | return htonl(~((1U<<(32-logmask))-1)); |
246 | return 0; | 246 | return 0; |
247 | } | 247 | } |
248 | 248 | ||
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 8422b4ed6882..b9376cd5a187 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h | |||
@@ -77,11 +77,6 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu) | |||
77 | return kstat_cpu(cpu).irqs_sum; | 77 | return kstat_cpu(cpu).irqs_sum; |
78 | } | 78 | } |
79 | 79 | ||
80 | /* | ||
81 | * Lock/unlock the current runqueue - to extract task statistics: | ||
82 | */ | ||
83 | extern unsigned long long task_delta_exec(struct task_struct *); | ||
84 | |||
85 | extern void account_user_time(struct task_struct *, cputime_t, cputime_t); | 80 | extern void account_user_time(struct task_struct *, cputime_t, cputime_t); |
86 | extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t); | 81 | extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t); |
87 | extern void account_steal_time(cputime_t); | 82 | extern void account_steal_time(cputime_t); |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ea53b04993f2..a6059bdf7b03 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -703,7 +703,7 @@ void kvm_arch_sync_events(struct kvm *kvm); | |||
703 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); | 703 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); |
704 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu); | 704 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu); |
705 | 705 | ||
706 | bool kvm_is_mmio_pfn(pfn_t pfn); | 706 | bool kvm_is_reserved_pfn(pfn_t pfn); |
707 | 707 | ||
708 | struct kvm_irq_ack_notifier { | 708 | struct kvm_irq_ack_notifier { |
709 | struct hlist_node link; | 709 | struct hlist_node link; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 5be8db45e368..4c8ac5fcc224 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -331,6 +331,7 @@ struct pci_dev { | |||
331 | unsigned int is_added:1; | 331 | unsigned int is_added:1; |
332 | unsigned int is_busmaster:1; /* device is busmaster */ | 332 | unsigned int is_busmaster:1; /* device is busmaster */ |
333 | unsigned int no_msi:1; /* device may not use msi */ | 333 | unsigned int no_msi:1; /* device may not use msi */ |
334 | unsigned int no_64bit_msi:1; /* device may only use 32-bit MSIs */ | ||
334 | unsigned int block_cfg_access:1; /* config space access is blocked */ | 335 | unsigned int block_cfg_access:1; /* config space access is blocked */ |
335 | unsigned int broken_parity_status:1; /* Device generates false positive parity */ | 336 | unsigned int broken_parity_status:1; /* Device generates false positive parity */ |
336 | unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */ | 337 | unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */ |
diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index d5c89e0dd0e6..51ce60c35f4c 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h | |||
@@ -133,7 +133,13 @@ static inline bool __ref_is_percpu(struct percpu_ref *ref, | |||
133 | /* paired with smp_store_release() in percpu_ref_reinit() */ | 133 | /* paired with smp_store_release() in percpu_ref_reinit() */ |
134 | smp_read_barrier_depends(); | 134 | smp_read_barrier_depends(); |
135 | 135 | ||
136 | if (unlikely(percpu_ptr & __PERCPU_REF_ATOMIC)) | 136 | /* |
137 | * Theoretically, the following could test just ATOMIC; however, | ||
138 | * then we'd have to mask off DEAD separately as DEAD may be | ||
139 | * visible without ATOMIC if we race with percpu_ref_kill(). DEAD | ||
140 | * implies ATOMIC anyway. Test them together. | ||
141 | */ | ||
142 | if (unlikely(percpu_ptr & __PERCPU_REF_ATOMIC_DEAD)) | ||
137 | return false; | 143 | return false; |
138 | 144 | ||
139 | *percpu_countp = (unsigned long __percpu *)percpu_ptr; | 145 | *percpu_countp = (unsigned long __percpu *)percpu_ptr; |
diff --git a/include/net/inet_common.h b/include/net/inet_common.h index fe7994c48b75..b2828a06a5a6 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h | |||
@@ -37,6 +37,8 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); | |||
37 | int inet_ctl_sock_create(struct sock **sk, unsigned short family, | 37 | int inet_ctl_sock_create(struct sock **sk, unsigned short family, |
38 | unsigned short type, unsigned char protocol, | 38 | unsigned short type, unsigned char protocol, |
39 | struct net *net); | 39 | struct net *net); |
40 | int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, | ||
41 | int *addr_len); | ||
40 | 42 | ||
41 | static inline void inet_ctl_sock_destroy(struct sock *sk) | 43 | static inline void inet_ctl_sock_destroy(struct sock *sk) |
42 | { | 44 | { |
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 845c596bf594..3ae969e3acf0 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h | |||
@@ -396,14 +396,12 @@ struct nft_rule { | |||
396 | /** | 396 | /** |
397 | * struct nft_trans - nf_tables object update in transaction | 397 | * struct nft_trans - nf_tables object update in transaction |
398 | * | 398 | * |
399 | * @rcu_head: rcu head to defer release of transaction data | ||
400 | * @list: used internally | 399 | * @list: used internally |
401 | * @msg_type: message type | 400 | * @msg_type: message type |
402 | * @ctx: transaction context | 401 | * @ctx: transaction context |
403 | * @data: internal information related to the transaction | 402 | * @data: internal information related to the transaction |
404 | */ | 403 | */ |
405 | struct nft_trans { | 404 | struct nft_trans { |
406 | struct rcu_head rcu_head; | ||
407 | struct list_head list; | 405 | struct list_head list; |
408 | int msg_type; | 406 | int msg_type; |
409 | struct nft_ctx ctx; | 407 | struct nft_ctx ctx; |
diff --git a/include/net/vxlan.h b/include/net/vxlan.h index d5f59f3fc35d..57cccd0052e5 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h | |||
@@ -8,6 +8,12 @@ | |||
8 | #define VNI_HASH_BITS 10 | 8 | #define VNI_HASH_BITS 10 |
9 | #define VNI_HASH_SIZE (1<<VNI_HASH_BITS) | 9 | #define VNI_HASH_SIZE (1<<VNI_HASH_BITS) |
10 | 10 | ||
11 | /* VXLAN protocol header */ | ||
12 | struct vxlanhdr { | ||
13 | __be32 vx_flags; | ||
14 | __be32 vx_vni; | ||
15 | }; | ||
16 | |||
11 | struct vxlan_sock; | 17 | struct vxlan_sock; |
12 | typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key); | 18 | typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key); |
13 | 19 | ||
@@ -45,6 +51,18 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
45 | __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, | 51 | __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, |
46 | __be16 src_port, __be16 dst_port, __be32 vni, bool xnet); | 52 | __be16 src_port, __be16 dst_port, __be32 vni, bool xnet); |
47 | 53 | ||
54 | static inline bool vxlan_gso_check(struct sk_buff *skb) | ||
55 | { | ||
56 | if ((skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) && | ||
57 | (skb->inner_protocol_type != ENCAP_TYPE_ETHER || | ||
58 | skb->inner_protocol != htons(ETH_P_TEB) || | ||
59 | (skb_inner_mac_header(skb) - skb_transport_header(skb) != | ||
60 | sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) | ||
61 | return false; | ||
62 | |||
63 | return true; | ||
64 | } | ||
65 | |||
48 | /* IP header + UDP + VXLAN + Ethernet header */ | 66 | /* IP header + UDP + VXLAN + Ethernet header */ |
49 | #define VXLAN_HEADROOM (20 + 8 + 8 + 14) | 67 | #define VXLAN_HEADROOM (20 + 8 + 8 + 14) |
50 | /* IPv6 header + UDP + VXLAN + Ethernet header */ | 68 | /* IPv6 header + UDP + VXLAN + Ethernet header */ |
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index ae6c3b8ed2f5..396e8f73670a 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h | |||
@@ -42,12 +42,11 @@ struct snd_compr_ops; | |||
42 | * @buffer_size: size of the above buffer | 42 | * @buffer_size: size of the above buffer |
43 | * @fragment_size: size of buffer fragment in bytes | 43 | * @fragment_size: size of buffer fragment in bytes |
44 | * @fragments: number of such fragments | 44 | * @fragments: number of such fragments |
45 | * @hw_pointer: offset of last location in buffer where DSP copied data | ||
46 | * @app_pointer: offset of last location in buffer where app wrote data | ||
47 | * @total_bytes_available: cumulative number of bytes made available in | 45 | * @total_bytes_available: cumulative number of bytes made available in |
48 | * the ring buffer | 46 | * the ring buffer |
49 | * @total_bytes_transferred: cumulative bytes transferred by offload DSP | 47 | * @total_bytes_transferred: cumulative bytes transferred by offload DSP |
50 | * @sleep: poll sleep | 48 | * @sleep: poll sleep |
49 | * @private_data: driver private data pointer | ||
51 | */ | 50 | */ |
52 | struct snd_compr_runtime { | 51 | struct snd_compr_runtime { |
53 | snd_pcm_state_t state; | 52 | snd_pcm_state_t state; |
@@ -94,6 +93,8 @@ struct snd_compr_stream { | |||
94 | * This can be called in during stream creation only to set codec params | 93 | * This can be called in during stream creation only to set codec params |
95 | * and the stream properties | 94 | * and the stream properties |
96 | * @get_params: retrieve the codec parameters, mandatory | 95 | * @get_params: retrieve the codec parameters, mandatory |
96 | * @set_metadata: Set the metadata values for a stream | ||
97 | * @get_metadata: retreives the requested metadata values from stream | ||
97 | * @trigger: Trigger operations like start, pause, resume, drain, stop. | 98 | * @trigger: Trigger operations like start, pause, resume, drain, stop. |
98 | * This callback is mandatory | 99 | * This callback is mandatory |
99 | * @pointer: Retrieve current h/w pointer information. Mandatory | 100 | * @pointer: Retrieve current h/w pointer information. Mandatory |
diff --git a/include/sound/jack.h b/include/sound/jack.h index 58916573db58..67f2bbcd515e 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h | |||
@@ -28,8 +28,23 @@ | |||
28 | struct input_dev; | 28 | struct input_dev; |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * Jack types which can be reported. These values are used as a | 31 | * enum snd_jack_types - Jack types which can be reported |
32 | * bitmask. | 32 | * @SND_JACK_HEADPHONE: Headphone |
33 | * @SND_JACK_MICROPHONE: Microphone | ||
34 | * @SND_JACK_HEADSET: Headset | ||
35 | * @SND_JACK_LINEOUT: Line out | ||
36 | * @SND_JACK_MECHANICAL: Mechanical switch | ||
37 | * @SND_JACK_VIDEOOUT: Video out | ||
38 | * @SND_JACK_AVOUT: AV (Audio Video) out | ||
39 | * @SND_JACK_LINEIN: Line in | ||
40 | * @SND_JACK_BTN_0: Button 0 | ||
41 | * @SND_JACK_BTN_1: Button 1 | ||
42 | * @SND_JACK_BTN_2: Button 2 | ||
43 | * @SND_JACK_BTN_3: Button 3 | ||
44 | * @SND_JACK_BTN_4: Button 4 | ||
45 | * @SND_JACK_BTN_5: Button 5 | ||
46 | * | ||
47 | * These values are used as a bitmask. | ||
33 | * | 48 | * |
34 | * Note that this must be kept in sync with the lookup table in | 49 | * Note that this must be kept in sync with the lookup table in |
35 | * sound/core/jack.c. | 50 | * sound/core/jack.c. |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 8bb00a27e219..1e7f74acc2ec 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -418,7 +418,10 @@ struct snd_pcm_substream { | |||
418 | struct snd_info_entry *proc_status_entry; | 418 | struct snd_info_entry *proc_status_entry; |
419 | struct snd_info_entry *proc_prealloc_entry; | 419 | struct snd_info_entry *proc_prealloc_entry; |
420 | struct snd_info_entry *proc_prealloc_max_entry; | 420 | struct snd_info_entry *proc_prealloc_max_entry; |
421 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | ||
422 | struct snd_info_entry *proc_xrun_injection_entry; | ||
421 | #endif | 423 | #endif |
424 | #endif /* CONFIG_SND_VERBOSE_PROCFS */ | ||
422 | /* misc flags */ | 425 | /* misc flags */ |
423 | unsigned int hw_opened: 1; | 426 | unsigned int hw_opened: 1; |
424 | }; | 427 | }; |
@@ -505,6 +508,7 @@ int snd_pcm_status(struct snd_pcm_substream *substream, | |||
505 | int snd_pcm_start(struct snd_pcm_substream *substream); | 508 | int snd_pcm_start(struct snd_pcm_substream *substream); |
506 | int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status); | 509 | int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status); |
507 | int snd_pcm_drain_done(struct snd_pcm_substream *substream); | 510 | int snd_pcm_drain_done(struct snd_pcm_substream *substream); |
511 | int snd_pcm_stop_xrun(struct snd_pcm_substream *substream); | ||
508 | #ifdef CONFIG_PM | 512 | #ifdef CONFIG_PM |
509 | int snd_pcm_suspend(struct snd_pcm_substream *substream); | 513 | int snd_pcm_suspend(struct snd_pcm_substream *substream); |
510 | int snd_pcm_suspend_all(struct snd_pcm *pcm); | 514 | int snd_pcm_suspend_all(struct snd_pcm *pcm); |
@@ -535,6 +539,12 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size) | |||
535 | * PCM library | 539 | * PCM library |
536 | */ | 540 | */ |
537 | 541 | ||
542 | /** | ||
543 | * snd_pcm_stream_linked - Check whether the substream is linked with others | ||
544 | * @substream: substream to check | ||
545 | * | ||
546 | * Returns true if the given substream is being linked with others. | ||
547 | */ | ||
538 | static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream) | 548 | static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream) |
539 | { | 549 | { |
540 | return substream->group != &substream->self_group; | 550 | return substream->group != &substream->self_group; |
@@ -545,6 +555,16 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream); | |||
545 | void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream); | 555 | void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream); |
546 | void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream); | 556 | void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream); |
547 | unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); | 557 | unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); |
558 | |||
559 | /** | ||
560 | * snd_pcm_stream_lock_irqsave - Lock the PCM stream | ||
561 | * @substream: PCM substream | ||
562 | * @flags: irq flags | ||
563 | * | ||
564 | * This locks the PCM stream like snd_pcm_stream_lock() but with the local | ||
565 | * IRQ (only when nonatomic is false). In nonatomic case, this is identical | ||
566 | * as snd_pcm_stream_lock(). | ||
567 | */ | ||
548 | #define snd_pcm_stream_lock_irqsave(substream, flags) \ | 568 | #define snd_pcm_stream_lock_irqsave(substream, flags) \ |
549 | do { \ | 569 | do { \ |
550 | typecheck(unsigned long, flags); \ | 570 | typecheck(unsigned long, flags); \ |
@@ -553,9 +573,25 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); | |||
553 | void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, | 573 | void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, |
554 | unsigned long flags); | 574 | unsigned long flags); |
555 | 575 | ||
576 | /** | ||
577 | * snd_pcm_group_for_each_entry - iterate over the linked substreams | ||
578 | * @s: the iterator | ||
579 | * @substream: the substream | ||
580 | * | ||
581 | * Iterate over the all linked substreams to the given @substream. | ||
582 | * When @substream isn't linked with any others, this gives returns @substream | ||
583 | * itself once. | ||
584 | */ | ||
556 | #define snd_pcm_group_for_each_entry(s, substream) \ | 585 | #define snd_pcm_group_for_each_entry(s, substream) \ |
557 | list_for_each_entry(s, &substream->group->substreams, link_list) | 586 | list_for_each_entry(s, &substream->group->substreams, link_list) |
558 | 587 | ||
588 | /** | ||
589 | * snd_pcm_running - Check whether the substream is in a running state | ||
590 | * @substream: substream to check | ||
591 | * | ||
592 | * Returns true if the given substream is in the state RUNNING, or in the | ||
593 | * state DRAINING for playback. | ||
594 | */ | ||
559 | static inline int snd_pcm_running(struct snd_pcm_substream *substream) | 595 | static inline int snd_pcm_running(struct snd_pcm_substream *substream) |
560 | { | 596 | { |
561 | return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || | 597 | return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || |
@@ -563,45 +599,81 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream) | |||
563 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); | 599 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); |
564 | } | 600 | } |
565 | 601 | ||
602 | /** | ||
603 | * bytes_to_samples - Unit conversion of the size from bytes to samples | ||
604 | * @runtime: PCM runtime instance | ||
605 | * @size: size in bytes | ||
606 | */ | ||
566 | static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size) | 607 | static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size) |
567 | { | 608 | { |
568 | return size * 8 / runtime->sample_bits; | 609 | return size * 8 / runtime->sample_bits; |
569 | } | 610 | } |
570 | 611 | ||
612 | /** | ||
613 | * bytes_to_frames - Unit conversion of the size from bytes to frames | ||
614 | * @runtime: PCM runtime instance | ||
615 | * @size: size in bytes | ||
616 | */ | ||
571 | static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size) | 617 | static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size) |
572 | { | 618 | { |
573 | return size * 8 / runtime->frame_bits; | 619 | return size * 8 / runtime->frame_bits; |
574 | } | 620 | } |
575 | 621 | ||
622 | /** | ||
623 | * samples_to_bytes - Unit conversion of the size from samples to bytes | ||
624 | * @runtime: PCM runtime instance | ||
625 | * @size: size in samples | ||
626 | */ | ||
576 | static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size) | 627 | static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size) |
577 | { | 628 | { |
578 | return size * runtime->sample_bits / 8; | 629 | return size * runtime->sample_bits / 8; |
579 | } | 630 | } |
580 | 631 | ||
632 | /** | ||
633 | * frames_to_bytes - Unit conversion of the size from frames to bytes | ||
634 | * @runtime: PCM runtime instance | ||
635 | * @size: size in frames | ||
636 | */ | ||
581 | static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size) | 637 | static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size) |
582 | { | 638 | { |
583 | return size * runtime->frame_bits / 8; | 639 | return size * runtime->frame_bits / 8; |
584 | } | 640 | } |
585 | 641 | ||
642 | /** | ||
643 | * frame_aligned - Check whether the byte size is aligned to frames | ||
644 | * @runtime: PCM runtime instance | ||
645 | * @bytes: size in bytes | ||
646 | */ | ||
586 | static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes) | 647 | static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes) |
587 | { | 648 | { |
588 | return bytes % runtime->byte_align == 0; | 649 | return bytes % runtime->byte_align == 0; |
589 | } | 650 | } |
590 | 651 | ||
652 | /** | ||
653 | * snd_pcm_lib_buffer_bytes - Get the buffer size of the current PCM in bytes | ||
654 | * @substream: PCM substream | ||
655 | */ | ||
591 | static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream) | 656 | static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream) |
592 | { | 657 | { |
593 | struct snd_pcm_runtime *runtime = substream->runtime; | 658 | struct snd_pcm_runtime *runtime = substream->runtime; |
594 | return frames_to_bytes(runtime, runtime->buffer_size); | 659 | return frames_to_bytes(runtime, runtime->buffer_size); |
595 | } | 660 | } |
596 | 661 | ||
662 | /** | ||
663 | * snd_pcm_lib_period_bytes - Get the period size of the current PCM in bytes | ||
664 | * @substream: PCM substream | ||
665 | */ | ||
597 | static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream) | 666 | static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream) |
598 | { | 667 | { |
599 | struct snd_pcm_runtime *runtime = substream->runtime; | 668 | struct snd_pcm_runtime *runtime = substream->runtime; |
600 | return frames_to_bytes(runtime, runtime->period_size); | 669 | return frames_to_bytes(runtime, runtime->period_size); |
601 | } | 670 | } |
602 | 671 | ||
603 | /* | 672 | /** |
604 | * result is: 0 ... (boundary - 1) | 673 | * snd_pcm_playback_avail - Get the available (writable) space for playback |
674 | * @runtime: PCM runtime instance | ||
675 | * | ||
676 | * Result is between 0 ... (boundary - 1) | ||
605 | */ | 677 | */ |
606 | static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime) | 678 | static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime) |
607 | { | 679 | { |
@@ -613,8 +685,11 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r | |||
613 | return avail; | 685 | return avail; |
614 | } | 686 | } |
615 | 687 | ||
616 | /* | 688 | /** |
617 | * result is: 0 ... (boundary - 1) | 689 | * snd_pcm_playback_avail - Get the available (readable) space for capture |
690 | * @runtime: PCM runtime instance | ||
691 | * | ||
692 | * Result is between 0 ... (boundary - 1) | ||
618 | */ | 693 | */ |
619 | static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime) | 694 | static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime) |
620 | { | 695 | { |
@@ -624,11 +699,19 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru | |||
624 | return avail; | 699 | return avail; |
625 | } | 700 | } |
626 | 701 | ||
702 | /** | ||
703 | * snd_pcm_playback_hw_avail - Get the queued space for playback | ||
704 | * @runtime: PCM runtime instance | ||
705 | */ | ||
627 | static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime) | 706 | static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime) |
628 | { | 707 | { |
629 | return runtime->buffer_size - snd_pcm_playback_avail(runtime); | 708 | return runtime->buffer_size - snd_pcm_playback_avail(runtime); |
630 | } | 709 | } |
631 | 710 | ||
711 | /** | ||
712 | * snd_pcm_capture_hw_avail - Get the free space for capture | ||
713 | * @runtime: PCM runtime instance | ||
714 | */ | ||
632 | static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime) | 715 | static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime) |
633 | { | 716 | { |
634 | return runtime->buffer_size - snd_pcm_capture_avail(runtime); | 717 | return runtime->buffer_size - snd_pcm_capture_avail(runtime); |
@@ -708,6 +791,20 @@ static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream) | |||
708 | return snd_pcm_capture_avail(runtime) == 0; | 791 | return snd_pcm_capture_avail(runtime) == 0; |
709 | } | 792 | } |
710 | 793 | ||
794 | /** | ||
795 | * snd_pcm_trigger_done - Mark the master substream | ||
796 | * @substream: the pcm substream instance | ||
797 | * @master: the linked master substream | ||
798 | * | ||
799 | * When multiple substreams of the same card are linked and the hardware | ||
800 | * supports the single-shot operation, the driver calls this in the loop | ||
801 | * in snd_pcm_group_for_each_entry() for marking the substream as "done". | ||
802 | * Then most of trigger operations are performed only to the given master | ||
803 | * substream. | ||
804 | * | ||
805 | * The trigger_master mark is cleared at timestamp updates at the end | ||
806 | * of trigger operations. | ||
807 | */ | ||
711 | static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream, | 808 | static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream, |
712 | struct snd_pcm_substream *master) | 809 | struct snd_pcm_substream *master) |
713 | { | 810 | { |
@@ -750,18 +847,59 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc | |||
750 | return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]; | 847 | return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]; |
751 | } | 848 | } |
752 | 849 | ||
753 | #define params_channels(p) \ | 850 | /** |
754 | (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min) | 851 | * params_channels - Get the number of channels from the hw params |
755 | #define params_rate(p) \ | 852 | * @p: hw params |
756 | (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_RATE)->min) | 853 | */ |
757 | #define params_period_size(p) \ | 854 | static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) |
758 | (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min) | 855 | { |
759 | #define params_periods(p) \ | 856 | return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min; |
760 | (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIODS)->min) | 857 | } |
761 | #define params_buffer_size(p) \ | 858 | |
762 | (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min) | 859 | /** |
763 | #define params_buffer_bytes(p) \ | 860 | * params_channels - Get the sample rate from the hw params |
764 | (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min) | 861 | * @p: hw params |
862 | */ | ||
863 | static inline unsigned int params_rate(const struct snd_pcm_hw_params *p) | ||
864 | { | ||
865 | return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_RATE)->min; | ||
866 | } | ||
867 | |||
868 | /** | ||
869 | * params_channels - Get the period size (in frames) from the hw params | ||
870 | * @p: hw params | ||
871 | */ | ||
872 | static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p) | ||
873 | { | ||
874 | return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min; | ||
875 | } | ||
876 | |||
877 | /** | ||
878 | * params_channels - Get the number of periods from the hw params | ||
879 | * @p: hw params | ||
880 | */ | ||
881 | static inline unsigned int params_periods(const struct snd_pcm_hw_params *p) | ||
882 | { | ||
883 | return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIODS)->min; | ||
884 | } | ||
885 | |||
886 | /** | ||
887 | * params_channels - Get the buffer size (in frames) from the hw params | ||
888 | * @p: hw params | ||
889 | */ | ||
890 | static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p) | ||
891 | { | ||
892 | return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min; | ||
893 | } | ||
894 | |||
895 | /** | ||
896 | * params_channels - Get the buffer size (in bytes) from the hw params | ||
897 | * @p: hw params | ||
898 | */ | ||
899 | static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p) | ||
900 | { | ||
901 | return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min; | ||
902 | } | ||
765 | 903 | ||
766 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v); | 904 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v); |
767 | void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); | 905 | void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); |
@@ -883,6 +1021,14 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); | |||
883 | unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, | 1021 | unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, |
884 | unsigned int rates_b); | 1022 | unsigned int rates_b); |
885 | 1023 | ||
1024 | /** | ||
1025 | * snd_pcm_set_runtime_buffer - Set the PCM runtime buffer | ||
1026 | * @substream: PCM substream to set | ||
1027 | * @bufp: the buffer information, NULL to clear | ||
1028 | * | ||
1029 | * Copy the buffer information to runtime->dma_buffer when @bufp is non-NULL. | ||
1030 | * Otherwise it clears the current buffer information. | ||
1031 | */ | ||
886 | static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, | 1032 | static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, |
887 | struct snd_dma_buffer *bufp) | 1033 | struct snd_dma_buffer *bufp) |
888 | { | 1034 | { |
@@ -908,6 +1054,11 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); | |||
908 | void snd_pcm_timer_init(struct snd_pcm_substream *substream); | 1054 | void snd_pcm_timer_init(struct snd_pcm_substream *substream); |
909 | void snd_pcm_timer_done(struct snd_pcm_substream *substream); | 1055 | void snd_pcm_timer_done(struct snd_pcm_substream *substream); |
910 | 1056 | ||
1057 | /** | ||
1058 | * snd_pcm_gettime - Fill the timespec depending on the timestamp mode | ||
1059 | * @runtime: PCM runtime instance | ||
1060 | * @tv: timespec to fill | ||
1061 | */ | ||
911 | static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime, | 1062 | static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime, |
912 | struct timespec *tv) | 1063 | struct timespec *tv) |
913 | { | 1064 | { |
@@ -944,7 +1095,6 @@ int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, | |||
944 | int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream); | 1095 | int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream); |
945 | struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, | 1096 | struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, |
946 | unsigned long offset); | 1097 | unsigned long offset); |
947 | #if 0 /* for kernel-doc */ | ||
948 | /** | 1098 | /** |
949 | * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer | 1099 | * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer |
950 | * @substream: the substream to allocate the buffer to | 1100 | * @substream: the substream to allocate the buffer to |
@@ -957,8 +1107,13 @@ struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, | |||
957 | * Return: 1 if the buffer was changed, 0 if not changed, or a negative error | 1107 | * Return: 1 if the buffer was changed, 0 if not changed, or a negative error |
958 | * code. | 1108 | * code. |
959 | */ | 1109 | */ |
960 | static int snd_pcm_lib_alloc_vmalloc_buffer | 1110 | static inline int snd_pcm_lib_alloc_vmalloc_buffer |
961 | (struct snd_pcm_substream *substream, size_t size); | 1111 | (struct snd_pcm_substream *substream, size_t size) |
1112 | { | ||
1113 | return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size, | ||
1114 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); | ||
1115 | } | ||
1116 | |||
962 | /** | 1117 | /** |
963 | * snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer | 1118 | * snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer |
964 | * @substream: the substream to allocate the buffer to | 1119 | * @substream: the substream to allocate the buffer to |
@@ -970,15 +1125,12 @@ static int snd_pcm_lib_alloc_vmalloc_buffer | |||
970 | * Return: 1 if the buffer was changed, 0 if not changed, or a negative error | 1125 | * Return: 1 if the buffer was changed, 0 if not changed, or a negative error |
971 | * code. | 1126 | * code. |
972 | */ | 1127 | */ |
973 | static int snd_pcm_lib_alloc_vmalloc_32_buffer | 1128 | static inline int snd_pcm_lib_alloc_vmalloc_32_buffer |
974 | (struct snd_pcm_substream *substream, size_t size); | 1129 | (struct snd_pcm_substream *substream, size_t size) |
975 | #endif | 1130 | { |
976 | #define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \ | 1131 | return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size, |
977 | _snd_pcm_lib_alloc_vmalloc_buffer \ | 1132 | GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); |
978 | (subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO) | 1133 | } |
979 | #define snd_pcm_lib_alloc_vmalloc_32_buffer(subs, size) \ | ||
980 | _snd_pcm_lib_alloc_vmalloc_buffer \ | ||
981 | (subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO) | ||
982 | 1134 | ||
983 | #define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) | 1135 | #define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) |
984 | 1136 | ||
@@ -998,18 +1150,35 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, | |||
998 | #define snd_pcm_sgbuf_ops_page NULL | 1150 | #define snd_pcm_sgbuf_ops_page NULL |
999 | #endif /* SND_DMA_SGBUF */ | 1151 | #endif /* SND_DMA_SGBUF */ |
1000 | 1152 | ||
1153 | /** | ||
1154 | * snd_pcm_sgbuf_get_addr - Get the DMA address at the corresponding offset | ||
1155 | * @substream: PCM substream | ||
1156 | * @ofs: byte offset | ||
1157 | */ | ||
1001 | static inline dma_addr_t | 1158 | static inline dma_addr_t |
1002 | snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) | 1159 | snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) |
1003 | { | 1160 | { |
1004 | return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs); | 1161 | return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs); |
1005 | } | 1162 | } |
1006 | 1163 | ||
1164 | /** | ||
1165 | * snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset | ||
1166 | * @substream: PCM substream | ||
1167 | * @ofs: byte offset | ||
1168 | */ | ||
1007 | static inline void * | 1169 | static inline void * |
1008 | snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs) | 1170 | snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs) |
1009 | { | 1171 | { |
1010 | return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs); | 1172 | return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs); |
1011 | } | 1173 | } |
1012 | 1174 | ||
1175 | /** | ||
1176 | * snd_pcm_sgbuf_chunk_size - Compute the max size that fits within the contig. | ||
1177 | * page from the given size | ||
1178 | * @substream: PCM substream | ||
1179 | * @ofs: byte offset | ||
1180 | * @size: byte size to examine | ||
1181 | */ | ||
1013 | static inline unsigned int | 1182 | static inline unsigned int |
1014 | snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, | 1183 | snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, |
1015 | unsigned int ofs, unsigned int size) | 1184 | unsigned int ofs, unsigned int size) |
@@ -1017,13 +1186,24 @@ snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, | |||
1017 | return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size); | 1186 | return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size); |
1018 | } | 1187 | } |
1019 | 1188 | ||
1020 | /* handle mmap counter - PCM mmap callback should handle this counter properly */ | 1189 | /** |
1190 | * snd_pcm_mmap_data_open - increase the mmap counter | ||
1191 | * @area: VMA | ||
1192 | * | ||
1193 | * PCM mmap callback should handle this counter properly | ||
1194 | */ | ||
1021 | static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) | 1195 | static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) |
1022 | { | 1196 | { |
1023 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; | 1197 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; |
1024 | atomic_inc(&substream->mmap_count); | 1198 | atomic_inc(&substream->mmap_count); |
1025 | } | 1199 | } |
1026 | 1200 | ||
1201 | /** | ||
1202 | * snd_pcm_mmap_data_close - decrease the mmap counter | ||
1203 | * @area: VMA | ||
1204 | * | ||
1205 | * PCM mmap callback should handle this counter properly | ||
1206 | */ | ||
1027 | static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) | 1207 | static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) |
1028 | { | 1208 | { |
1029 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; | 1209 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; |
@@ -1043,6 +1223,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s | |||
1043 | 1223 | ||
1044 | #define snd_pcm_lib_mmap_vmalloc NULL | 1224 | #define snd_pcm_lib_mmap_vmalloc NULL |
1045 | 1225 | ||
1226 | /** | ||
1227 | * snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer | ||
1228 | * @dma: DMA number | ||
1229 | * @max: pointer to store the max size | ||
1230 | */ | ||
1046 | static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) | 1231 | static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) |
1047 | { | 1232 | { |
1048 | *max = dma < 4 ? 64 * 1024 : 128 * 1024; | 1233 | *max = dma < 4 ? 64 * 1024 : 128 * 1024; |
@@ -1095,7 +1280,11 @@ struct snd_pcm_chmap { | |||
1095 | void *private_data; /* optional: private data pointer */ | 1280 | void *private_data; /* optional: private data pointer */ |
1096 | }; | 1281 | }; |
1097 | 1282 | ||
1098 | /* get the PCM substream assigned to the given chmap info */ | 1283 | /** |
1284 | * snd_pcm_chmap_substream - get the PCM substream assigned to the given chmap info | ||
1285 | * @info: chmap information | ||
1286 | * @idx: the substream number index | ||
1287 | */ | ||
1099 | static inline struct snd_pcm_substream * | 1288 | static inline struct snd_pcm_substream * |
1100 | snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) | 1289 | snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) |
1101 | { | 1290 | { |
@@ -1122,7 +1311,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, | |||
1122 | unsigned long private_value, | 1311 | unsigned long private_value, |
1123 | struct snd_pcm_chmap **info_ret); | 1312 | struct snd_pcm_chmap **info_ret); |
1124 | 1313 | ||
1125 | /* Strong-typed conversion of pcm_format to bitwise */ | 1314 | /** |
1315 | * pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise | ||
1316 | * @pcm_format: PCM format | ||
1317 | */ | ||
1126 | static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) | 1318 | static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) |
1127 | { | 1319 | { |
1128 | return 1ULL << (__force int) pcm_format; | 1320 | return 1ULL << (__force int) pcm_format; |
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h index 2398521f0998..eea5400fe373 100644 --- a/include/sound/seq_kernel.h +++ b/include/sound/seq_kernel.h | |||
@@ -108,9 +108,13 @@ int snd_seq_event_port_detach(int client, int port); | |||
108 | #ifdef CONFIG_MODULES | 108 | #ifdef CONFIG_MODULES |
109 | void snd_seq_autoload_lock(void); | 109 | void snd_seq_autoload_lock(void); |
110 | void snd_seq_autoload_unlock(void); | 110 | void snd_seq_autoload_unlock(void); |
111 | void snd_seq_autoload_init(void); | ||
112 | #define snd_seq_autoload_exit() snd_seq_autoload_lock() | ||
111 | #else | 113 | #else |
112 | #define snd_seq_autoload_lock() | 114 | #define snd_seq_autoload_lock() |
113 | #define snd_seq_autoload_unlock() | 115 | #define snd_seq_autoload_unlock() |
116 | #define snd_seq_autoload_init() | ||
117 | #define snd_seq_autoload_exit() | ||
114 | #endif | 118 | #endif |
115 | 119 | ||
116 | #endif /* __SOUND_SEQ_KERNEL_H */ | 120 | #endif /* __SOUND_SEQ_KERNEL_H */ |
diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/compress_offload.h index 1964026b5e09..22ed8cb7800b 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2) | 33 | #define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2) |
34 | /** | 34 | /** |
35 | * struct snd_compressed_buffer: compressed buffer | 35 | * struct snd_compressed_buffer - compressed buffer |
36 | * @fragment_size: size of buffer fragment in bytes | 36 | * @fragment_size: size of buffer fragment in bytes |
37 | * @fragments: number of such fragments | 37 | * @fragments: number of such fragments |
38 | */ | 38 | */ |
@@ -42,7 +42,7 @@ struct snd_compressed_buffer { | |||
42 | } __attribute__((packed, aligned(4))); | 42 | } __attribute__((packed, aligned(4))); |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * struct snd_compr_params: compressed stream params | 45 | * struct snd_compr_params - compressed stream params |
46 | * @buffer: buffer description | 46 | * @buffer: buffer description |
47 | * @codec: codec parameters | 47 | * @codec: codec parameters |
48 | * @no_wake_mode: dont wake on fragment elapsed | 48 | * @no_wake_mode: dont wake on fragment elapsed |
@@ -54,7 +54,7 @@ struct snd_compr_params { | |||
54 | } __attribute__((packed, aligned(4))); | 54 | } __attribute__((packed, aligned(4))); |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * struct snd_compr_tstamp: timestamp descriptor | 57 | * struct snd_compr_tstamp - timestamp descriptor |
58 | * @byte_offset: Byte offset in ring buffer to DSP | 58 | * @byte_offset: Byte offset in ring buffer to DSP |
59 | * @copied_total: Total number of bytes copied from/to ring buffer to/by DSP | 59 | * @copied_total: Total number of bytes copied from/to ring buffer to/by DSP |
60 | * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by | 60 | * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by |
@@ -73,7 +73,7 @@ struct snd_compr_tstamp { | |||
73 | } __attribute__((packed, aligned(4))); | 73 | } __attribute__((packed, aligned(4))); |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * struct snd_compr_avail: avail descriptor | 76 | * struct snd_compr_avail - avail descriptor |
77 | * @avail: Number of bytes available in ring buffer for writing/reading | 77 | * @avail: Number of bytes available in ring buffer for writing/reading |
78 | * @tstamp: timestamp infomation | 78 | * @tstamp: timestamp infomation |
79 | */ | 79 | */ |
@@ -88,7 +88,7 @@ enum snd_compr_direction { | |||
88 | }; | 88 | }; |
89 | 89 | ||
90 | /** | 90 | /** |
91 | * struct snd_compr_caps: caps descriptor | 91 | * struct snd_compr_caps - caps descriptor |
92 | * @codecs: pointer to array of codecs | 92 | * @codecs: pointer to array of codecs |
93 | * @direction: direction supported. Of type snd_compr_direction | 93 | * @direction: direction supported. Of type snd_compr_direction |
94 | * @min_fragment_size: minimum fragment supported by DSP | 94 | * @min_fragment_size: minimum fragment supported by DSP |
@@ -110,7 +110,7 @@ struct snd_compr_caps { | |||
110 | } __attribute__((packed, aligned(4))); | 110 | } __attribute__((packed, aligned(4))); |
111 | 111 | ||
112 | /** | 112 | /** |
113 | * struct snd_compr_codec_caps: query capability of codec | 113 | * struct snd_compr_codec_caps - query capability of codec |
114 | * @codec: codec for which capability is queried | 114 | * @codec: codec for which capability is queried |
115 | * @num_descriptors: number of codec descriptors | 115 | * @num_descriptors: number of codec descriptors |
116 | * @descriptor: array of codec capability descriptor | 116 | * @descriptor: array of codec capability descriptor |
@@ -122,18 +122,19 @@ struct snd_compr_codec_caps { | |||
122 | } __attribute__((packed, aligned(4))); | 122 | } __attribute__((packed, aligned(4))); |
123 | 123 | ||
124 | /** | 124 | /** |
125 | * enum sndrv_compress_encoder | ||
125 | * @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the | 126 | * @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the |
126 | * end of the track | 127 | * end of the track |
127 | * @SNDRV_COMPRESS_ENCODER_DELAY: no of samples inserted by the encoder at the | 128 | * @SNDRV_COMPRESS_ENCODER_DELAY: no of samples inserted by the encoder at the |
128 | * beginning of the track | 129 | * beginning of the track |
129 | */ | 130 | */ |
130 | enum { | 131 | enum sndrv_compress_encoder { |
131 | SNDRV_COMPRESS_ENCODER_PADDING = 1, | 132 | SNDRV_COMPRESS_ENCODER_PADDING = 1, |
132 | SNDRV_COMPRESS_ENCODER_DELAY = 2, | 133 | SNDRV_COMPRESS_ENCODER_DELAY = 2, |
133 | }; | 134 | }; |
134 | 135 | ||
135 | /** | 136 | /** |
136 | * struct snd_compr_metadata: compressed stream metadata | 137 | * struct snd_compr_metadata - compressed stream metadata |
137 | * @key: key id | 138 | * @key: key id |
138 | * @value: key value | 139 | * @value: key value |
139 | */ | 140 | */ |
diff --git a/include/uapi/sound/hdspm.h b/include/uapi/sound/hdspm.h index d956c3593f65..b357f1a5e29c 100644 --- a/include/uapi/sound/hdspm.h +++ b/include/uapi/sound/hdspm.h | |||
@@ -74,14 +74,14 @@ struct hdspm_config { | |||
74 | #define SNDRV_HDSPM_IOCTL_GET_CONFIG \ | 74 | #define SNDRV_HDSPM_IOCTL_GET_CONFIG \ |
75 | _IOR('H', 0x41, struct hdspm_config) | 75 | _IOR('H', 0x41, struct hdspm_config) |
76 | 76 | ||
77 | /** | 77 | /* |
78 | * If there's a TCO (TimeCode Option) board installed, | 78 | * If there's a TCO (TimeCode Option) board installed, |
79 | * there are further options and status data available. | 79 | * there are further options and status data available. |
80 | * The hdspm_ltc structure contains the current SMPTE | 80 | * The hdspm_ltc structure contains the current SMPTE |
81 | * timecode and some status information and can be | 81 | * timecode and some status information and can be |
82 | * obtained via SNDRV_HDSPM_IOCTL_GET_LTC or in the | 82 | * obtained via SNDRV_HDSPM_IOCTL_GET_LTC or in the |
83 | * hdspm_status struct. | 83 | * hdspm_status struct. |
84 | **/ | 84 | */ |
85 | 85 | ||
86 | enum hdspm_ltc_format { | 86 | enum hdspm_ltc_format { |
87 | format_invalid, | 87 | format_invalid, |
@@ -113,11 +113,11 @@ struct hdspm_ltc { | |||
113 | 113 | ||
114 | #define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc) | 114 | #define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc) |
115 | 115 | ||
116 | /** | 116 | /* |
117 | * The status data reflects the device's current state | 117 | * The status data reflects the device's current state |
118 | * as determined by the card's configuration and | 118 | * as determined by the card's configuration and |
119 | * connection status. | 119 | * connection status. |
120 | **/ | 120 | */ |
121 | 121 | ||
122 | enum hdspm_sync { | 122 | enum hdspm_sync { |
123 | hdspm_sync_no_lock = 0, | 123 | hdspm_sync_no_lock = 0, |
@@ -171,9 +171,9 @@ struct hdspm_status { | |||
171 | #define SNDRV_HDSPM_IOCTL_GET_STATUS \ | 171 | #define SNDRV_HDSPM_IOCTL_GET_STATUS \ |
172 | _IOR('H', 0x47, struct hdspm_status) | 172 | _IOR('H', 0x47, struct hdspm_status) |
173 | 173 | ||
174 | /** | 174 | /* |
175 | * Get information about the card and its add-ons. | 175 | * Get information about the card and its add-ons. |
176 | **/ | 176 | */ |
177 | 177 | ||
178 | #define HDSPM_ADDON_TCO 1 | 178 | #define HDSPM_ADDON_TCO 1 |
179 | 179 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index 2b02c9fda790..1cd5eef1fcdd 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -1562,8 +1562,10 @@ static void perf_remove_from_context(struct perf_event *event, bool detach_group | |||
1562 | 1562 | ||
1563 | if (!task) { | 1563 | if (!task) { |
1564 | /* | 1564 | /* |
1565 | * Per cpu events are removed via an smp call and | 1565 | * Per cpu events are removed via an smp call. The removal can |
1566 | * the removal is always successful. | 1566 | * fail if the CPU is currently offline, but in that case we |
1567 | * already called __perf_remove_from_context from | ||
1568 | * perf_event_exit_cpu. | ||
1567 | */ | 1569 | */ |
1568 | cpu_function_call(event->cpu, __perf_remove_from_context, &re); | 1570 | cpu_function_call(event->cpu, __perf_remove_from_context, &re); |
1569 | return; | 1571 | return; |
@@ -8117,7 +8119,7 @@ static void perf_pmu_rotate_stop(struct pmu *pmu) | |||
8117 | 8119 | ||
8118 | static void __perf_event_exit_context(void *__info) | 8120 | static void __perf_event_exit_context(void *__info) |
8119 | { | 8121 | { |
8120 | struct remove_event re = { .detach_group = false }; | 8122 | struct remove_event re = { .detach_group = true }; |
8121 | struct perf_event_context *ctx = __info; | 8123 | struct perf_event_context *ctx = __info; |
8122 | 8124 | ||
8123 | perf_pmu_rotate_stop(ctx->pmu); | 8125 | perf_pmu_rotate_stop(ctx->pmu); |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 1d0af8a2c646..ed8f2cde34c5 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1640,7 +1640,6 @@ bool uprobe_deny_signal(void) | |||
1640 | if (__fatal_signal_pending(t) || arch_uprobe_xol_was_trapped(t)) { | 1640 | if (__fatal_signal_pending(t) || arch_uprobe_xol_was_trapped(t)) { |
1641 | utask->state = UTASK_SSTEP_TRAPPED; | 1641 | utask->state = UTASK_SSTEP_TRAPPED; |
1642 | set_tsk_thread_flag(t, TIF_UPROBE); | 1642 | set_tsk_thread_flag(t, TIF_UPROBE); |
1643 | set_tsk_thread_flag(t, TIF_NOTIFY_RESUME); | ||
1644 | } | 1643 | } |
1645 | } | 1644 | } |
1646 | 1645 | ||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 240157c13ddc..24beb9bb4c3e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2475,44 +2475,6 @@ EXPORT_PER_CPU_SYMBOL(kstat); | |||
2475 | EXPORT_PER_CPU_SYMBOL(kernel_cpustat); | 2475 | EXPORT_PER_CPU_SYMBOL(kernel_cpustat); |
2476 | 2476 | ||
2477 | /* | 2477 | /* |
2478 | * Return any ns on the sched_clock that have not yet been accounted in | ||
2479 | * @p in case that task is currently running. | ||
2480 | * | ||
2481 | * Called with task_rq_lock() held on @rq. | ||
2482 | */ | ||
2483 | static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq) | ||
2484 | { | ||
2485 | u64 ns = 0; | ||
2486 | |||
2487 | /* | ||
2488 | * Must be ->curr _and_ ->on_rq. If dequeued, we would | ||
2489 | * project cycles that may never be accounted to this | ||
2490 | * thread, breaking clock_gettime(). | ||
2491 | */ | ||
2492 | if (task_current(rq, p) && task_on_rq_queued(p)) { | ||
2493 | update_rq_clock(rq); | ||
2494 | ns = rq_clock_task(rq) - p->se.exec_start; | ||
2495 | if ((s64)ns < 0) | ||
2496 | ns = 0; | ||
2497 | } | ||
2498 | |||
2499 | return ns; | ||
2500 | } | ||
2501 | |||
2502 | unsigned long long task_delta_exec(struct task_struct *p) | ||
2503 | { | ||
2504 | unsigned long flags; | ||
2505 | struct rq *rq; | ||
2506 | u64 ns = 0; | ||
2507 | |||
2508 | rq = task_rq_lock(p, &flags); | ||
2509 | ns = do_task_delta_exec(p, rq); | ||
2510 | task_rq_unlock(rq, p, &flags); | ||
2511 | |||
2512 | return ns; | ||
2513 | } | ||
2514 | |||
2515 | /* | ||
2516 | * Return accounted runtime for the task. | 2478 | * Return accounted runtime for the task. |
2517 | * In case the task is currently running, return the runtime plus current's | 2479 | * In case the task is currently running, return the runtime plus current's |
2518 | * pending runtime that have not been accounted yet. | 2480 | * pending runtime that have not been accounted yet. |
@@ -2521,7 +2483,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) | |||
2521 | { | 2483 | { |
2522 | unsigned long flags; | 2484 | unsigned long flags; |
2523 | struct rq *rq; | 2485 | struct rq *rq; |
2524 | u64 ns = 0; | 2486 | u64 ns; |
2525 | 2487 | ||
2526 | #if defined(CONFIG_64BIT) && defined(CONFIG_SMP) | 2488 | #if defined(CONFIG_64BIT) && defined(CONFIG_SMP) |
2527 | /* | 2489 | /* |
@@ -2540,7 +2502,16 @@ unsigned long long task_sched_runtime(struct task_struct *p) | |||
2540 | #endif | 2502 | #endif |
2541 | 2503 | ||
2542 | rq = task_rq_lock(p, &flags); | 2504 | rq = task_rq_lock(p, &flags); |
2543 | ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq); | 2505 | /* |
2506 | * Must be ->curr _and_ ->on_rq. If dequeued, we would | ||
2507 | * project cycles that may never be accounted to this | ||
2508 | * thread, breaking clock_gettime(). | ||
2509 | */ | ||
2510 | if (task_current(rq, p) && task_on_rq_queued(p)) { | ||
2511 | update_rq_clock(rq); | ||
2512 | p->sched_class->update_curr(rq); | ||
2513 | } | ||
2514 | ns = p->se.sum_exec_runtime; | ||
2544 | task_rq_unlock(rq, p, &flags); | 2515 | task_rq_unlock(rq, p, &flags); |
2545 | 2516 | ||
2546 | return ns; | 2517 | return ns; |
@@ -6368,6 +6339,10 @@ static void sched_init_numa(void) | |||
6368 | if (!sched_debug()) | 6339 | if (!sched_debug()) |
6369 | break; | 6340 | break; |
6370 | } | 6341 | } |
6342 | |||
6343 | if (!level) | ||
6344 | return; | ||
6345 | |||
6371 | /* | 6346 | /* |
6372 | * 'level' contains the number of unique distances, excluding the | 6347 | * 'level' contains the number of unique distances, excluding the |
6373 | * identity distance node_distance(i,i). | 6348 | * identity distance node_distance(i,i). |
@@ -7444,8 +7419,12 @@ void sched_move_task(struct task_struct *tsk) | |||
7444 | if (unlikely(running)) | 7419 | if (unlikely(running)) |
7445 | put_prev_task(rq, tsk); | 7420 | put_prev_task(rq, tsk); |
7446 | 7421 | ||
7447 | tg = container_of(task_css_check(tsk, cpu_cgrp_id, | 7422 | /* |
7448 | lockdep_is_held(&tsk->sighand->siglock)), | 7423 | * All callers are synchronized by task_rq_lock(); we do not use RCU |
7424 | * which is pointless here. Thus, we pass "true" to task_css_check() | ||
7425 | * to prevent lockdep warnings. | ||
7426 | */ | ||
7427 | tg = container_of(task_css_check(tsk, cpu_cgrp_id, true), | ||
7449 | struct task_group, css); | 7428 | struct task_group, css); |
7450 | tg = autogroup_task_group(tsk, tg); | 7429 | tg = autogroup_task_group(tsk, tg); |
7451 | tsk->sched_task_group = tg; | 7430 | tsk->sched_task_group = tg; |
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 5285332392d5..28fa9d9e9201 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c | |||
@@ -1701,4 +1701,6 @@ const struct sched_class dl_sched_class = { | |||
1701 | .prio_changed = prio_changed_dl, | 1701 | .prio_changed = prio_changed_dl, |
1702 | .switched_from = switched_from_dl, | 1702 | .switched_from = switched_from_dl, |
1703 | .switched_to = switched_to_dl, | 1703 | .switched_to = switched_to_dl, |
1704 | |||
1705 | .update_curr = update_curr_dl, | ||
1704 | }; | 1706 | }; |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 34baa60f8a7b..ef2b104b254c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -726,6 +726,11 @@ static void update_curr(struct cfs_rq *cfs_rq) | |||
726 | account_cfs_rq_runtime(cfs_rq, delta_exec); | 726 | account_cfs_rq_runtime(cfs_rq, delta_exec); |
727 | } | 727 | } |
728 | 728 | ||
729 | static void update_curr_fair(struct rq *rq) | ||
730 | { | ||
731 | update_curr(cfs_rq_of(&rq->curr->se)); | ||
732 | } | ||
733 | |||
729 | static inline void | 734 | static inline void |
730 | update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se) | 735 | update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se) |
731 | { | 736 | { |
@@ -1180,6 +1185,13 @@ static void task_numa_compare(struct task_numa_env *env, | |||
1180 | raw_spin_unlock_irq(&dst_rq->lock); | 1185 | raw_spin_unlock_irq(&dst_rq->lock); |
1181 | 1186 | ||
1182 | /* | 1187 | /* |
1188 | * Because we have preemption enabled we can get migrated around and | ||
1189 | * end try selecting ourselves (current == env->p) as a swap candidate. | ||
1190 | */ | ||
1191 | if (cur == env->p) | ||
1192 | goto unlock; | ||
1193 | |||
1194 | /* | ||
1183 | * "imp" is the fault differential for the source task between the | 1195 | * "imp" is the fault differential for the source task between the |
1184 | * source and destination node. Calculate the total differential for | 1196 | * source and destination node. Calculate the total differential for |
1185 | * the source task and potential destination task. The more negative | 1197 | * the source task and potential destination task. The more negative |
@@ -7949,6 +7961,8 @@ const struct sched_class fair_sched_class = { | |||
7949 | 7961 | ||
7950 | .get_rr_interval = get_rr_interval_fair, | 7962 | .get_rr_interval = get_rr_interval_fair, |
7951 | 7963 | ||
7964 | .update_curr = update_curr_fair, | ||
7965 | |||
7952 | #ifdef CONFIG_FAIR_GROUP_SCHED | 7966 | #ifdef CONFIG_FAIR_GROUP_SCHED |
7953 | .task_move_group = task_move_group_fair, | 7967 | .task_move_group = task_move_group_fair, |
7954 | #endif | 7968 | #endif |
diff --git a/kernel/sched/idle_task.c b/kernel/sched/idle_task.c index 67ad4e7f506a..c65dac8c97cd 100644 --- a/kernel/sched/idle_task.c +++ b/kernel/sched/idle_task.c | |||
@@ -75,6 +75,10 @@ static unsigned int get_rr_interval_idle(struct rq *rq, struct task_struct *task | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | static void update_curr_idle(struct rq *rq) | ||
79 | { | ||
80 | } | ||
81 | |||
78 | /* | 82 | /* |
79 | * Simple, special scheduling class for the per-CPU idle tasks: | 83 | * Simple, special scheduling class for the per-CPU idle tasks: |
80 | */ | 84 | */ |
@@ -101,4 +105,5 @@ const struct sched_class idle_sched_class = { | |||
101 | 105 | ||
102 | .prio_changed = prio_changed_idle, | 106 | .prio_changed = prio_changed_idle, |
103 | .switched_to = switched_to_idle, | 107 | .switched_to = switched_to_idle, |
108 | .update_curr = update_curr_idle, | ||
104 | }; | 109 | }; |
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index d024e6ce30ba..20bca398084a 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
@@ -2128,6 +2128,8 @@ const struct sched_class rt_sched_class = { | |||
2128 | 2128 | ||
2129 | .prio_changed = prio_changed_rt, | 2129 | .prio_changed = prio_changed_rt, |
2130 | .switched_to = switched_to_rt, | 2130 | .switched_to = switched_to_rt, |
2131 | |||
2132 | .update_curr = update_curr_rt, | ||
2131 | }; | 2133 | }; |
2132 | 2134 | ||
2133 | #ifdef CONFIG_SCHED_DEBUG | 2135 | #ifdef CONFIG_SCHED_DEBUG |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 24156c8434d1..2df8ef067cc5 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -1135,6 +1135,8 @@ struct sched_class { | |||
1135 | unsigned int (*get_rr_interval) (struct rq *rq, | 1135 | unsigned int (*get_rr_interval) (struct rq *rq, |
1136 | struct task_struct *task); | 1136 | struct task_struct *task); |
1137 | 1137 | ||
1138 | void (*update_curr) (struct rq *rq); | ||
1139 | |||
1138 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1140 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1139 | void (*task_move_group) (struct task_struct *p, int on_rq); | 1141 | void (*task_move_group) (struct task_struct *p, int on_rq); |
1140 | #endif | 1142 | #endif |
diff --git a/kernel/sched/stop_task.c b/kernel/sched/stop_task.c index 67426e529f59..79ffec45a6ac 100644 --- a/kernel/sched/stop_task.c +++ b/kernel/sched/stop_task.c | |||
@@ -102,6 +102,10 @@ get_rr_interval_stop(struct rq *rq, struct task_struct *task) | |||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | static void update_curr_stop(struct rq *rq) | ||
106 | { | ||
107 | } | ||
108 | |||
105 | /* | 109 | /* |
106 | * Simple, special scheduling class for the per-CPU stop tasks: | 110 | * Simple, special scheduling class for the per-CPU stop tasks: |
107 | */ | 111 | */ |
@@ -128,4 +132,5 @@ const struct sched_class stop_sched_class = { | |||
128 | 132 | ||
129 | .prio_changed = prio_changed_stop, | 133 | .prio_changed = prio_changed_stop, |
130 | .switched_to = switched_to_stop, | 134 | .switched_to = switched_to_stop, |
135 | .update_curr = update_curr_stop, | ||
131 | }; | 136 | }; |
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 492b986195d5..a16b67859e2a 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c | |||
@@ -553,7 +553,7 @@ static int cpu_timer_sample_group(const clockid_t which_clock, | |||
553 | *sample = cputime_to_expires(cputime.utime); | 553 | *sample = cputime_to_expires(cputime.utime); |
554 | break; | 554 | break; |
555 | case CPUCLOCK_SCHED: | 555 | case CPUCLOCK_SCHED: |
556 | *sample = cputime.sum_exec_runtime + task_delta_exec(p); | 556 | *sample = cputime.sum_exec_runtime; |
557 | break; | 557 | break; |
558 | } | 558 | } |
559 | return 0; | 559 | return 0; |
diff --git a/lib/Makefile b/lib/Makefile index 7512dc978f18..0211d2bd5e17 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -10,7 +10,7 @@ endif | |||
10 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ | 10 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ |
11 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ | 11 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ |
12 | idr.o int_sqrt.o extable.o \ | 12 | idr.o int_sqrt.o extable.o \ |
13 | sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ | 13 | sha1.o md5.o irq_regs.o argv_split.o \ |
14 | proportions.o flex_proportions.o ratelimit.o show_mem.o \ | 14 | proportions.o flex_proportions.o ratelimit.o show_mem.o \ |
15 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ | 15 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ |
16 | earlycpio.o | 16 | earlycpio.o |
@@ -26,7 +26,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | |||
26 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ | 26 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ |
27 | gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \ | 27 | gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \ |
28 | bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ | 28 | bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ |
29 | percpu-refcount.o percpu_ida.o hash.o rhashtable.o | 29 | percpu-refcount.o percpu_ida.o hash.o rhashtable.o reciprocal_div.o |
30 | obj-y += string_helpers.o | 30 | obj-y += string_helpers.o |
31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o | 31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o |
32 | obj-y += kstrtox.o | 32 | obj-y += kstrtox.o |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 648d79ccf462..c465876c7861 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -813,10 +813,9 @@ static void __br_multicast_send_query(struct net_bridge *br, | |||
813 | return; | 813 | return; |
814 | 814 | ||
815 | if (port) { | 815 | if (port) { |
816 | __skb_push(skb, sizeof(struct ethhdr)); | ||
817 | skb->dev = port->dev; | 816 | skb->dev = port->dev; |
818 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, | 817 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
819 | dev_queue_xmit); | 818 | br_dev_queue_push_xmit); |
820 | } else { | 819 | } else { |
821 | br_multicast_select_own_querier(br, ip, skb); | 820 | br_multicast_select_own_querier(br, ip, skb); |
822 | netif_rx(skb); | 821 | netif_rx(skb); |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2ff9706647f2..e5ec470b851f 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -280,6 +280,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { | |||
280 | [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, | 280 | [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, |
281 | [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, | 281 | [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, |
282 | [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, | 282 | [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, |
283 | [IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 }, | ||
283 | [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, | 284 | [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, |
284 | [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, | 285 | [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, |
285 | }; | 286 | }; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a6882686ca3a..b9b7dfaf202b 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -2685,13 +2685,20 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) | |||
2685 | int idx = 0; | 2685 | int idx = 0; |
2686 | u32 portid = NETLINK_CB(cb->skb).portid; | 2686 | u32 portid = NETLINK_CB(cb->skb).portid; |
2687 | u32 seq = cb->nlh->nlmsg_seq; | 2687 | u32 seq = cb->nlh->nlmsg_seq; |
2688 | struct nlattr *extfilt; | ||
2689 | u32 filter_mask = 0; | 2688 | u32 filter_mask = 0; |
2690 | 2689 | ||
2691 | extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), | 2690 | if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { |
2692 | IFLA_EXT_MASK); | 2691 | struct nlattr *extfilt; |
2693 | if (extfilt) | 2692 | |
2694 | filter_mask = nla_get_u32(extfilt); | 2693 | extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), |
2694 | IFLA_EXT_MASK); | ||
2695 | if (extfilt) { | ||
2696 | if (nla_len(extfilt) < sizeof(filter_mask)) | ||
2697 | return -EINVAL; | ||
2698 | |||
2699 | filter_mask = nla_get_u32(extfilt); | ||
2700 | } | ||
2701 | } | ||
2695 | 2702 | ||
2696 | rcu_read_lock(); | 2703 | rcu_read_lock(); |
2697 | for_each_netdev_rcu(net, dev) { | 2704 | for_each_netdev_rcu(net, dev) { |
@@ -2798,6 +2805,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2798 | if (br_spec) { | 2805 | if (br_spec) { |
2799 | nla_for_each_nested(attr, br_spec, rem) { | 2806 | nla_for_each_nested(attr, br_spec, rem) { |
2800 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { | 2807 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { |
2808 | if (nla_len(attr) < sizeof(flags)) | ||
2809 | return -EINVAL; | ||
2810 | |||
2801 | have_flags = true; | 2811 | have_flags = true; |
2802 | flags = nla_get_u16(attr); | 2812 | flags = nla_get_u16(attr); |
2803 | break; | 2813 | break; |
@@ -2868,6 +2878,9 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2868 | if (br_spec) { | 2878 | if (br_spec) { |
2869 | nla_for_each_nested(attr, br_spec, rem) { | 2879 | nla_for_each_nested(attr, br_spec, rem) { |
2870 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { | 2880 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { |
2881 | if (nla_len(attr) < sizeof(flags)) | ||
2882 | return -EINVAL; | ||
2883 | |||
2871 | have_flags = true; | 2884 | have_flags = true; |
2872 | flags = nla_get_u16(attr); | 2885 | flags = nla_get_u16(attr); |
2873 | break; | 2886 | break; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c16615bfb61e..32e31c299631 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -552,20 +552,13 @@ static void kfree_skbmem(struct sk_buff *skb) | |||
552 | case SKB_FCLONE_CLONE: | 552 | case SKB_FCLONE_CLONE: |
553 | fclones = container_of(skb, struct sk_buff_fclones, skb2); | 553 | fclones = container_of(skb, struct sk_buff_fclones, skb2); |
554 | 554 | ||
555 | /* Warning : We must perform the atomic_dec_and_test() before | 555 | /* The clone portion is available for |
556 | * setting skb->fclone back to SKB_FCLONE_FREE, otherwise | 556 | * fast-cloning again. |
557 | * skb_clone() could set clone_ref to 2 before our decrement. | ||
558 | * Anyway, if we are going to free the structure, no need to | ||
559 | * rewrite skb->fclone. | ||
560 | */ | 557 | */ |
561 | if (atomic_dec_and_test(&fclones->fclone_ref)) { | 558 | skb->fclone = SKB_FCLONE_FREE; |
559 | |||
560 | if (atomic_dec_and_test(&fclones->fclone_ref)) | ||
562 | kmem_cache_free(skbuff_fclone_cache, fclones); | 561 | kmem_cache_free(skbuff_fclone_cache, fclones); |
563 | } else { | ||
564 | /* The clone portion is available for | ||
565 | * fast-cloning again. | ||
566 | */ | ||
567 | skb->fclone = SKB_FCLONE_FREE; | ||
568 | } | ||
569 | break; | 562 | break; |
570 | } | 563 | } |
571 | } | 564 | } |
@@ -887,11 +880,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) | |||
887 | if (skb->fclone == SKB_FCLONE_ORIG && | 880 | if (skb->fclone == SKB_FCLONE_ORIG && |
888 | n->fclone == SKB_FCLONE_FREE) { | 881 | n->fclone == SKB_FCLONE_FREE) { |
889 | n->fclone = SKB_FCLONE_CLONE; | 882 | n->fclone = SKB_FCLONE_CLONE; |
890 | /* As our fastclone was free, clone_ref must be 1 at this point. | 883 | atomic_inc(&fclones->fclone_ref); |
891 | * We could use atomic_inc() here, but it is faster | ||
892 | * to set the final value. | ||
893 | */ | ||
894 | atomic_set(&fclones->fclone_ref, 2); | ||
895 | } else { | 884 | } else { |
896 | if (skb_pfmemalloc(skb)) | 885 | if (skb_pfmemalloc(skb)) |
897 | gfp_mask |= __GFP_MEMALLOC; | 886 | gfp_mask |= __GFP_MEMALLOC; |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index ca11d283bbeb..93ea80196f0e 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -1080,13 +1080,13 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1080 | if (!app) | 1080 | if (!app) |
1081 | return -EMSGSIZE; | 1081 | return -EMSGSIZE; |
1082 | 1082 | ||
1083 | spin_lock(&dcb_lock); | 1083 | spin_lock_bh(&dcb_lock); |
1084 | list_for_each_entry(itr, &dcb_app_list, list) { | 1084 | list_for_each_entry(itr, &dcb_app_list, list) { |
1085 | if (itr->ifindex == netdev->ifindex) { | 1085 | if (itr->ifindex == netdev->ifindex) { |
1086 | err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), | 1086 | err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), |
1087 | &itr->app); | 1087 | &itr->app); |
1088 | if (err) { | 1088 | if (err) { |
1089 | spin_unlock(&dcb_lock); | 1089 | spin_unlock_bh(&dcb_lock); |
1090 | return -EMSGSIZE; | 1090 | return -EMSGSIZE; |
1091 | } | 1091 | } |
1092 | } | 1092 | } |
@@ -1097,7 +1097,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1097 | else | 1097 | else |
1098 | dcbx = -EOPNOTSUPP; | 1098 | dcbx = -EOPNOTSUPP; |
1099 | 1099 | ||
1100 | spin_unlock(&dcb_lock); | 1100 | spin_unlock_bh(&dcb_lock); |
1101 | nla_nest_end(skb, app); | 1101 | nla_nest_end(skb, app); |
1102 | 1102 | ||
1103 | /* get peer info if available */ | 1103 | /* get peer info if available */ |
@@ -1234,7 +1234,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | /* local app */ | 1236 | /* local app */ |
1237 | spin_lock(&dcb_lock); | 1237 | spin_lock_bh(&dcb_lock); |
1238 | app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); | 1238 | app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); |
1239 | if (!app) | 1239 | if (!app) |
1240 | goto dcb_unlock; | 1240 | goto dcb_unlock; |
@@ -1271,7 +1271,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1271 | else | 1271 | else |
1272 | dcbx = -EOPNOTSUPP; | 1272 | dcbx = -EOPNOTSUPP; |
1273 | 1273 | ||
1274 | spin_unlock(&dcb_lock); | 1274 | spin_unlock_bh(&dcb_lock); |
1275 | 1275 | ||
1276 | /* features flags */ | 1276 | /* features flags */ |
1277 | if (ops->getfeatcfg) { | 1277 | if (ops->getfeatcfg) { |
@@ -1326,7 +1326,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
1326 | return 0; | 1326 | return 0; |
1327 | 1327 | ||
1328 | dcb_unlock: | 1328 | dcb_unlock: |
1329 | spin_unlock(&dcb_lock); | 1329 | spin_unlock_bh(&dcb_lock); |
1330 | nla_put_failure: | 1330 | nla_put_failure: |
1331 | return err; | 1331 | return err; |
1332 | } | 1332 | } |
@@ -1762,10 +1762,10 @@ u8 dcb_getapp(struct net_device *dev, struct dcb_app *app) | |||
1762 | struct dcb_app_type *itr; | 1762 | struct dcb_app_type *itr; |
1763 | u8 prio = 0; | 1763 | u8 prio = 0; |
1764 | 1764 | ||
1765 | spin_lock(&dcb_lock); | 1765 | spin_lock_bh(&dcb_lock); |
1766 | if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) | 1766 | if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) |
1767 | prio = itr->app.priority; | 1767 | prio = itr->app.priority; |
1768 | spin_unlock(&dcb_lock); | 1768 | spin_unlock_bh(&dcb_lock); |
1769 | 1769 | ||
1770 | return prio; | 1770 | return prio; |
1771 | } | 1771 | } |
@@ -1789,7 +1789,7 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new) | |||
1789 | if (dev->dcbnl_ops->getdcbx) | 1789 | if (dev->dcbnl_ops->getdcbx) |
1790 | event.dcbx = dev->dcbnl_ops->getdcbx(dev); | 1790 | event.dcbx = dev->dcbnl_ops->getdcbx(dev); |
1791 | 1791 | ||
1792 | spin_lock(&dcb_lock); | 1792 | spin_lock_bh(&dcb_lock); |
1793 | /* Search for existing match and replace */ | 1793 | /* Search for existing match and replace */ |
1794 | if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) { | 1794 | if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) { |
1795 | if (new->priority) | 1795 | if (new->priority) |
@@ -1804,7 +1804,7 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new) | |||
1804 | if (new->priority) | 1804 | if (new->priority) |
1805 | err = dcb_app_add(new, dev->ifindex); | 1805 | err = dcb_app_add(new, dev->ifindex); |
1806 | out: | 1806 | out: |
1807 | spin_unlock(&dcb_lock); | 1807 | spin_unlock_bh(&dcb_lock); |
1808 | if (!err) | 1808 | if (!err) |
1809 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); | 1809 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); |
1810 | return err; | 1810 | return err; |
@@ -1823,10 +1823,10 @@ u8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) | |||
1823 | struct dcb_app_type *itr; | 1823 | struct dcb_app_type *itr; |
1824 | u8 prio = 0; | 1824 | u8 prio = 0; |
1825 | 1825 | ||
1826 | spin_lock(&dcb_lock); | 1826 | spin_lock_bh(&dcb_lock); |
1827 | if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) | 1827 | if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) |
1828 | prio |= 1 << itr->app.priority; | 1828 | prio |= 1 << itr->app.priority; |
1829 | spin_unlock(&dcb_lock); | 1829 | spin_unlock_bh(&dcb_lock); |
1830 | 1830 | ||
1831 | return prio; | 1831 | return prio; |
1832 | } | 1832 | } |
@@ -1850,7 +1850,7 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) | |||
1850 | if (dev->dcbnl_ops->getdcbx) | 1850 | if (dev->dcbnl_ops->getdcbx) |
1851 | event.dcbx = dev->dcbnl_ops->getdcbx(dev); | 1851 | event.dcbx = dev->dcbnl_ops->getdcbx(dev); |
1852 | 1852 | ||
1853 | spin_lock(&dcb_lock); | 1853 | spin_lock_bh(&dcb_lock); |
1854 | /* Search for existing match and abort if found */ | 1854 | /* Search for existing match and abort if found */ |
1855 | if (dcb_app_lookup(new, dev->ifindex, new->priority)) { | 1855 | if (dcb_app_lookup(new, dev->ifindex, new->priority)) { |
1856 | err = -EEXIST; | 1856 | err = -EEXIST; |
@@ -1859,7 +1859,7 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) | |||
1859 | 1859 | ||
1860 | err = dcb_app_add(new, dev->ifindex); | 1860 | err = dcb_app_add(new, dev->ifindex); |
1861 | out: | 1861 | out: |
1862 | spin_unlock(&dcb_lock); | 1862 | spin_unlock_bh(&dcb_lock); |
1863 | if (!err) | 1863 | if (!err) |
1864 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); | 1864 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); |
1865 | return err; | 1865 | return err; |
@@ -1882,7 +1882,7 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) | |||
1882 | if (dev->dcbnl_ops->getdcbx) | 1882 | if (dev->dcbnl_ops->getdcbx) |
1883 | event.dcbx = dev->dcbnl_ops->getdcbx(dev); | 1883 | event.dcbx = dev->dcbnl_ops->getdcbx(dev); |
1884 | 1884 | ||
1885 | spin_lock(&dcb_lock); | 1885 | spin_lock_bh(&dcb_lock); |
1886 | /* Search for existing match and remove it. */ | 1886 | /* Search for existing match and remove it. */ |
1887 | if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) { | 1887 | if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) { |
1888 | list_del(&itr->list); | 1888 | list_del(&itr->list); |
@@ -1890,7 +1890,7 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) | |||
1890 | err = 0; | 1890 | err = 0; |
1891 | } | 1891 | } |
1892 | 1892 | ||
1893 | spin_unlock(&dcb_lock); | 1893 | spin_unlock_bh(&dcb_lock); |
1894 | if (!err) | 1894 | if (!err) |
1895 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); | 1895 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); |
1896 | return err; | 1896 | return err; |
@@ -1902,12 +1902,12 @@ static void dcb_flushapp(void) | |||
1902 | struct dcb_app_type *app; | 1902 | struct dcb_app_type *app; |
1903 | struct dcb_app_type *tmp; | 1903 | struct dcb_app_type *tmp; |
1904 | 1904 | ||
1905 | spin_lock(&dcb_lock); | 1905 | spin_lock_bh(&dcb_lock); |
1906 | list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { | 1906 | list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { |
1907 | list_del(&app->list); | 1907 | list_del(&app->list); |
1908 | kfree(app); | 1908 | kfree(app); |
1909 | } | 1909 | } |
1910 | spin_unlock(&dcb_lock); | 1910 | spin_unlock_bh(&dcb_lock); |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | static int __init dcbnl_init(void) | 1913 | static int __init dcbnl_init(void) |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8b7fe5b03906..e67da4e6c324 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1386,6 +1386,17 @@ out: | |||
1386 | return pp; | 1386 | return pp; |
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | ||
1390 | { | ||
1391 | if (sk->sk_family == AF_INET) | ||
1392 | return ip_recv_error(sk, msg, len, addr_len); | ||
1393 | #if IS_ENABLED(CONFIG_IPV6) | ||
1394 | if (sk->sk_family == AF_INET6) | ||
1395 | return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len); | ||
1396 | #endif | ||
1397 | return -EINVAL; | ||
1398 | } | ||
1399 | |||
1389 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) | 1400 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) |
1390 | { | 1401 | { |
1391 | __be16 newlen = htons(skb->len - nhoff); | 1402 | __be16 newlen = htons(skb->len - nhoff); |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index f2e15738534d..8f7bd56955b0 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -62,6 +62,10 @@ int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) | |||
62 | else | 62 | else |
63 | res->tclassid = 0; | 63 | res->tclassid = 0; |
64 | #endif | 64 | #endif |
65 | |||
66 | if (err == -ESRCH) | ||
67 | err = -ENETUNREACH; | ||
68 | |||
65 | return err; | 69 | return err; |
66 | } | 70 | } |
67 | EXPORT_SYMBOL_GPL(__fib_lookup); | 71 | EXPORT_SYMBOL_GPL(__fib_lookup); |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index fb70e3ecc3e4..bb15d0e03d4f 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -318,9 +318,7 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) | |||
318 | return scount; | 318 | return scount; |
319 | } | 319 | } |
320 | 320 | ||
321 | #define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb)) | 321 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) |
322 | |||
323 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | ||
324 | { | 322 | { |
325 | struct sk_buff *skb; | 323 | struct sk_buff *skb; |
326 | struct rtable *rt; | 324 | struct rtable *rt; |
@@ -330,6 +328,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
330 | struct flowi4 fl4; | 328 | struct flowi4 fl4; |
331 | int hlen = LL_RESERVED_SPACE(dev); | 329 | int hlen = LL_RESERVED_SPACE(dev); |
332 | int tlen = dev->needed_tailroom; | 330 | int tlen = dev->needed_tailroom; |
331 | unsigned int size = mtu; | ||
333 | 332 | ||
334 | while (1) { | 333 | while (1) { |
335 | skb = alloc_skb(size + hlen + tlen, | 334 | skb = alloc_skb(size + hlen + tlen, |
@@ -341,7 +340,6 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
341 | return NULL; | 340 | return NULL; |
342 | } | 341 | } |
343 | skb->priority = TC_PRIO_CONTROL; | 342 | skb->priority = TC_PRIO_CONTROL; |
344 | igmp_skb_size(skb) = size; | ||
345 | 343 | ||
346 | rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0, | 344 | rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0, |
347 | 0, 0, | 345 | 0, 0, |
@@ -354,6 +352,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
354 | skb_dst_set(skb, &rt->dst); | 352 | skb_dst_set(skb, &rt->dst); |
355 | skb->dev = dev; | 353 | skb->dev = dev; |
356 | 354 | ||
355 | skb->reserved_tailroom = skb_end_offset(skb) - | ||
356 | min(mtu, skb_end_offset(skb)); | ||
357 | skb_reserve(skb, hlen); | 357 | skb_reserve(skb, hlen); |
358 | 358 | ||
359 | skb_reset_network_header(skb); | 359 | skb_reset_network_header(skb); |
@@ -423,8 +423,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
423 | return skb; | 423 | return skb; |
424 | } | 424 | } |
425 | 425 | ||
426 | #define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \ | 426 | #define AVAILABLE(skb) ((skb) ? skb_availroom(skb) : 0) |
427 | skb_tailroom(skb)) : 0) | ||
428 | 427 | ||
429 | static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | 428 | static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, |
430 | int type, int gdeleted, int sdeleted) | 429 | int type, int gdeleted, int sdeleted) |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 3e861011e4a3..1a7e979e80ba 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -528,6 +528,7 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = { | |||
528 | .validate = vti_tunnel_validate, | 528 | .validate = vti_tunnel_validate, |
529 | .newlink = vti_newlink, | 529 | .newlink = vti_newlink, |
530 | .changelink = vti_changelink, | 530 | .changelink = vti_changelink, |
531 | .dellink = ip_tunnel_dellink, | ||
531 | .get_size = vti_get_size, | 532 | .get_size = vti_get_size, |
532 | .fill_info = vti_fill_info, | 533 | .fill_info = vti_fill_info, |
533 | }; | 534 | }; |
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c index c1023c445920..665de06561cd 100644 --- a/net/ipv4/netfilter/nft_masq_ipv4.c +++ b/net/ipv4/netfilter/nft_masq_ipv4.c | |||
@@ -24,6 +24,7 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr, | |||
24 | struct nf_nat_range range; | 24 | struct nf_nat_range range; |
25 | unsigned int verdict; | 25 | unsigned int verdict; |
26 | 26 | ||
27 | memset(&range, 0, sizeof(range)); | ||
27 | range.flags = priv->flags; | 28 | range.flags = priv->flags; |
28 | 29 | ||
29 | verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum, | 30 | verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum, |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 57f7c9804139..5d740cccf69e 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -217,6 +217,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) | |||
217 | &ipv6_hdr(skb)->daddr)) | 217 | &ipv6_hdr(skb)->daddr)) |
218 | continue; | 218 | continue; |
219 | #endif | 219 | #endif |
220 | } else { | ||
221 | continue; | ||
220 | } | 222 | } |
221 | 223 | ||
222 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) | 224 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) |
@@ -853,16 +855,8 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
853 | if (flags & MSG_OOB) | 855 | if (flags & MSG_OOB) |
854 | goto out; | 856 | goto out; |
855 | 857 | ||
856 | if (flags & MSG_ERRQUEUE) { | 858 | if (flags & MSG_ERRQUEUE) |
857 | if (family == AF_INET) { | 859 | return inet_recv_error(sk, msg, len, addr_len); |
858 | return ip_recv_error(sk, msg, len, addr_len); | ||
859 | #if IS_ENABLED(CONFIG_IPV6) | ||
860 | } else if (family == AF_INET6) { | ||
861 | return pingv6_ops.ipv6_recv_error(sk, msg, len, | ||
862 | addr_len); | ||
863 | #endif | ||
864 | } | ||
865 | } | ||
866 | 860 | ||
867 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 861 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
868 | if (!skb) | 862 | if (!skb) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 39ec0c379545..38c2bcb8dd5d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1598,7 +1598,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1598 | u32 urg_hole = 0; | 1598 | u32 urg_hole = 0; |
1599 | 1599 | ||
1600 | if (unlikely(flags & MSG_ERRQUEUE)) | 1600 | if (unlikely(flags & MSG_ERRQUEUE)) |
1601 | return ip_recv_error(sk, msg, len, addr_len); | 1601 | return inet_recv_error(sk, msg, len, addr_len); |
1602 | 1602 | ||
1603 | if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && | 1603 | if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && |
1604 | (sk->sk_state == TCP_ESTABLISHED)) | 1604 | (sk->sk_state == TCP_ESTABLISHED)) |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 88fa2d160685..d107ee246a1d 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5231,7 +5231,7 @@ slow_path: | |||
5231 | if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb)) | 5231 | if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb)) |
5232 | goto csum_error; | 5232 | goto csum_error; |
5233 | 5233 | ||
5234 | if (!th->ack && !th->rst) | 5234 | if (!th->ack && !th->rst && !th->syn) |
5235 | goto discard; | 5235 | goto discard; |
5236 | 5236 | ||
5237 | /* | 5237 | /* |
@@ -5650,7 +5650,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5650 | goto discard; | 5650 | goto discard; |
5651 | } | 5651 | } |
5652 | 5652 | ||
5653 | if (!th->ack && !th->rst) | 5653 | if (!th->ack && !th->rst && !th->syn) |
5654 | goto discard; | 5654 | goto discard; |
5655 | 5655 | ||
5656 | if (!tcp_validate_incoming(sk, skb, th, 0)) | 5656 | if (!tcp_validate_incoming(sk, skb, th, 0)) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9c7d7621466b..147be2024290 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -598,7 +598,10 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
598 | if (th->rst) | 598 | if (th->rst) |
599 | return; | 599 | return; |
600 | 600 | ||
601 | if (skb_rtable(skb)->rt_type != RTN_LOCAL) | 601 | /* If sk not NULL, it means we did a successful lookup and incoming |
602 | * route had to be correct. prequeue might have dropped our dst. | ||
603 | */ | ||
604 | if (!sk && skb_rtable(skb)->rt_type != RTN_LOCAL) | ||
602 | return; | 605 | return; |
603 | 606 | ||
604 | /* Swap the send and the receive. */ | 607 | /* Swap the send and the receive. */ |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 4564e1fca3eb..0e32d2e1bdbf 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -502,11 +502,11 @@ static int ip6gre_rcv(struct sk_buff *skb) | |||
502 | 502 | ||
503 | skb->protocol = gre_proto; | 503 | skb->protocol = gre_proto; |
504 | /* WCCP version 1 and 2 protocol decoding. | 504 | /* WCCP version 1 and 2 protocol decoding. |
505 | * - Change protocol to IP | 505 | * - Change protocol to IPv6 |
506 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header | 506 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header |
507 | */ | 507 | */ |
508 | if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) { | 508 | if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) { |
509 | skb->protocol = htons(ETH_P_IP); | 509 | skb->protocol = htons(ETH_P_IPV6); |
510 | if ((*(h + offset) & 0xF0) != 0x40) | 510 | if ((*(h + offset) & 0xF0) != 0x40) |
511 | offset += 4; | 511 | offset += 4; |
512 | } | 512 | } |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index a071563a7e6e..01e12d0d8fcc 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -69,7 +69,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
69 | int nhoff; | 69 | int nhoff; |
70 | 70 | ||
71 | if (unlikely(skb_shinfo(skb)->gso_type & | 71 | if (unlikely(skb_shinfo(skb)->gso_type & |
72 | ~(SKB_GSO_UDP | | 72 | ~(SKB_GSO_TCPV4 | |
73 | SKB_GSO_UDP | | ||
73 | SKB_GSO_DODGY | | 74 | SKB_GSO_DODGY | |
74 | SKB_GSO_TCP_ECN | | 75 | SKB_GSO_TCP_ECN | |
75 | SKB_GSO_GRE | | 76 | SKB_GSO_GRE | |
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c index b04ed72c4542..8db6c98fe218 100644 --- a/net/ipv6/ip6_udp_tunnel.c +++ b/net/ipv6/ip6_udp_tunnel.c | |||
@@ -79,15 +79,13 @@ int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst, | |||
79 | uh->source = src_port; | 79 | uh->source = src_port; |
80 | 80 | ||
81 | uh->len = htons(skb->len); | 81 | uh->len = htons(skb->len); |
82 | uh->check = 0; | ||
83 | 82 | ||
84 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 83 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
85 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | 84 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
86 | | IPSKB_REROUTED); | 85 | | IPSKB_REROUTED); |
87 | skb_dst_set(skb, dst); | 86 | skb_dst_set(skb, dst); |
88 | 87 | ||
89 | udp6_set_csum(udp_get_no_check6_tx(sk), skb, &inet6_sk(sk)->saddr, | 88 | udp6_set_csum(udp_get_no_check6_tx(sk), skb, saddr, daddr, skb->len); |
90 | &sk->sk_v6_daddr, skb->len); | ||
91 | 89 | ||
92 | __skb_push(skb, sizeof(*ip6h)); | 90 | __skb_push(skb, sizeof(*ip6h)); |
93 | skb_reset_network_header(skb); | 91 | skb_reset_network_header(skb); |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 31089d153fd3..bcda14de7f84 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -905,6 +905,15 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev, | |||
905 | return vti6_tnl_create2(dev); | 905 | return vti6_tnl_create2(dev); |
906 | } | 906 | } |
907 | 907 | ||
908 | static void vti6_dellink(struct net_device *dev, struct list_head *head) | ||
909 | { | ||
910 | struct net *net = dev_net(dev); | ||
911 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); | ||
912 | |||
913 | if (dev != ip6n->fb_tnl_dev) | ||
914 | unregister_netdevice_queue(dev, head); | ||
915 | } | ||
916 | |||
908 | static int vti6_changelink(struct net_device *dev, struct nlattr *tb[], | 917 | static int vti6_changelink(struct net_device *dev, struct nlattr *tb[], |
909 | struct nlattr *data[]) | 918 | struct nlattr *data[]) |
910 | { | 919 | { |
@@ -980,6 +989,7 @@ static struct rtnl_link_ops vti6_link_ops __read_mostly = { | |||
980 | .setup = vti6_dev_setup, | 989 | .setup = vti6_dev_setup, |
981 | .validate = vti6_validate, | 990 | .validate = vti6_validate, |
982 | .newlink = vti6_newlink, | 991 | .newlink = vti6_newlink, |
992 | .dellink = vti6_dellink, | ||
983 | .changelink = vti6_changelink, | 993 | .changelink = vti6_changelink, |
984 | .get_size = vti6_get_size, | 994 | .get_size = vti6_get_size, |
985 | .fill_info = vti6_fill_info, | 995 | .fill_info = vti6_fill_info, |
@@ -1020,6 +1030,7 @@ static int __net_init vti6_init_net(struct net *net) | |||
1020 | if (!ip6n->fb_tnl_dev) | 1030 | if (!ip6n->fb_tnl_dev) |
1021 | goto err_alloc_dev; | 1031 | goto err_alloc_dev; |
1022 | dev_net_set(ip6n->fb_tnl_dev, net); | 1032 | dev_net_set(ip6n->fb_tnl_dev, net); |
1033 | ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops; | ||
1023 | 1034 | ||
1024 | err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev); | 1035 | err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev); |
1025 | if (err < 0) | 1036 | if (err < 0) |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 0171f08325c3..1a01d79b8698 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1439,6 +1439,10 @@ reg_pernet_fail: | |||
1439 | 1439 | ||
1440 | void ip6_mr_cleanup(void) | 1440 | void ip6_mr_cleanup(void) |
1441 | { | 1441 | { |
1442 | rtnl_unregister(RTNL_FAMILY_IP6MR, RTM_GETROUTE); | ||
1443 | #ifdef CONFIG_IPV6_PIMSM_V2 | ||
1444 | inet6_del_protocol(&pim6_protocol, IPPROTO_PIM); | ||
1445 | #endif | ||
1442 | unregister_netdevice_notifier(&ip6_mr_notifier); | 1446 | unregister_netdevice_notifier(&ip6_mr_notifier); |
1443 | unregister_pernet_subsys(&ip6mr_net_ops); | 1447 | unregister_pernet_subsys(&ip6mr_net_ops); |
1444 | kmem_cache_destroy(mrt_cachep); | 1448 | kmem_cache_destroy(mrt_cachep); |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 9648de2b6745..ed2c4e400b46 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1550,7 +1550,7 @@ static void ip6_mc_hdr(struct sock *sk, struct sk_buff *skb, | |||
1550 | hdr->daddr = *daddr; | 1550 | hdr->daddr = *daddr; |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size) | 1553 | static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) |
1554 | { | 1554 | { |
1555 | struct net_device *dev = idev->dev; | 1555 | struct net_device *dev = idev->dev; |
1556 | struct net *net = dev_net(dev); | 1556 | struct net *net = dev_net(dev); |
@@ -1561,13 +1561,13 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size) | |||
1561 | const struct in6_addr *saddr; | 1561 | const struct in6_addr *saddr; |
1562 | int hlen = LL_RESERVED_SPACE(dev); | 1562 | int hlen = LL_RESERVED_SPACE(dev); |
1563 | int tlen = dev->needed_tailroom; | 1563 | int tlen = dev->needed_tailroom; |
1564 | unsigned int size = mtu + hlen + tlen; | ||
1564 | int err; | 1565 | int err; |
1565 | u8 ra[8] = { IPPROTO_ICMPV6, 0, | 1566 | u8 ra[8] = { IPPROTO_ICMPV6, 0, |
1566 | IPV6_TLV_ROUTERALERT, 2, 0, 0, | 1567 | IPV6_TLV_ROUTERALERT, 2, 0, 0, |
1567 | IPV6_TLV_PADN, 0 }; | 1568 | IPV6_TLV_PADN, 0 }; |
1568 | 1569 | ||
1569 | /* we assume size > sizeof(ra) here */ | 1570 | /* we assume size > sizeof(ra) here */ |
1570 | size += hlen + tlen; | ||
1571 | /* limit our allocations to order-0 page */ | 1571 | /* limit our allocations to order-0 page */ |
1572 | size = min_t(int, size, SKB_MAX_ORDER(0, 0)); | 1572 | size = min_t(int, size, SKB_MAX_ORDER(0, 0)); |
1573 | skb = sock_alloc_send_skb(sk, size, 1, &err); | 1573 | skb = sock_alloc_send_skb(sk, size, 1, &err); |
@@ -1576,6 +1576,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size) | |||
1576 | return NULL; | 1576 | return NULL; |
1577 | 1577 | ||
1578 | skb->priority = TC_PRIO_CONTROL; | 1578 | skb->priority = TC_PRIO_CONTROL; |
1579 | skb->reserved_tailroom = skb_end_offset(skb) - | ||
1580 | min(mtu, skb_end_offset(skb)); | ||
1579 | skb_reserve(skb, hlen); | 1581 | skb_reserve(skb, hlen); |
1580 | 1582 | ||
1581 | if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) { | 1583 | if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) { |
@@ -1690,8 +1692,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1690 | return skb; | 1692 | return skb; |
1691 | } | 1693 | } |
1692 | 1694 | ||
1693 | #define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \ | 1695 | #define AVAILABLE(skb) ((skb) ? skb_availroom(skb) : 0) |
1694 | skb_tailroom(skb)) : 0) | ||
1695 | 1696 | ||
1696 | static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | 1697 | static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, |
1697 | int type, int gdeleted, int sdeleted, int crsend) | 1698 | int type, int gdeleted, int sdeleted, int crsend) |
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c index 8a7ac685076d..529c119cbb14 100644 --- a/net/ipv6/netfilter/nft_masq_ipv6.c +++ b/net/ipv6/netfilter/nft_masq_ipv6.c | |||
@@ -25,6 +25,7 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr, | |||
25 | struct nf_nat_range range; | 25 | struct nf_nat_range range; |
26 | unsigned int verdict; | 26 | unsigned int verdict; |
27 | 27 | ||
28 | memset(&range, 0, sizeof(range)); | ||
28 | range.flags = priv->flags; | 29 | range.flags = priv->flags; |
29 | 30 | ||
30 | verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); | 31 | verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ace29b60813c..dc495ae2ead0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -903,7 +903,10 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | |||
903 | if (th->rst) | 903 | if (th->rst) |
904 | return; | 904 | return; |
905 | 905 | ||
906 | if (!ipv6_unicast_destination(skb)) | 906 | /* If sk not NULL, it means we did a successful lookup and incoming |
907 | * route had to be correct. prequeue might have dropped our dst. | ||
908 | */ | ||
909 | if (!sk && !ipv6_unicast_destination(skb)) | ||
907 | return; | 910 | return; |
908 | 911 | ||
909 | #ifdef CONFIG_TCP_MD5SIG | 912 | #ifdef CONFIG_TCP_MD5SIG |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 91729b807c7d..1b095ca37aa4 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1764,6 +1764,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1764 | struct ipxhdr *ipx = NULL; | 1764 | struct ipxhdr *ipx = NULL; |
1765 | struct sk_buff *skb; | 1765 | struct sk_buff *skb; |
1766 | int copied, rc; | 1766 | int copied, rc; |
1767 | bool locked = true; | ||
1767 | 1768 | ||
1768 | lock_sock(sk); | 1769 | lock_sock(sk); |
1769 | /* put the autobinding in */ | 1770 | /* put the autobinding in */ |
@@ -1790,6 +1791,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1790 | if (sock_flag(sk, SOCK_ZAPPED)) | 1791 | if (sock_flag(sk, SOCK_ZAPPED)) |
1791 | goto out; | 1792 | goto out; |
1792 | 1793 | ||
1794 | release_sock(sk); | ||
1795 | locked = false; | ||
1793 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1796 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
1794 | flags & MSG_DONTWAIT, &rc); | 1797 | flags & MSG_DONTWAIT, &rc); |
1795 | if (!skb) { | 1798 | if (!skb) { |
@@ -1826,7 +1829,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1826 | out_free: | 1829 | out_free: |
1827 | skb_free_datagram(sk, skb); | 1830 | skb_free_datagram(sk, skb); |
1828 | out: | 1831 | out: |
1829 | release_sock(sk); | 1832 | if (locked) |
1833 | release_sock(sk); | ||
1830 | return rc; | 1834 | return rc; |
1831 | } | 1835 | } |
1832 | 1836 | ||
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index ec24378caaaf..09d9caaec591 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -53,6 +53,9 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, | |||
53 | __aligned(__alignof__(struct aead_request)); | 53 | __aligned(__alignof__(struct aead_request)); |
54 | struct aead_request *aead_req = (void *) aead_req_data; | 54 | struct aead_request *aead_req = (void *) aead_req_data; |
55 | 55 | ||
56 | if (data_len == 0) | ||
57 | return -EINVAL; | ||
58 | |||
56 | memset(aead_req, 0, sizeof(aead_req_data)); | 59 | memset(aead_req, 0, sizeof(aead_req_data)); |
57 | 60 | ||
58 | sg_init_one(&pt, data, data_len); | 61 | sg_init_one(&pt, data, data_len); |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index df90ce2db00c..408fd8ab4eef 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -252,19 +252,16 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, | |||
252 | cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp; | 252 | cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp; |
253 | cur_prob = mi->groups[cur_group].rates[cur_idx].probability; | 253 | cur_prob = mi->groups[cur_group].rates[cur_idx].probability; |
254 | 254 | ||
255 | tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; | 255 | do { |
256 | tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; | ||
257 | tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | ||
258 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; | ||
259 | |||
260 | while (j > 0 && (cur_thr > tmp_thr || | ||
261 | (cur_thr == tmp_thr && cur_prob > tmp_prob))) { | ||
262 | j--; | ||
263 | tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; | 256 | tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; |
264 | tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; | 257 | tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; |
265 | tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | 258 | tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp; |
266 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; | 259 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; |
267 | } | 260 | if (cur_thr < tmp_thr || |
261 | (cur_thr == tmp_thr && cur_prob <= tmp_prob)) | ||
262 | break; | ||
263 | j--; | ||
264 | } while (j > 0); | ||
268 | 265 | ||
269 | if (j < MAX_THR_RATES - 1) { | 266 | if (j < MAX_THR_RATES - 1) { |
270 | memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) * | 267 | memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) * |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 86f9d76b1464..d259da3ce67a 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
@@ -1863,6 +1863,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) | |||
1863 | if (*op < IP_SET_OP_VERSION) { | 1863 | if (*op < IP_SET_OP_VERSION) { |
1864 | /* Check the version at the beginning of operations */ | 1864 | /* Check the version at the beginning of operations */ |
1865 | struct ip_set_req_version *req_version = data; | 1865 | struct ip_set_req_version *req_version = data; |
1866 | |||
1867 | if (*len < sizeof(struct ip_set_req_version)) { | ||
1868 | ret = -EINVAL; | ||
1869 | goto done; | ||
1870 | } | ||
1871 | |||
1866 | if (req_version->version != IPSET_PROTOCOL) { | 1872 | if (req_version->version != IPSET_PROTOCOL) { |
1867 | ret = -EPROTO; | 1873 | ret = -EPROTO; |
1868 | goto done; | 1874 | goto done; |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 437a3663ad03..bd90bf8107da 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -846,6 +846,8 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af, | |||
846 | new_skb = skb_realloc_headroom(skb, max_headroom); | 846 | new_skb = skb_realloc_headroom(skb, max_headroom); |
847 | if (!new_skb) | 847 | if (!new_skb) |
848 | goto error; | 848 | goto error; |
849 | if (skb->sk) | ||
850 | skb_set_owner_w(new_skb, skb->sk); | ||
849 | consume_skb(skb); | 851 | consume_skb(skb); |
850 | skb = new_skb; | 852 | skb = new_skb; |
851 | } | 853 | } |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 11ab4b078f3b..66e8425dbfe7 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -3484,13 +3484,8 @@ static void nft_chain_commit_update(struct nft_trans *trans) | |||
3484 | } | 3484 | } |
3485 | } | 3485 | } |
3486 | 3486 | ||
3487 | /* Schedule objects for release via rcu to make sure no packets are accesing | 3487 | static void nf_tables_commit_release(struct nft_trans *trans) |
3488 | * removed rules. | ||
3489 | */ | ||
3490 | static void nf_tables_commit_release_rcu(struct rcu_head *rt) | ||
3491 | { | 3488 | { |
3492 | struct nft_trans *trans = container_of(rt, struct nft_trans, rcu_head); | ||
3493 | |||
3494 | switch (trans->msg_type) { | 3489 | switch (trans->msg_type) { |
3495 | case NFT_MSG_DELTABLE: | 3490 | case NFT_MSG_DELTABLE: |
3496 | nf_tables_table_destroy(&trans->ctx); | 3491 | nf_tables_table_destroy(&trans->ctx); |
@@ -3612,10 +3607,11 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
3612 | } | 3607 | } |
3613 | } | 3608 | } |
3614 | 3609 | ||
3610 | synchronize_rcu(); | ||
3611 | |||
3615 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { | 3612 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { |
3616 | list_del(&trans->list); | 3613 | list_del(&trans->list); |
3617 | trans->ctx.nla = NULL; | 3614 | nf_tables_commit_release(trans); |
3618 | call_rcu(&trans->rcu_head, nf_tables_commit_release_rcu); | ||
3619 | } | 3615 | } |
3620 | 3616 | ||
3621 | nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN); | 3617 | nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN); |
@@ -3623,13 +3619,8 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
3623 | return 0; | 3619 | return 0; |
3624 | } | 3620 | } |
3625 | 3621 | ||
3626 | /* Schedule objects for release via rcu to make sure no packets are accesing | 3622 | static void nf_tables_abort_release(struct nft_trans *trans) |
3627 | * aborted rules. | ||
3628 | */ | ||
3629 | static void nf_tables_abort_release_rcu(struct rcu_head *rt) | ||
3630 | { | 3623 | { |
3631 | struct nft_trans *trans = container_of(rt, struct nft_trans, rcu_head); | ||
3632 | |||
3633 | switch (trans->msg_type) { | 3624 | switch (trans->msg_type) { |
3634 | case NFT_MSG_NEWTABLE: | 3625 | case NFT_MSG_NEWTABLE: |
3635 | nf_tables_table_destroy(&trans->ctx); | 3626 | nf_tables_table_destroy(&trans->ctx); |
@@ -3725,11 +3716,12 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3725 | } | 3716 | } |
3726 | } | 3717 | } |
3727 | 3718 | ||
3719 | synchronize_rcu(); | ||
3720 | |||
3728 | list_for_each_entry_safe_reverse(trans, next, | 3721 | list_for_each_entry_safe_reverse(trans, next, |
3729 | &net->nft.commit_list, list) { | 3722 | &net->nft.commit_list, list) { |
3730 | list_del(&trans->list); | 3723 | list_del(&trans->list); |
3731 | trans->ctx.nla = NULL; | 3724 | nf_tables_abort_release(trans); |
3732 | call_rcu(&trans->rcu_head, nf_tables_abort_release_rcu); | ||
3733 | } | 3725 | } |
3734 | 3726 | ||
3735 | return 0; | 3727 | return 0; |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 6c5a915cfa75..13c2e17bbe27 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -47,6 +47,8 @@ static const int nfnl_group2type[NFNLGRP_MAX+1] = { | |||
47 | [NFNLGRP_CONNTRACK_EXP_NEW] = NFNL_SUBSYS_CTNETLINK_EXP, | 47 | [NFNLGRP_CONNTRACK_EXP_NEW] = NFNL_SUBSYS_CTNETLINK_EXP, |
48 | [NFNLGRP_CONNTRACK_EXP_UPDATE] = NFNL_SUBSYS_CTNETLINK_EXP, | 48 | [NFNLGRP_CONNTRACK_EXP_UPDATE] = NFNL_SUBSYS_CTNETLINK_EXP, |
49 | [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP, | 49 | [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP, |
50 | [NFNLGRP_NFTABLES] = NFNL_SUBSYS_NFTABLES, | ||
51 | [NFNLGRP_ACCT_QUOTA] = NFNL_SUBSYS_ACCT, | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | void nfnl_lock(__u8 subsys_id) | 54 | void nfnl_lock(__u8 subsys_id) |
@@ -464,7 +466,12 @@ static void nfnetlink_rcv(struct sk_buff *skb) | |||
464 | static int nfnetlink_bind(int group) | 466 | static int nfnetlink_bind(int group) |
465 | { | 467 | { |
466 | const struct nfnetlink_subsystem *ss; | 468 | const struct nfnetlink_subsystem *ss; |
467 | int type = nfnl_group2type[group]; | 469 | int type; |
470 | |||
471 | if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX) | ||
472 | return -EINVAL; | ||
473 | |||
474 | type = nfnl_group2type[group]; | ||
468 | 475 | ||
469 | rcu_read_lock(); | 476 | rcu_read_lock(); |
470 | ss = nfnetlink_get_subsys(type); | 477 | ss = nfnetlink_get_subsys(type); |
@@ -514,6 +521,9 @@ static int __init nfnetlink_init(void) | |||
514 | { | 521 | { |
515 | int i; | 522 | int i; |
516 | 523 | ||
524 | for (i = NFNLGRP_NONE + 1; i <= NFNLGRP_MAX; i++) | ||
525 | BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE); | ||
526 | |||
517 | for (i=0; i<NFNL_SUBSYS_COUNT; i++) | 527 | for (i=0; i<NFNL_SUBSYS_COUNT; i++) |
518 | mutex_init(&table[i].mutex); | 528 | mutex_init(&table[i].mutex); |
519 | 529 | ||
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 9d6d6f60a80f..265e190f2218 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c | |||
@@ -21,45 +21,17 @@ | |||
21 | #include <linux/netfilter_ipv6/ip6_tables.h> | 21 | #include <linux/netfilter_ipv6/ip6_tables.h> |
22 | #include <net/netfilter/nf_tables.h> | 22 | #include <net/netfilter/nf_tables.h> |
23 | 23 | ||
24 | static const struct { | ||
25 | const char *name; | ||
26 | u8 type; | ||
27 | } table_to_chaintype[] = { | ||
28 | { "filter", NFT_CHAIN_T_DEFAULT }, | ||
29 | { "raw", NFT_CHAIN_T_DEFAULT }, | ||
30 | { "security", NFT_CHAIN_T_DEFAULT }, | ||
31 | { "mangle", NFT_CHAIN_T_ROUTE }, | ||
32 | { "nat", NFT_CHAIN_T_NAT }, | ||
33 | { }, | ||
34 | }; | ||
35 | |||
36 | static int nft_compat_table_to_chaintype(const char *table) | ||
37 | { | ||
38 | int i; | ||
39 | |||
40 | for (i = 0; table_to_chaintype[i].name != NULL; i++) { | ||
41 | if (strcmp(table_to_chaintype[i].name, table) == 0) | ||
42 | return table_to_chaintype[i].type; | ||
43 | } | ||
44 | |||
45 | return -1; | ||
46 | } | ||
47 | |||
48 | static int nft_compat_chain_validate_dependency(const char *tablename, | 24 | static int nft_compat_chain_validate_dependency(const char *tablename, |
49 | const struct nft_chain *chain) | 25 | const struct nft_chain *chain) |
50 | { | 26 | { |
51 | enum nft_chain_type type; | ||
52 | const struct nft_base_chain *basechain; | 27 | const struct nft_base_chain *basechain; |
53 | 28 | ||
54 | if (!tablename || !(chain->flags & NFT_BASE_CHAIN)) | 29 | if (!tablename || !(chain->flags & NFT_BASE_CHAIN)) |
55 | return 0; | 30 | return 0; |
56 | 31 | ||
57 | type = nft_compat_table_to_chaintype(tablename); | ||
58 | if (type < 0) | ||
59 | return -EINVAL; | ||
60 | |||
61 | basechain = nft_base_chain(chain); | 32 | basechain = nft_base_chain(chain); |
62 | if (basechain->type->type != type) | 33 | if (strcmp(tablename, "nat") == 0 && |
34 | basechain->type->type != NFT_CHAIN_T_NAT) | ||
63 | return -EINVAL; | 35 | return -EINVAL; |
64 | 36 | ||
65 | return 0; | 37 | return 0; |
@@ -117,7 +89,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par, | |||
117 | struct xt_target *target, void *info, | 89 | struct xt_target *target, void *info, |
118 | union nft_entry *entry, u8 proto, bool inv) | 90 | union nft_entry *entry, u8 proto, bool inv) |
119 | { | 91 | { |
120 | par->net = &init_net; | 92 | par->net = ctx->net; |
121 | par->table = ctx->table->name; | 93 | par->table = ctx->table->name; |
122 | switch (ctx->afi->family) { | 94 | switch (ctx->afi->family) { |
123 | case AF_INET: | 95 | case AF_INET: |
@@ -324,7 +296,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, | |||
324 | struct xt_match *match, void *info, | 296 | struct xt_match *match, void *info, |
325 | union nft_entry *entry, u8 proto, bool inv) | 297 | union nft_entry *entry, u8 proto, bool inv) |
326 | { | 298 | { |
327 | par->net = &init_net; | 299 | par->net = ctx->net; |
328 | par->table = ctx->table->name; | 300 | par->table = ctx->table->name; |
329 | switch (ctx->afi->family) { | 301 | switch (ctx->afi->family) { |
330 | case AF_INET: | 302 | case AF_INET: |
@@ -374,7 +346,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
374 | union nft_entry e = {}; | 346 | union nft_entry e = {}; |
375 | int ret; | 347 | int ret; |
376 | 348 | ||
377 | ret = nft_compat_chain_validate_dependency(match->name, ctx->chain); | 349 | ret = nft_compat_chain_validate_dependency(match->table, ctx->chain); |
378 | if (ret < 0) | 350 | if (ret < 0) |
379 | goto err; | 351 | goto err; |
380 | 352 | ||
@@ -448,7 +420,7 @@ static int nft_match_validate(const struct nft_ctx *ctx, | |||
448 | if (!(hook_mask & match->hooks)) | 420 | if (!(hook_mask & match->hooks)) |
449 | return -EINVAL; | 421 | return -EINVAL; |
450 | 422 | ||
451 | ret = nft_compat_chain_validate_dependency(match->name, | 423 | ret = nft_compat_chain_validate_dependency(match->table, |
452 | ctx->chain); | 424 | ctx->chain); |
453 | if (ret < 0) | 425 | if (ret < 0) |
454 | return ret; | 426 | return ret; |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 006886dbee36..8c4229b11c34 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -246,11 +246,11 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto, | |||
246 | { | 246 | { |
247 | int transport_len = skb->len - skb_transport_offset(skb); | 247 | int transport_len = skb->len - skb_transport_offset(skb); |
248 | 248 | ||
249 | if (l4_proto == IPPROTO_TCP) { | 249 | if (l4_proto == NEXTHDR_TCP) { |
250 | if (likely(transport_len >= sizeof(struct tcphdr))) | 250 | if (likely(transport_len >= sizeof(struct tcphdr))) |
251 | inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb, | 251 | inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb, |
252 | addr, new_addr, 1); | 252 | addr, new_addr, 1); |
253 | } else if (l4_proto == IPPROTO_UDP) { | 253 | } else if (l4_proto == NEXTHDR_UDP) { |
254 | if (likely(transport_len >= sizeof(struct udphdr))) { | 254 | if (likely(transport_len >= sizeof(struct udphdr))) { |
255 | struct udphdr *uh = udp_hdr(skb); | 255 | struct udphdr *uh = udp_hdr(skb); |
256 | 256 | ||
@@ -261,6 +261,10 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto, | |||
261 | uh->check = CSUM_MANGLED_0; | 261 | uh->check = CSUM_MANGLED_0; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | } else if (l4_proto == NEXTHDR_ICMP) { | ||
265 | if (likely(transport_len >= sizeof(struct icmp6hdr))) | ||
266 | inet_proto_csum_replace16(&icmp6_hdr(skb)->icmp6_cksum, | ||
267 | skb, addr, new_addr, 1); | ||
264 | } | 268 | } |
265 | } | 269 | } |
266 | 270 | ||
@@ -722,8 +726,6 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
722 | 726 | ||
723 | case OVS_ACTION_ATTR_SAMPLE: | 727 | case OVS_ACTION_ATTR_SAMPLE: |
724 | err = sample(dp, skb, key, a); | 728 | err = sample(dp, skb, key, a); |
725 | if (unlikely(err)) /* skb already freed. */ | ||
726 | return err; | ||
727 | break; | 729 | break; |
728 | } | 730 | } |
729 | 731 | ||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e6d7255183eb..f9e556b56086 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1265,7 +1265,7 @@ static size_t ovs_dp_cmd_msg_size(void) | |||
1265 | return msgsize; | 1265 | return msgsize; |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | /* Called with ovs_mutex or RCU read lock. */ | 1268 | /* Called with ovs_mutex. */ |
1269 | static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, | 1269 | static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, |
1270 | u32 portid, u32 seq, u32 flags, u8 cmd) | 1270 | u32 portid, u32 seq, u32 flags, u8 cmd) |
1271 | { | 1271 | { |
@@ -1555,7 +1555,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
1555 | if (!reply) | 1555 | if (!reply) |
1556 | return -ENOMEM; | 1556 | return -ENOMEM; |
1557 | 1557 | ||
1558 | rcu_read_lock(); | 1558 | ovs_lock(); |
1559 | dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); | 1559 | dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); |
1560 | if (IS_ERR(dp)) { | 1560 | if (IS_ERR(dp)) { |
1561 | err = PTR_ERR(dp); | 1561 | err = PTR_ERR(dp); |
@@ -1564,12 +1564,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
1564 | err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid, | 1564 | err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid, |
1565 | info->snd_seq, 0, OVS_DP_CMD_NEW); | 1565 | info->snd_seq, 0, OVS_DP_CMD_NEW); |
1566 | BUG_ON(err < 0); | 1566 | BUG_ON(err < 0); |
1567 | rcu_read_unlock(); | 1567 | ovs_unlock(); |
1568 | 1568 | ||
1569 | return genlmsg_reply(reply, info); | 1569 | return genlmsg_reply(reply, info); |
1570 | 1570 | ||
1571 | err_unlock_free: | 1571 | err_unlock_free: |
1572 | rcu_read_unlock(); | 1572 | ovs_unlock(); |
1573 | kfree_skb(reply); | 1573 | kfree_skb(reply); |
1574 | return err; | 1574 | return err; |
1575 | } | 1575 | } |
@@ -1581,8 +1581,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1581 | int skip = cb->args[0]; | 1581 | int skip = cb->args[0]; |
1582 | int i = 0; | 1582 | int i = 0; |
1583 | 1583 | ||
1584 | rcu_read_lock(); | 1584 | ovs_lock(); |
1585 | list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) { | 1585 | list_for_each_entry(dp, &ovs_net->dps, list_node) { |
1586 | if (i >= skip && | 1586 | if (i >= skip && |
1587 | ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, | 1587 | ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, |
1588 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1588 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
@@ -1590,7 +1590,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1590 | break; | 1590 | break; |
1591 | i++; | 1591 | i++; |
1592 | } | 1592 | } |
1593 | rcu_read_unlock(); | 1593 | ovs_unlock(); |
1594 | 1594 | ||
1595 | cb->args[0] = i; | 1595 | cb->args[0] = i; |
1596 | 1596 | ||
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 939bcb32100f..089b195c064a 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -145,7 +145,7 @@ static bool match_validate(const struct sw_flow_match *match, | |||
145 | if (match->key->eth.type == htons(ETH_P_ARP) | 145 | if (match->key->eth.type == htons(ETH_P_ARP) |
146 | || match->key->eth.type == htons(ETH_P_RARP)) { | 146 | || match->key->eth.type == htons(ETH_P_RARP)) { |
147 | key_expected |= 1 << OVS_KEY_ATTR_ARP; | 147 | key_expected |= 1 << OVS_KEY_ATTR_ARP; |
148 | if (match->mask && (match->mask->key.eth.type == htons(0xffff))) | 148 | if (match->mask && (match->mask->key.tp.src == htons(0xff))) |
149 | mask_allowed |= 1 << OVS_KEY_ATTR_ARP; | 149 | mask_allowed |= 1 << OVS_KEY_ATTR_ARP; |
150 | } | 150 | } |
151 | 151 | ||
@@ -689,6 +689,13 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
689 | ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); | 689 | ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); |
690 | return -EINVAL; | 690 | return -EINVAL; |
691 | } | 691 | } |
692 | |||
693 | if (!is_mask && ipv6_key->ipv6_label & htonl(0xFFF00000)) { | ||
694 | OVS_NLERR("IPv6 flow label %x is out of range (max=%x).\n", | ||
695 | ntohl(ipv6_key->ipv6_label), (1 << 20) - 1); | ||
696 | return -EINVAL; | ||
697 | } | ||
698 | |||
692 | SW_FLOW_KEY_PUT(match, ipv6.label, | 699 | SW_FLOW_KEY_PUT(match, ipv6.label, |
693 | ipv6_key->ipv6_label, is_mask); | 700 | ipv6_key->ipv6_label, is_mask); |
694 | SW_FLOW_KEY_PUT(match, ip.proto, | 701 | SW_FLOW_KEY_PUT(match, ip.proto, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 87d20f48ff06..07c04a841ba0 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -378,7 +378,7 @@ static void unregister_prot_hook(struct sock *sk, bool sync) | |||
378 | __unregister_prot_hook(sk, sync); | 378 | __unregister_prot_hook(sk, sync); |
379 | } | 379 | } |
380 | 380 | ||
381 | static inline __pure struct page *pgv_to_page(void *addr) | 381 | static inline struct page * __pure pgv_to_page(void *addr) |
382 | { | 382 | { |
383 | if (is_vmalloc_addr(addr)) | 383 | if (is_vmalloc_addr(addr)) |
384 | return vmalloc_to_page(addr); | 384 | return vmalloc_to_page(addr); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 3f959c681885..f9c052d508f0 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -1019,17 +1019,12 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
1019 | xid = *p++; | 1019 | xid = *p++; |
1020 | calldir = *p; | 1020 | calldir = *p; |
1021 | 1021 | ||
1022 | if (bc_xprt) | 1022 | if (!bc_xprt) |
1023 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1024 | |||
1025 | if (!req) { | ||
1026 | printk(KERN_NOTICE | ||
1027 | "%s: Got unrecognized reply: " | ||
1028 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1029 | __func__, ntohl(calldir), | ||
1030 | bc_xprt, ntohl(xid)); | ||
1031 | return -EAGAIN; | 1023 | return -EAGAIN; |
1032 | } | 1024 | spin_lock_bh(&bc_xprt->transport_lock); |
1025 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1026 | if (!req) | ||
1027 | goto unlock_notfound; | ||
1033 | 1028 | ||
1034 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); | 1029 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); |
1035 | /* | 1030 | /* |
@@ -1040,11 +1035,21 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
1040 | dst = &req->rq_private_buf.head[0]; | 1035 | dst = &req->rq_private_buf.head[0]; |
1041 | src = &rqstp->rq_arg.head[0]; | 1036 | src = &rqstp->rq_arg.head[0]; |
1042 | if (dst->iov_len < src->iov_len) | 1037 | if (dst->iov_len < src->iov_len) |
1043 | return -EAGAIN; /* whatever; just giving up. */ | 1038 | goto unlock_eagain; /* whatever; just giving up. */ |
1044 | memcpy(dst->iov_base, src->iov_base, src->iov_len); | 1039 | memcpy(dst->iov_base, src->iov_base, src->iov_len); |
1045 | xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); | 1040 | xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); |
1046 | rqstp->rq_arg.len = 0; | 1041 | rqstp->rq_arg.len = 0; |
1042 | spin_unlock_bh(&bc_xprt->transport_lock); | ||
1047 | return 0; | 1043 | return 0; |
1044 | unlock_notfound: | ||
1045 | printk(KERN_NOTICE | ||
1046 | "%s: Got unrecognized reply: " | ||
1047 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1048 | __func__, ntohl(calldir), | ||
1049 | bc_xprt, ntohl(xid)); | ||
1050 | unlock_eagain: | ||
1051 | spin_unlock_bh(&bc_xprt->transport_lock); | ||
1052 | return -EAGAIN; | ||
1048 | } | 1053 | } |
1049 | 1054 | ||
1050 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) | 1055 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) |
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 401107b85d30..23c371ecfb6b 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c | |||
@@ -243,13 +243,7 @@ static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol, | |||
243 | { | 243 | { |
244 | static const char * const texts[] = { "Line-In", "Microphone" }; | 244 | static const char * const texts[] = { "Line-In", "Microphone" }; |
245 | 245 | ||
246 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 246 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
247 | uinfo->count = 1; | ||
248 | uinfo->value.enumerated.items = 2; | ||
249 | if (uinfo->value.enumerated.item > 1) | ||
250 | uinfo->value.enumerated.item = 1; | ||
251 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
252 | return 0; | ||
253 | } | 247 | } |
254 | 248 | ||
255 | static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol, | 249 | static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index cf3c6303b7e3..364c7c4416e8 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c | |||
@@ -478,15 +478,9 @@ static struct snd_kcontrol_new drc_switch_control = { | |||
478 | static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol, | 478 | static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol, |
479 | struct snd_ctl_elem_info *uinfo) | 479 | struct snd_ctl_elem_info *uinfo) |
480 | { | 480 | { |
481 | static char *texts[] = { "Line-In", "Microphone" }; | 481 | static const char * const texts[] = { "Line-In", "Microphone" }; |
482 | 482 | ||
483 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 483 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
484 | uinfo->count = 1; | ||
485 | uinfo->value.enumerated.items = 2; | ||
486 | if (uinfo->value.enumerated.item > 1) | ||
487 | uinfo->value.enumerated.item = 1; | ||
488 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
489 | return 0; | ||
490 | } | 484 | } |
491 | 485 | ||
492 | static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol, | 486 | static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index a80d5ea87ccd..4e2b4fbf2496 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c | |||
@@ -79,8 +79,7 @@ static void i2sbus_release_dev(struct device *dev) | |||
79 | if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma); | 79 | if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma); |
80 | if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma); | 80 | if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma); |
81 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) | 81 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) |
82 | if (i2sdev->allocated_resource[i]) | 82 | release_and_free_resource(i2sdev->allocated_resource[i]); |
83 | release_and_free_resource(i2sdev->allocated_resource[i]); | ||
84 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); | 83 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); |
85 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring); | 84 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring); |
86 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) | 85 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) |
@@ -323,8 +322,7 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
323 | if (dev->out.dbdma) iounmap(dev->out.dbdma); | 322 | if (dev->out.dbdma) iounmap(dev->out.dbdma); |
324 | if (dev->in.dbdma) iounmap(dev->in.dbdma); | 323 | if (dev->in.dbdma) iounmap(dev->in.dbdma); |
325 | for (i=0;i<3;i++) | 324 | for (i=0;i<3;i++) |
326 | if (dev->allocated_resource[i]) | 325 | release_and_free_resource(dev->allocated_resource[i]); |
327 | release_and_free_resource(dev->allocated_resource[i]); | ||
328 | mutex_destroy(&dev->lock); | 326 | mutex_destroy(&dev->lock); |
329 | kfree(dev); | 327 | kfree(dev); |
330 | return 0; | 328 | return 0; |
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c index a61d7a9a995e..01f8fdc42b1b 100644 --- a/sound/arm/pxa2xx-pcm-lib.c +++ b/sound/arm/pxa2xx-pcm-lib.c | |||
@@ -200,9 +200,7 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) | |||
200 | } else { | 200 | } else { |
201 | printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n", | 201 | printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n", |
202 | dma_ch, dcsr); | 202 | dma_ch, dcsr); |
203 | snd_pcm_stream_lock(substream); | 203 | snd_pcm_stop_xrun(substream); |
204 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
205 | snd_pcm_stream_unlock(substream); | ||
206 | } | 204 | } |
207 | } | 205 | } |
208 | EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); | 206 | EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); |
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c index 31061e3521d4..023140504104 100644 --- a/sound/atmel/abdac.c +++ b/sound/atmel/abdac.c | |||
@@ -242,7 +242,7 @@ static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd) | |||
242 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 242 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
243 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 243 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
244 | case SNDRV_PCM_TRIGGER_START: | 244 | case SNDRV_PCM_TRIGGER_START: |
245 | clk_enable(dac->sample_clk); | 245 | clk_prepare_enable(dac->sample_clk); |
246 | retval = dw_dma_cyclic_start(dac->dma.chan); | 246 | retval = dw_dma_cyclic_start(dac->dma.chan); |
247 | if (retval) | 247 | if (retval) |
248 | goto out; | 248 | goto out; |
@@ -254,7 +254,7 @@ static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd) | |||
254 | dw_dma_cyclic_stop(dac->dma.chan); | 254 | dw_dma_cyclic_stop(dac->dma.chan); |
255 | dac_writel(dac, DATA, 0); | 255 | dac_writel(dac, DATA, 0); |
256 | dac_writel(dac, CTRL, 0); | 256 | dac_writel(dac, CTRL, 0); |
257 | clk_disable(dac->sample_clk); | 257 | clk_disable_unprepare(dac->sample_clk); |
258 | break; | 258 | break; |
259 | default: | 259 | default: |
260 | retval = -EINVAL; | 260 | retval = -EINVAL; |
@@ -429,7 +429,7 @@ static int atmel_abdac_probe(struct platform_device *pdev) | |||
429 | retval = PTR_ERR(sample_clk); | 429 | retval = PTR_ERR(sample_clk); |
430 | goto out_put_pclk; | 430 | goto out_put_pclk; |
431 | } | 431 | } |
432 | clk_enable(pclk); | 432 | clk_prepare_enable(pclk); |
433 | 433 | ||
434 | retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, | 434 | retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, |
435 | SNDRV_DEFAULT_STR1, THIS_MODULE, | 435 | SNDRV_DEFAULT_STR1, THIS_MODULE, |
@@ -528,7 +528,7 @@ out_free_card: | |||
528 | snd_card_free(card); | 528 | snd_card_free(card); |
529 | out_put_sample_clk: | 529 | out_put_sample_clk: |
530 | clk_put(sample_clk); | 530 | clk_put(sample_clk); |
531 | clk_disable(pclk); | 531 | clk_disable_unprepare(pclk); |
532 | out_put_pclk: | 532 | out_put_pclk: |
533 | clk_put(pclk); | 533 | clk_put(pclk); |
534 | return retval; | 534 | return retval; |
@@ -541,8 +541,8 @@ static int atmel_abdac_suspend(struct device *pdev) | |||
541 | struct atmel_abdac *dac = card->private_data; | 541 | struct atmel_abdac *dac = card->private_data; |
542 | 542 | ||
543 | dw_dma_cyclic_stop(dac->dma.chan); | 543 | dw_dma_cyclic_stop(dac->dma.chan); |
544 | clk_disable(dac->sample_clk); | 544 | clk_disable_unprepare(dac->sample_clk); |
545 | clk_disable(dac->pclk); | 545 | clk_disable_unprepare(dac->pclk); |
546 | 546 | ||
547 | return 0; | 547 | return 0; |
548 | } | 548 | } |
@@ -552,8 +552,8 @@ static int atmel_abdac_resume(struct device *pdev) | |||
552 | struct snd_card *card = dev_get_drvdata(pdev); | 552 | struct snd_card *card = dev_get_drvdata(pdev); |
553 | struct atmel_abdac *dac = card->private_data; | 553 | struct atmel_abdac *dac = card->private_data; |
554 | 554 | ||
555 | clk_enable(dac->pclk); | 555 | clk_prepare_enable(dac->pclk); |
556 | clk_enable(dac->sample_clk); | 556 | clk_prepare_enable(dac->sample_clk); |
557 | if (test_bit(DMA_READY, &dac->flags)) | 557 | if (test_bit(DMA_READY, &dac->flags)) |
558 | dw_dma_cyclic_start(dac->dma.chan); | 558 | dw_dma_cyclic_start(dac->dma.chan); |
559 | 559 | ||
@@ -572,7 +572,7 @@ static int atmel_abdac_remove(struct platform_device *pdev) | |||
572 | struct atmel_abdac *dac = get_dac(card); | 572 | struct atmel_abdac *dac = get_dac(card); |
573 | 573 | ||
574 | clk_put(dac->sample_clk); | 574 | clk_put(dac->sample_clk); |
575 | clk_disable(dac->pclk); | 575 | clk_disable_unprepare(dac->pclk); |
576 | clk_put(dac->pclk); | 576 | clk_put(dac->pclk); |
577 | 577 | ||
578 | dma_release_channel(dac->dma.chan); | 578 | dma_release_channel(dac->dma.chan); |
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index b59427d5a697..cb44c74c9702 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -773,7 +773,7 @@ static int atmel_ac97c_pcm_new(struct atmel_ac97c *chip) | |||
773 | return err; | 773 | return err; |
774 | } | 774 | } |
775 | retval = snd_pcm_new(chip->card, chip->card->shortname, | 775 | retval = snd_pcm_new(chip->card, chip->card->shortname, |
776 | chip->pdev->id, playback, capture, &pcm); | 776 | 0, playback, capture, &pcm); |
777 | if (retval) | 777 | if (retval) |
778 | return retval; | 778 | return retval; |
779 | 779 | ||
@@ -944,7 +944,7 @@ static int atmel_ac97c_probe(struct platform_device *pdev) | |||
944 | dev_dbg(&pdev->dev, "no peripheral clock\n"); | 944 | dev_dbg(&pdev->dev, "no peripheral clock\n"); |
945 | return PTR_ERR(pclk); | 945 | return PTR_ERR(pclk); |
946 | } | 946 | } |
947 | clk_enable(pclk); | 947 | clk_prepare_enable(pclk); |
948 | 948 | ||
949 | retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, | 949 | retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, |
950 | SNDRV_DEFAULT_STR1, THIS_MODULE, | 950 | SNDRV_DEFAULT_STR1, THIS_MODULE, |
@@ -1122,7 +1122,7 @@ err_ioremap: | |||
1122 | err_request_irq: | 1122 | err_request_irq: |
1123 | snd_card_free(card); | 1123 | snd_card_free(card); |
1124 | err_snd_card_new: | 1124 | err_snd_card_new: |
1125 | clk_disable(pclk); | 1125 | clk_disable_unprepare(pclk); |
1126 | clk_put(pclk); | 1126 | clk_put(pclk); |
1127 | return retval; | 1127 | return retval; |
1128 | } | 1128 | } |
@@ -1139,7 +1139,7 @@ static int atmel_ac97c_suspend(struct device *pdev) | |||
1139 | if (test_bit(DMA_TX_READY, &chip->flags)) | 1139 | if (test_bit(DMA_TX_READY, &chip->flags)) |
1140 | dw_dma_cyclic_stop(chip->dma.tx_chan); | 1140 | dw_dma_cyclic_stop(chip->dma.tx_chan); |
1141 | } | 1141 | } |
1142 | clk_disable(chip->pclk); | 1142 | clk_disable_unprepare(chip->pclk); |
1143 | 1143 | ||
1144 | return 0; | 1144 | return 0; |
1145 | } | 1145 | } |
@@ -1149,7 +1149,7 @@ static int atmel_ac97c_resume(struct device *pdev) | |||
1149 | struct snd_card *card = dev_get_drvdata(pdev); | 1149 | struct snd_card *card = dev_get_drvdata(pdev); |
1150 | struct atmel_ac97c *chip = card->private_data; | 1150 | struct atmel_ac97c *chip = card->private_data; |
1151 | 1151 | ||
1152 | clk_enable(chip->pclk); | 1152 | clk_prepare_enable(chip->pclk); |
1153 | if (cpu_is_at32ap7000()) { | 1153 | if (cpu_is_at32ap7000()) { |
1154 | if (test_bit(DMA_RX_READY, &chip->flags)) | 1154 | if (test_bit(DMA_RX_READY, &chip->flags)) |
1155 | dw_dma_cyclic_start(chip->dma.rx_chan); | 1155 | dw_dma_cyclic_start(chip->dma.rx_chan); |
@@ -1177,7 +1177,7 @@ static int atmel_ac97c_remove(struct platform_device *pdev) | |||
1177 | ac97c_writel(chip, COMR, 0); | 1177 | ac97c_writel(chip, COMR, 0); |
1178 | ac97c_writel(chip, MR, 0); | 1178 | ac97c_writel(chip, MR, 0); |
1179 | 1179 | ||
1180 | clk_disable(chip->pclk); | 1180 | clk_disable_unprepare(chip->pclk); |
1181 | clk_put(chip->pclk); | 1181 | clk_put(chip->pclk); |
1182 | iounmap(chip->regs); | 1182 | iounmap(chip->regs); |
1183 | free_irq(chip->irq, chip); | 1183 | free_irq(chip->irq, chip); |
diff --git a/sound/core/Makefile b/sound/core/Makefile index 394a38909f6b..4daf2f58261c 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile | |||
@@ -14,6 +14,9 @@ snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ | |||
14 | pcm_memory.o memalloc.o | 14 | pcm_memory.o memalloc.o |
15 | snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o | 15 | snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o |
16 | 16 | ||
17 | # for trace-points | ||
18 | CFLAGS_pcm_lib.o := -I$(src) | ||
19 | |||
17 | snd-pcm-dmaengine-objs := pcm_dmaengine.o | 20 | snd-pcm-dmaengine-objs := pcm_dmaengine.o |
18 | 21 | ||
19 | snd-rawmidi-objs := rawmidi.o | 22 | snd-rawmidi-objs := rawmidi.o |
diff --git a/sound/core/control.c b/sound/core/control.c index b9611344ff9e..bb96a467e88d 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -141,6 +141,16 @@ static int snd_ctl_release(struct inode *inode, struct file *file) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | /** | ||
145 | * snd_ctl_notify - Send notification to user-space for a control change | ||
146 | * @card: the card to send notification | ||
147 | * @mask: the event mask, SNDRV_CTL_EVENT_* | ||
148 | * @id: the ctl element id to send notification | ||
149 | * | ||
150 | * This function adds an event record with the given id and mask, appends | ||
151 | * to the list and wakes up the user-space for notification. This can be | ||
152 | * called in the atomic context. | ||
153 | */ | ||
144 | void snd_ctl_notify(struct snd_card *card, unsigned int mask, | 154 | void snd_ctl_notify(struct snd_card *card, unsigned int mask, |
145 | struct snd_ctl_elem_id *id) | 155 | struct snd_ctl_elem_id *id) |
146 | { | 156 | { |
@@ -179,7 +189,6 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, | |||
179 | } | 189 | } |
180 | read_unlock(&card->ctl_files_rwlock); | 190 | read_unlock(&card->ctl_files_rwlock); |
181 | } | 191 | } |
182 | |||
183 | EXPORT_SYMBOL(snd_ctl_notify); | 192 | EXPORT_SYMBOL(snd_ctl_notify); |
184 | 193 | ||
185 | /** | 194 | /** |
@@ -261,7 +270,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, | |||
261 | kctl.private_data = private_data; | 270 | kctl.private_data = private_data; |
262 | return snd_ctl_new(&kctl, access); | 271 | return snd_ctl_new(&kctl, access); |
263 | } | 272 | } |
264 | |||
265 | EXPORT_SYMBOL(snd_ctl_new1); | 273 | EXPORT_SYMBOL(snd_ctl_new1); |
266 | 274 | ||
267 | /** | 275 | /** |
@@ -280,7 +288,6 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) | |||
280 | kfree(kcontrol); | 288 | kfree(kcontrol); |
281 | } | 289 | } |
282 | } | 290 | } |
283 | |||
284 | EXPORT_SYMBOL(snd_ctl_free_one); | 291 | EXPORT_SYMBOL(snd_ctl_free_one); |
285 | 292 | ||
286 | static bool snd_ctl_remove_numid_conflict(struct snd_card *card, | 293 | static bool snd_ctl_remove_numid_conflict(struct snd_card *card, |
@@ -376,7 +383,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
376 | snd_ctl_free_one(kcontrol); | 383 | snd_ctl_free_one(kcontrol); |
377 | return err; | 384 | return err; |
378 | } | 385 | } |
379 | |||
380 | EXPORT_SYMBOL(snd_ctl_add); | 386 | EXPORT_SYMBOL(snd_ctl_add); |
381 | 387 | ||
382 | /** | 388 | /** |
@@ -471,7 +477,6 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
471 | snd_ctl_free_one(kcontrol); | 477 | snd_ctl_free_one(kcontrol); |
472 | return 0; | 478 | return 0; |
473 | } | 479 | } |
474 | |||
475 | EXPORT_SYMBOL(snd_ctl_remove); | 480 | EXPORT_SYMBOL(snd_ctl_remove); |
476 | 481 | ||
477 | /** | 482 | /** |
@@ -499,7 +504,6 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) | |||
499 | up_write(&card->controls_rwsem); | 504 | up_write(&card->controls_rwsem); |
500 | return ret; | 505 | return ret; |
501 | } | 506 | } |
502 | |||
503 | EXPORT_SYMBOL(snd_ctl_remove_id); | 507 | EXPORT_SYMBOL(snd_ctl_remove_id); |
504 | 508 | ||
505 | /** | 509 | /** |
@@ -568,7 +572,7 @@ int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, | |||
568 | ret = -ENOENT; | 572 | ret = -ENOENT; |
569 | goto unlock; | 573 | goto unlock; |
570 | } | 574 | } |
571 | index_offset = snd_ctl_get_ioff(kctl, &kctl->id); | 575 | index_offset = snd_ctl_get_ioff(kctl, id); |
572 | vd = &kctl->vd[index_offset]; | 576 | vd = &kctl->vd[index_offset]; |
573 | ret = 0; | 577 | ret = 0; |
574 | if (active) { | 578 | if (active) { |
@@ -617,7 +621,6 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, | |||
617 | up_write(&card->controls_rwsem); | 621 | up_write(&card->controls_rwsem); |
618 | return 0; | 622 | return 0; |
619 | } | 623 | } |
620 | |||
621 | EXPORT_SYMBOL(snd_ctl_rename_id); | 624 | EXPORT_SYMBOL(snd_ctl_rename_id); |
622 | 625 | ||
623 | /** | 626 | /** |
@@ -645,7 +648,6 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi | |||
645 | } | 648 | } |
646 | return NULL; | 649 | return NULL; |
647 | } | 650 | } |
648 | |||
649 | EXPORT_SYMBOL(snd_ctl_find_numid); | 651 | EXPORT_SYMBOL(snd_ctl_find_numid); |
650 | 652 | ||
651 | /** | 653 | /** |
@@ -687,7 +689,6 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, | |||
687 | } | 689 | } |
688 | return NULL; | 690 | return NULL; |
689 | } | 691 | } |
690 | |||
691 | EXPORT_SYMBOL(snd_ctl_find_id); | 692 | EXPORT_SYMBOL(snd_ctl_find_id); |
692 | 693 | ||
693 | static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, | 694 | static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, |
@@ -1526,19 +1527,28 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * | |||
1526 | return 0; | 1527 | return 0; |
1527 | } | 1528 | } |
1528 | 1529 | ||
1530 | /** | ||
1531 | * snd_ctl_register_ioctl - register the device-specific control-ioctls | ||
1532 | * @fcn: ioctl callback function | ||
1533 | * | ||
1534 | * called from each device manager like pcm.c, hwdep.c, etc. | ||
1535 | */ | ||
1529 | int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) | 1536 | int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) |
1530 | { | 1537 | { |
1531 | return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); | 1538 | return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); |
1532 | } | 1539 | } |
1533 | |||
1534 | EXPORT_SYMBOL(snd_ctl_register_ioctl); | 1540 | EXPORT_SYMBOL(snd_ctl_register_ioctl); |
1535 | 1541 | ||
1536 | #ifdef CONFIG_COMPAT | 1542 | #ifdef CONFIG_COMPAT |
1543 | /** | ||
1544 | * snd_ctl_register_ioctl_compat - register the device-specific 32bit compat | ||
1545 | * control-ioctls | ||
1546 | * @fcn: ioctl callback function | ||
1547 | */ | ||
1537 | int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) | 1548 | int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) |
1538 | { | 1549 | { |
1539 | return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); | 1550 | return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); |
1540 | } | 1551 | } |
1541 | |||
1542 | EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); | 1552 | EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); |
1543 | #endif | 1553 | #endif |
1544 | 1554 | ||
@@ -1566,19 +1576,26 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, | |||
1566 | return -EINVAL; | 1576 | return -EINVAL; |
1567 | } | 1577 | } |
1568 | 1578 | ||
1579 | /** | ||
1580 | * snd_ctl_unregister_ioctl - de-register the device-specific control-ioctls | ||
1581 | * @fcn: ioctl callback function to unregister | ||
1582 | */ | ||
1569 | int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) | 1583 | int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) |
1570 | { | 1584 | { |
1571 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); | 1585 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); |
1572 | } | 1586 | } |
1573 | |||
1574 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl); | 1587 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl); |
1575 | 1588 | ||
1576 | #ifdef CONFIG_COMPAT | 1589 | #ifdef CONFIG_COMPAT |
1590 | /** | ||
1591 | * snd_ctl_unregister_ioctl - de-register the device-specific compat 32bit | ||
1592 | * control-ioctls | ||
1593 | * @fcn: ioctl callback function to unregister | ||
1594 | */ | ||
1577 | int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) | 1595 | int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) |
1578 | { | 1596 | { |
1579 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); | 1597 | return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); |
1580 | } | 1598 | } |
1581 | |||
1582 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); | 1599 | EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); |
1583 | #endif | 1600 | #endif |
1584 | 1601 | ||
@@ -1702,6 +1719,16 @@ int snd_ctl_create(struct snd_card *card) | |||
1702 | /* | 1719 | /* |
1703 | * Frequently used control callbacks/helpers | 1720 | * Frequently used control callbacks/helpers |
1704 | */ | 1721 | */ |
1722 | |||
1723 | /** | ||
1724 | * snd_ctl_boolean_mono_info - Helper function for a standard boolean info | ||
1725 | * callback with a mono channel | ||
1726 | * @kcontrol: the kcontrol instance | ||
1727 | * @uinfo: info to store | ||
1728 | * | ||
1729 | * This is a function that can be used as info callback for a standard | ||
1730 | * boolean control with a single mono channel. | ||
1731 | */ | ||
1705 | int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, | 1732 | int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, |
1706 | struct snd_ctl_elem_info *uinfo) | 1733 | struct snd_ctl_elem_info *uinfo) |
1707 | { | 1734 | { |
@@ -1711,9 +1738,17 @@ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, | |||
1711 | uinfo->value.integer.max = 1; | 1738 | uinfo->value.integer.max = 1; |
1712 | return 0; | 1739 | return 0; |
1713 | } | 1740 | } |
1714 | |||
1715 | EXPORT_SYMBOL(snd_ctl_boolean_mono_info); | 1741 | EXPORT_SYMBOL(snd_ctl_boolean_mono_info); |
1716 | 1742 | ||
1743 | /** | ||
1744 | * snd_ctl_boolean_stereo_info - Helper function for a standard boolean info | ||
1745 | * callback with stereo two channels | ||
1746 | * @kcontrol: the kcontrol instance | ||
1747 | * @uinfo: info to store | ||
1748 | * | ||
1749 | * This is a function that can be used as info callback for a standard | ||
1750 | * boolean control with stereo two channels. | ||
1751 | */ | ||
1717 | int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, | 1752 | int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, |
1718 | struct snd_ctl_elem_info *uinfo) | 1753 | struct snd_ctl_elem_info *uinfo) |
1719 | { | 1754 | { |
@@ -1723,7 +1758,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, | |||
1723 | uinfo->value.integer.max = 1; | 1758 | uinfo->value.integer.max = 1; |
1724 | return 0; | 1759 | return 0; |
1725 | } | 1760 | } |
1726 | |||
1727 | EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); | 1761 | EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); |
1728 | 1762 | ||
1729 | /** | 1763 | /** |
@@ -1745,8 +1779,13 @@ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, | |||
1745 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1779 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1746 | info->count = channels; | 1780 | info->count = channels; |
1747 | info->value.enumerated.items = items; | 1781 | info->value.enumerated.items = items; |
1782 | if (!items) | ||
1783 | return 0; | ||
1748 | if (info->value.enumerated.item >= items) | 1784 | if (info->value.enumerated.item >= items) |
1749 | info->value.enumerated.item = items - 1; | 1785 | info->value.enumerated.item = items - 1; |
1786 | WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name), | ||
1787 | "ALSA: too long item name '%s'\n", | ||
1788 | names[info->value.enumerated.item]); | ||
1750 | strlcpy(info->value.enumerated.name, | 1789 | strlcpy(info->value.enumerated.name, |
1751 | names[info->value.enumerated.item], | 1790 | names[info->value.enumerated.item], |
1752 | sizeof(info->value.enumerated.name)); | 1791 | sizeof(info->value.enumerated.name)); |
diff --git a/sound/core/init.c b/sound/core/init.c index 7bdfd19e24a8..074875d68c15 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -438,17 +438,6 @@ int snd_card_disconnect(struct snd_card *card) | |||
438 | 438 | ||
439 | EXPORT_SYMBOL(snd_card_disconnect); | 439 | EXPORT_SYMBOL(snd_card_disconnect); |
440 | 440 | ||
441 | /** | ||
442 | * snd_card_free - frees given soundcard structure | ||
443 | * @card: soundcard structure | ||
444 | * | ||
445 | * This function releases the soundcard structure and the all assigned | ||
446 | * devices automatically. That is, you don't have to release the devices | ||
447 | * by yourself. | ||
448 | * | ||
449 | * Return: Zero. Frees all associated devices and frees the control | ||
450 | * interface associated to given soundcard. | ||
451 | */ | ||
452 | static int snd_card_do_free(struct snd_card *card) | 441 | static int snd_card_do_free(struct snd_card *card) |
453 | { | 442 | { |
454 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) | 443 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) |
@@ -469,6 +458,15 @@ static int snd_card_do_free(struct snd_card *card) | |||
469 | return 0; | 458 | return 0; |
470 | } | 459 | } |
471 | 460 | ||
461 | /** | ||
462 | * snd_card_free_when_closed - Disconnect the card, free it later eventually | ||
463 | * @card: soundcard structure | ||
464 | * | ||
465 | * Unlike snd_card_free(), this function doesn't try to release the card | ||
466 | * resource immediately, but tries to disconnect at first. When the card | ||
467 | * is still in use, the function returns before freeing the resources. | ||
468 | * The card resources will be freed when the refcount gets to zero. | ||
469 | */ | ||
472 | int snd_card_free_when_closed(struct snd_card *card) | 470 | int snd_card_free_when_closed(struct snd_card *card) |
473 | { | 471 | { |
474 | int ret = snd_card_disconnect(card); | 472 | int ret = snd_card_disconnect(card); |
@@ -479,6 +477,19 @@ int snd_card_free_when_closed(struct snd_card *card) | |||
479 | } | 477 | } |
480 | EXPORT_SYMBOL(snd_card_free_when_closed); | 478 | EXPORT_SYMBOL(snd_card_free_when_closed); |
481 | 479 | ||
480 | /** | ||
481 | * snd_card_free - frees given soundcard structure | ||
482 | * @card: soundcard structure | ||
483 | * | ||
484 | * This function releases the soundcard structure and the all assigned | ||
485 | * devices automatically. That is, you don't have to release the devices | ||
486 | * by yourself. | ||
487 | * | ||
488 | * This function waits until the all resources are properly released. | ||
489 | * | ||
490 | * Return: Zero. Frees all associated devices and frees the control | ||
491 | * interface associated to given soundcard. | ||
492 | */ | ||
482 | int snd_card_free(struct snd_card *card) | 493 | int snd_card_free(struct snd_card *card) |
483 | { | 494 | { |
484 | struct completion released; | 495 | struct completion released; |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index c6ff94ab1ad6..cfc56c806964 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -220,6 +220,10 @@ static char *snd_pcm_format_names[] = { | |||
220 | FORMAT(DSD_U32_BE), | 220 | FORMAT(DSD_U32_BE), |
221 | }; | 221 | }; |
222 | 222 | ||
223 | /** | ||
224 | * snd_pcm_format_name - Return a name string for the given PCM format | ||
225 | * @format: PCM format | ||
226 | */ | ||
223 | const char *snd_pcm_format_name(snd_pcm_format_t format) | 227 | const char *snd_pcm_format_name(snd_pcm_format_t format) |
224 | { | 228 | { |
225 | if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) | 229 | if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) |
@@ -481,6 +485,19 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | |||
481 | } | 485 | } |
482 | 486 | ||
483 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 487 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
488 | static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry, | ||
489 | struct snd_info_buffer *buffer) | ||
490 | { | ||
491 | struct snd_pcm_substream *substream = entry->private_data; | ||
492 | struct snd_pcm_runtime *runtime; | ||
493 | |||
494 | snd_pcm_stream_lock_irq(substream); | ||
495 | runtime = substream->runtime; | ||
496 | if (runtime && runtime->status->state == SNDRV_PCM_STATE_RUNNING) | ||
497 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
498 | snd_pcm_stream_unlock_irq(substream); | ||
499 | } | ||
500 | |||
484 | static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry, | 501 | static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry, |
485 | struct snd_info_buffer *buffer) | 502 | struct snd_info_buffer *buffer) |
486 | { | 503 | { |
@@ -612,6 +629,22 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) | |||
612 | } | 629 | } |
613 | substream->proc_status_entry = entry; | 630 | substream->proc_status_entry = entry; |
614 | 631 | ||
632 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | ||
633 | entry = snd_info_create_card_entry(card, "xrun_injection", | ||
634 | substream->proc_root); | ||
635 | if (entry) { | ||
636 | entry->private_data = substream; | ||
637 | entry->c.text.read = NULL; | ||
638 | entry->c.text.write = snd_pcm_xrun_injection_write; | ||
639 | entry->mode = S_IFREG | S_IWUSR; | ||
640 | if (snd_info_register(entry) < 0) { | ||
641 | snd_info_free_entry(entry); | ||
642 | entry = NULL; | ||
643 | } | ||
644 | } | ||
645 | substream->proc_xrun_injection_entry = entry; | ||
646 | #endif /* CONFIG_SND_PCM_XRUN_DEBUG */ | ||
647 | |||
615 | return 0; | 648 | return 0; |
616 | } | 649 | } |
617 | 650 | ||
@@ -625,6 +658,10 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) | |||
625 | substream->proc_sw_params_entry = NULL; | 658 | substream->proc_sw_params_entry = NULL; |
626 | snd_info_free_entry(substream->proc_status_entry); | 659 | snd_info_free_entry(substream->proc_status_entry); |
627 | substream->proc_status_entry = NULL; | 660 | substream->proc_status_entry = NULL; |
661 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | ||
662 | snd_info_free_entry(substream->proc_xrun_injection_entry); | ||
663 | substream->proc_xrun_injection_entry = NULL; | ||
664 | #endif | ||
628 | snd_info_free_entry(substream->proc_root); | 665 | snd_info_free_entry(substream->proc_root); |
629 | substream->proc_root = NULL; | 666 | substream->proc_root = NULL; |
630 | return 0; | 667 | return 0; |
@@ -709,7 +746,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
709 | } | 746 | } |
710 | return 0; | 747 | return 0; |
711 | } | 748 | } |
712 | |||
713 | EXPORT_SYMBOL(snd_pcm_new_stream); | 749 | EXPORT_SYMBOL(snd_pcm_new_stream); |
714 | 750 | ||
715 | static int _snd_pcm_new(struct snd_card *card, const char *id, int device, | 751 | static int _snd_pcm_new(struct snd_card *card, const char *id, int device, |
@@ -1157,6 +1193,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
1157 | return 0; | 1193 | return 0; |
1158 | } | 1194 | } |
1159 | 1195 | ||
1196 | /** | ||
1197 | * snd_pcm_notify - Add/remove the notify list | ||
1198 | * @notify: PCM notify list | ||
1199 | * @nfree: 0 = register, 1 = unregister | ||
1200 | * | ||
1201 | * This adds the given notifier to the global list so that the callback is | ||
1202 | * called for each registered PCM devices. This exists only for PCM OSS | ||
1203 | * emulation, so far. | ||
1204 | */ | ||
1160 | int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | 1205 | int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) |
1161 | { | 1206 | { |
1162 | struct snd_pcm *pcm; | 1207 | struct snd_pcm *pcm; |
@@ -1179,7 +1224,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1179 | mutex_unlock(®ister_mutex); | 1224 | mutex_unlock(®ister_mutex); |
1180 | return 0; | 1225 | return 0; |
1181 | } | 1226 | } |
1182 | |||
1183 | EXPORT_SYMBOL(snd_pcm_notify); | 1227 | EXPORT_SYMBOL(snd_pcm_notify); |
1184 | 1228 | ||
1185 | #ifdef CONFIG_PROC_FS | 1229 | #ifdef CONFIG_PROC_FS |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index dfc28542a007..ec9e7866177f 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -32,6 +32,15 @@ | |||
32 | #include <sound/pcm_params.h> | 32 | #include <sound/pcm_params.h> |
33 | #include <sound/timer.h> | 33 | #include <sound/timer.h> |
34 | 34 | ||
35 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | ||
36 | #define CREATE_TRACE_POINTS | ||
37 | #include "pcm_trace.h" | ||
38 | #else | ||
39 | #define trace_hwptr(substream, pos, in_interrupt) | ||
40 | #define trace_xrun(substream) | ||
41 | #define trace_hw_ptr_error(substream, reason) | ||
42 | #endif | ||
43 | |||
35 | /* | 44 | /* |
36 | * fill ring buffer with silence | 45 | * fill ring buffer with silence |
37 | * runtime->silence_start: starting pointer to silence area | 46 | * runtime->silence_start: starting pointer to silence area |
@@ -146,10 +155,6 @@ EXPORT_SYMBOL(snd_pcm_debug_name); | |||
146 | #define XRUN_DEBUG_BASIC (1<<0) | 155 | #define XRUN_DEBUG_BASIC (1<<0) |
147 | #define XRUN_DEBUG_STACK (1<<1) /* dump also stack */ | 156 | #define XRUN_DEBUG_STACK (1<<1) /* dump also stack */ |
148 | #define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */ | 157 | #define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */ |
149 | #define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */ | ||
150 | #define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */ | ||
151 | #define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */ | ||
152 | #define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */ | ||
153 | 158 | ||
154 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 159 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
155 | 160 | ||
@@ -168,6 +173,7 @@ static void xrun(struct snd_pcm_substream *substream) | |||
168 | { | 173 | { |
169 | struct snd_pcm_runtime *runtime = substream->runtime; | 174 | struct snd_pcm_runtime *runtime = substream->runtime; |
170 | 175 | ||
176 | trace_xrun(substream); | ||
171 | if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) | 177 | if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) |
172 | snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); | 178 | snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); |
173 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | 179 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); |
@@ -180,97 +186,19 @@ static void xrun(struct snd_pcm_substream *substream) | |||
180 | } | 186 | } |
181 | 187 | ||
182 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 188 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
183 | #define hw_ptr_error(substream, fmt, args...) \ | 189 | #define hw_ptr_error(substream, in_interrupt, reason, fmt, args...) \ |
184 | do { \ | 190 | do { \ |
191 | trace_hw_ptr_error(substream, reason); \ | ||
185 | if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ | 192 | if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ |
186 | xrun_log_show(substream); \ | 193 | pr_err_ratelimited("ALSA: PCM: [%c] " reason ": " fmt, \ |
187 | pr_err_ratelimited("ALSA: PCM: " fmt, ##args); \ | 194 | (in_interrupt) ? 'Q' : 'P', ##args); \ |
188 | dump_stack_on_xrun(substream); \ | 195 | dump_stack_on_xrun(substream); \ |
189 | } \ | 196 | } \ |
190 | } while (0) | 197 | } while (0) |
191 | 198 | ||
192 | #define XRUN_LOG_CNT 10 | ||
193 | |||
194 | struct hwptr_log_entry { | ||
195 | unsigned int in_interrupt; | ||
196 | unsigned long jiffies; | ||
197 | snd_pcm_uframes_t pos; | ||
198 | snd_pcm_uframes_t period_size; | ||
199 | snd_pcm_uframes_t buffer_size; | ||
200 | snd_pcm_uframes_t old_hw_ptr; | ||
201 | snd_pcm_uframes_t hw_ptr_base; | ||
202 | }; | ||
203 | |||
204 | struct snd_pcm_hwptr_log { | ||
205 | unsigned int idx; | ||
206 | unsigned int hit: 1; | ||
207 | struct hwptr_log_entry entries[XRUN_LOG_CNT]; | ||
208 | }; | ||
209 | |||
210 | static void xrun_log(struct snd_pcm_substream *substream, | ||
211 | snd_pcm_uframes_t pos, int in_interrupt) | ||
212 | { | ||
213 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
214 | struct snd_pcm_hwptr_log *log = runtime->hwptr_log; | ||
215 | struct hwptr_log_entry *entry; | ||
216 | |||
217 | if (log == NULL) { | ||
218 | log = kzalloc(sizeof(*log), GFP_ATOMIC); | ||
219 | if (log == NULL) | ||
220 | return; | ||
221 | runtime->hwptr_log = log; | ||
222 | } else { | ||
223 | if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) | ||
224 | return; | ||
225 | } | ||
226 | entry = &log->entries[log->idx]; | ||
227 | entry->in_interrupt = in_interrupt; | ||
228 | entry->jiffies = jiffies; | ||
229 | entry->pos = pos; | ||
230 | entry->period_size = runtime->period_size; | ||
231 | entry->buffer_size = runtime->buffer_size; | ||
232 | entry->old_hw_ptr = runtime->status->hw_ptr; | ||
233 | entry->hw_ptr_base = runtime->hw_ptr_base; | ||
234 | log->idx = (log->idx + 1) % XRUN_LOG_CNT; | ||
235 | } | ||
236 | |||
237 | static void xrun_log_show(struct snd_pcm_substream *substream) | ||
238 | { | ||
239 | struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log; | ||
240 | struct hwptr_log_entry *entry; | ||
241 | char name[16]; | ||
242 | unsigned int idx; | ||
243 | int cnt; | ||
244 | |||
245 | if (log == NULL) | ||
246 | return; | ||
247 | if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) | ||
248 | return; | ||
249 | snd_pcm_debug_name(substream, name, sizeof(name)); | ||
250 | for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) { | ||
251 | entry = &log->entries[idx]; | ||
252 | if (entry->period_size == 0) | ||
253 | break; | ||
254 | pr_info("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, " | ||
255 | "hwptr=%ld/%ld\n", | ||
256 | name, entry->in_interrupt ? "[Q] " : "", | ||
257 | entry->jiffies, | ||
258 | (unsigned long)entry->pos, | ||
259 | (unsigned long)entry->period_size, | ||
260 | (unsigned long)entry->buffer_size, | ||
261 | (unsigned long)entry->old_hw_ptr, | ||
262 | (unsigned long)entry->hw_ptr_base); | ||
263 | idx++; | ||
264 | idx %= XRUN_LOG_CNT; | ||
265 | } | ||
266 | log->hit = 1; | ||
267 | } | ||
268 | |||
269 | #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ | 199 | #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ |
270 | 200 | ||
271 | #define hw_ptr_error(substream, fmt, args...) do { } while (0) | 201 | #define hw_ptr_error(substream, fmt, args...) do { } while (0) |
272 | #define xrun_log(substream, pos, in_interrupt) do { } while (0) | ||
273 | #define xrun_log_show(substream) do { } while (0) | ||
274 | 202 | ||
275 | #endif | 203 | #endif |
276 | 204 | ||
@@ -343,17 +271,15 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
343 | if (printk_ratelimit()) { | 271 | if (printk_ratelimit()) { |
344 | char name[16]; | 272 | char name[16]; |
345 | snd_pcm_debug_name(substream, name, sizeof(name)); | 273 | snd_pcm_debug_name(substream, name, sizeof(name)); |
346 | xrun_log_show(substream); | ||
347 | pcm_err(substream->pcm, | 274 | pcm_err(substream->pcm, |
348 | "XRUN: %s, pos = %ld, buffer size = %ld, period size = %ld\n", | 275 | "BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n", |
349 | name, pos, runtime->buffer_size, | 276 | name, pos, runtime->buffer_size, |
350 | runtime->period_size); | 277 | runtime->period_size); |
351 | } | 278 | } |
352 | pos = 0; | 279 | pos = 0; |
353 | } | 280 | } |
354 | pos -= pos % runtime->min_align; | 281 | pos -= pos % runtime->min_align; |
355 | if (xrun_debug(substream, XRUN_DEBUG_LOG)) | 282 | trace_hwptr(substream, pos, in_interrupt); |
356 | xrun_log(substream, pos, in_interrupt); | ||
357 | hw_base = runtime->hw_ptr_base; | 283 | hw_base = runtime->hw_ptr_base; |
358 | new_hw_ptr = hw_base + pos; | 284 | new_hw_ptr = hw_base + pos; |
359 | if (in_interrupt) { | 285 | if (in_interrupt) { |
@@ -388,22 +314,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
388 | delta = new_hw_ptr - old_hw_ptr; | 314 | delta = new_hw_ptr - old_hw_ptr; |
389 | if (delta < 0) | 315 | if (delta < 0) |
390 | delta += runtime->boundary; | 316 | delta += runtime->boundary; |
391 | if (xrun_debug(substream, in_interrupt ? | ||
392 | XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { | ||
393 | char name[16]; | ||
394 | snd_pcm_debug_name(substream, name, sizeof(name)); | ||
395 | pcm_dbg(substream->pcm, | ||
396 | "%s_update: %s: pos=%u/%u/%u, hwptr=%ld/%ld/%ld/%ld\n", | ||
397 | in_interrupt ? "period" : "hwptr", | ||
398 | name, | ||
399 | (unsigned int)pos, | ||
400 | (unsigned int)runtime->period_size, | ||
401 | (unsigned int)runtime->buffer_size, | ||
402 | (unsigned long)delta, | ||
403 | (unsigned long)old_hw_ptr, | ||
404 | (unsigned long)new_hw_ptr, | ||
405 | (unsigned long)runtime->hw_ptr_base); | ||
406 | } | ||
407 | 317 | ||
408 | if (runtime->no_period_wakeup) { | 318 | if (runtime->no_period_wakeup) { |
409 | snd_pcm_sframes_t xrun_threshold; | 319 | snd_pcm_sframes_t xrun_threshold; |
@@ -431,13 +341,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
431 | 341 | ||
432 | /* something must be really wrong */ | 342 | /* something must be really wrong */ |
433 | if (delta >= runtime->buffer_size + runtime->period_size) { | 343 | if (delta >= runtime->buffer_size + runtime->period_size) { |
434 | hw_ptr_error(substream, | 344 | hw_ptr_error(substream, in_interrupt, "Unexpected hw_ptr", |
435 | "Unexpected hw_pointer value %s" | 345 | "(stream=%i, pos=%ld, new_hw_ptr=%ld, old_hw_ptr=%ld)\n", |
436 | "(stream=%i, pos=%ld, new_hw_ptr=%ld, " | 346 | substream->stream, (long)pos, |
437 | "old_hw_ptr=%ld)\n", | 347 | (long)new_hw_ptr, (long)old_hw_ptr); |
438 | in_interrupt ? "[Q] " : "[P]", | ||
439 | substream->stream, (long)pos, | ||
440 | (long)new_hw_ptr, (long)old_hw_ptr); | ||
441 | return 0; | 348 | return 0; |
442 | } | 349 | } |
443 | 350 | ||
@@ -474,11 +381,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
474 | delta--; | 381 | delta--; |
475 | } | 382 | } |
476 | /* align hw_base to buffer_size */ | 383 | /* align hw_base to buffer_size */ |
477 | hw_ptr_error(substream, | 384 | hw_ptr_error(substream, in_interrupt, "hw_ptr skipping", |
478 | "hw_ptr skipping! %s" | 385 | "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n", |
479 | "(pos=%ld, delta=%ld, period=%ld, " | ||
480 | "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n", | ||
481 | in_interrupt ? "[Q] " : "", | ||
482 | (long)pos, (long)hdelta, | 386 | (long)pos, (long)hdelta, |
483 | (long)runtime->period_size, jdelta, | 387 | (long)runtime->period_size, jdelta, |
484 | ((hdelta * HZ) / runtime->rate), hw_base, | 388 | ((hdelta * HZ) / runtime->rate), hw_base, |
@@ -490,11 +394,9 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
490 | } | 394 | } |
491 | no_jiffies_check: | 395 | no_jiffies_check: |
492 | if (delta > runtime->period_size + runtime->period_size / 2) { | 396 | if (delta > runtime->period_size + runtime->period_size / 2) { |
493 | hw_ptr_error(substream, | 397 | hw_ptr_error(substream, in_interrupt, |
494 | "Lost interrupts? %s" | 398 | "Lost interrupts?", |
495 | "(stream=%i, delta=%ld, new_hw_ptr=%ld, " | 399 | "(stream=%i, delta=%ld, new_hw_ptr=%ld, old_hw_ptr=%ld)\n", |
496 | "old_hw_ptr=%ld)\n", | ||
497 | in_interrupt ? "[Q] " : "", | ||
498 | substream->stream, (long)delta, | 400 | substream->stream, (long)delta, |
499 | (long)new_hw_ptr, | 401 | (long)new_hw_ptr, |
500 | (long)old_hw_ptr); | 402 | (long)old_hw_ptr); |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 166d59cdc86b..095d9572ad2b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -35,9 +35,6 @@ | |||
35 | #include <sound/timer.h> | 35 | #include <sound/timer.h> |
36 | #include <sound/minors.h> | 36 | #include <sound/minors.h> |
37 | #include <asm/io.h> | 37 | #include <asm/io.h> |
38 | #if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) | ||
39 | #include <dma-coherence.h> | ||
40 | #endif | ||
41 | 38 | ||
42 | /* | 39 | /* |
43 | * Compatibility | 40 | * Compatibility |
@@ -77,6 +74,14 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); | |||
77 | static DEFINE_RWLOCK(snd_pcm_link_rwlock); | 74 | static DEFINE_RWLOCK(snd_pcm_link_rwlock); |
78 | static DECLARE_RWSEM(snd_pcm_link_rwsem); | 75 | static DECLARE_RWSEM(snd_pcm_link_rwsem); |
79 | 76 | ||
77 | /** | ||
78 | * snd_pcm_stream_lock - Lock the PCM stream | ||
79 | * @substream: PCM substream | ||
80 | * | ||
81 | * This locks the PCM stream's spinlock or mutex depending on the nonatomic | ||
82 | * flag of the given substream. This also takes the global link rw lock | ||
83 | * (or rw sem), too, for avoiding the race with linked streams. | ||
84 | */ | ||
80 | void snd_pcm_stream_lock(struct snd_pcm_substream *substream) | 85 | void snd_pcm_stream_lock(struct snd_pcm_substream *substream) |
81 | { | 86 | { |
82 | if (substream->pcm->nonatomic) { | 87 | if (substream->pcm->nonatomic) { |
@@ -89,6 +94,12 @@ void snd_pcm_stream_lock(struct snd_pcm_substream *substream) | |||
89 | } | 94 | } |
90 | EXPORT_SYMBOL_GPL(snd_pcm_stream_lock); | 95 | EXPORT_SYMBOL_GPL(snd_pcm_stream_lock); |
91 | 96 | ||
97 | /** | ||
98 | * snd_pcm_stream_lock - Unlock the PCM stream | ||
99 | * @substream: PCM substream | ||
100 | * | ||
101 | * This unlocks the PCM stream that has been locked via snd_pcm_stream_lock(). | ||
102 | */ | ||
92 | void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) | 103 | void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) |
93 | { | 104 | { |
94 | if (substream->pcm->nonatomic) { | 105 | if (substream->pcm->nonatomic) { |
@@ -101,6 +112,14 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) | |||
101 | } | 112 | } |
102 | EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); | 113 | EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); |
103 | 114 | ||
115 | /** | ||
116 | * snd_pcm_stream_lock_irq - Lock the PCM stream | ||
117 | * @substream: PCM substream | ||
118 | * | ||
119 | * This locks the PCM stream like snd_pcm_stream_lock() and disables the local | ||
120 | * IRQ (only when nonatomic is false). In nonatomic case, this is identical | ||
121 | * as snd_pcm_stream_lock(). | ||
122 | */ | ||
104 | void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) | 123 | void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) |
105 | { | 124 | { |
106 | if (!substream->pcm->nonatomic) | 125 | if (!substream->pcm->nonatomic) |
@@ -109,6 +128,12 @@ void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) | |||
109 | } | 128 | } |
110 | EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); | 129 | EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); |
111 | 130 | ||
131 | /** | ||
132 | * snd_pcm_stream_unlock_irq - Unlock the PCM stream | ||
133 | * @substream: PCM substream | ||
134 | * | ||
135 | * This is a counter-part of snd_pcm_stream_lock_irq(). | ||
136 | */ | ||
112 | void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) | 137 | void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) |
113 | { | 138 | { |
114 | snd_pcm_stream_unlock(substream); | 139 | snd_pcm_stream_unlock(substream); |
@@ -127,6 +152,13 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream) | |||
127 | } | 152 | } |
128 | EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave); | 153 | EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave); |
129 | 154 | ||
155 | /** | ||
156 | * snd_pcm_stream_unlock_irqrestore - Unlock the PCM stream | ||
157 | * @substream: PCM substream | ||
158 | * @flags: irq flags | ||
159 | * | ||
160 | * This is a counter-part of snd_pcm_stream_lock_irqsave(). | ||
161 | */ | ||
130 | void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, | 162 | void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, |
131 | unsigned long flags) | 163 | unsigned long flags) |
132 | { | 164 | { |
@@ -195,6 +227,21 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream, | |||
195 | return err; | 227 | return err; |
196 | } | 228 | } |
197 | 229 | ||
230 | static bool hw_support_mmap(struct snd_pcm_substream *substream) | ||
231 | { | ||
232 | if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP)) | ||
233 | return false; | ||
234 | /* check architectures that return -EINVAL from dma_mmap_coherent() */ | ||
235 | /* FIXME: this should be some global flag */ | ||
236 | #if defined(CONFIG_C6X) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) ||\ | ||
237 | defined(CONFIG_PARISC) || defined(CONFIG_XTENSA) | ||
238 | if (!substream->ops->mmap && | ||
239 | substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) | ||
240 | return false; | ||
241 | #endif | ||
242 | return true; | ||
243 | } | ||
244 | |||
198 | #undef RULES_DEBUG | 245 | #undef RULES_DEBUG |
199 | 246 | ||
200 | #ifdef RULES_DEBUG | 247 | #ifdef RULES_DEBUG |
@@ -372,8 +419,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, | |||
372 | } | 419 | } |
373 | 420 | ||
374 | hw = &substream->runtime->hw; | 421 | hw = &substream->runtime->hw; |
375 | if (!params->info) | 422 | if (!params->info) { |
376 | params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; | 423 | params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; |
424 | if (!hw_support_mmap(substream)) | ||
425 | params->info &= ~(SNDRV_PCM_INFO_MMAP | | ||
426 | SNDRV_PCM_INFO_MMAP_VALID); | ||
427 | } | ||
377 | if (!params->fifo_size) { | 428 | if (!params->fifo_size) { |
378 | m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 429 | m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
379 | i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 430 | i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
@@ -849,14 +900,19 @@ static int snd_pcm_action_single(struct action_ops *ops, | |||
849 | return res; | 900 | return res; |
850 | } | 901 | } |
851 | 902 | ||
852 | /* call in mutex-protected context */ | 903 | /* |
853 | static int snd_pcm_action_mutex(struct action_ops *ops, | 904 | * Note: call with stream lock |
854 | struct snd_pcm_substream *substream, | 905 | */ |
855 | int state) | 906 | static int snd_pcm_action(struct action_ops *ops, |
907 | struct snd_pcm_substream *substream, | ||
908 | int state) | ||
856 | { | 909 | { |
857 | int res; | 910 | int res; |
858 | 911 | ||
859 | if (snd_pcm_stream_linked(substream)) { | 912 | if (!snd_pcm_stream_linked(substream)) |
913 | return snd_pcm_action_single(ops, substream, state); | ||
914 | |||
915 | if (substream->pcm->nonatomic) { | ||
860 | if (!mutex_trylock(&substream->group->mutex)) { | 916 | if (!mutex_trylock(&substream->group->mutex)) { |
861 | mutex_unlock(&substream->self_group.mutex); | 917 | mutex_unlock(&substream->self_group.mutex); |
862 | mutex_lock(&substream->group->mutex); | 918 | mutex_lock(&substream->group->mutex); |
@@ -865,24 +921,6 @@ static int snd_pcm_action_mutex(struct action_ops *ops, | |||
865 | res = snd_pcm_action_group(ops, substream, state, 1); | 921 | res = snd_pcm_action_group(ops, substream, state, 1); |
866 | mutex_unlock(&substream->group->mutex); | 922 | mutex_unlock(&substream->group->mutex); |
867 | } else { | 923 | } else { |
868 | res = snd_pcm_action_single(ops, substream, state); | ||
869 | } | ||
870 | return res; | ||
871 | } | ||
872 | |||
873 | /* | ||
874 | * Note: call with stream lock | ||
875 | */ | ||
876 | static int snd_pcm_action(struct action_ops *ops, | ||
877 | struct snd_pcm_substream *substream, | ||
878 | int state) | ||
879 | { | ||
880 | int res; | ||
881 | |||
882 | if (substream->pcm->nonatomic) | ||
883 | return snd_pcm_action_mutex(ops, substream, state); | ||
884 | |||
885 | if (snd_pcm_stream_linked(substream)) { | ||
886 | if (!spin_trylock(&substream->group->lock)) { | 924 | if (!spin_trylock(&substream->group->lock)) { |
887 | spin_unlock(&substream->self_group.lock); | 925 | spin_unlock(&substream->self_group.lock); |
888 | spin_lock(&substream->group->lock); | 926 | spin_lock(&substream->group->lock); |
@@ -890,34 +928,10 @@ static int snd_pcm_action(struct action_ops *ops, | |||
890 | } | 928 | } |
891 | res = snd_pcm_action_group(ops, substream, state, 1); | 929 | res = snd_pcm_action_group(ops, substream, state, 1); |
892 | spin_unlock(&substream->group->lock); | 930 | spin_unlock(&substream->group->lock); |
893 | } else { | ||
894 | res = snd_pcm_action_single(ops, substream, state); | ||
895 | } | 931 | } |
896 | return res; | 932 | return res; |
897 | } | 933 | } |
898 | 934 | ||
899 | static int snd_pcm_action_lock_mutex(struct action_ops *ops, | ||
900 | struct snd_pcm_substream *substream, | ||
901 | int state) | ||
902 | { | ||
903 | int res; | ||
904 | |||
905 | down_read(&snd_pcm_link_rwsem); | ||
906 | if (snd_pcm_stream_linked(substream)) { | ||
907 | mutex_lock(&substream->group->mutex); | ||
908 | mutex_lock(&substream->self_group.mutex); | ||
909 | res = snd_pcm_action_group(ops, substream, state, 1); | ||
910 | mutex_unlock(&substream->self_group.mutex); | ||
911 | mutex_unlock(&substream->group->mutex); | ||
912 | } else { | ||
913 | mutex_lock(&substream->self_group.mutex); | ||
914 | res = snd_pcm_action_single(ops, substream, state); | ||
915 | mutex_unlock(&substream->self_group.mutex); | ||
916 | } | ||
917 | up_read(&snd_pcm_link_rwsem); | ||
918 | return res; | ||
919 | } | ||
920 | |||
921 | /* | 935 | /* |
922 | * Note: don't use any locks before | 936 | * Note: don't use any locks before |
923 | */ | 937 | */ |
@@ -927,22 +941,9 @@ static int snd_pcm_action_lock_irq(struct action_ops *ops, | |||
927 | { | 941 | { |
928 | int res; | 942 | int res; |
929 | 943 | ||
930 | if (substream->pcm->nonatomic) | 944 | snd_pcm_stream_lock_irq(substream); |
931 | return snd_pcm_action_lock_mutex(ops, substream, state); | 945 | res = snd_pcm_action(ops, substream, state); |
932 | 946 | snd_pcm_stream_unlock_irq(substream); | |
933 | read_lock_irq(&snd_pcm_link_rwlock); | ||
934 | if (snd_pcm_stream_linked(substream)) { | ||
935 | spin_lock(&substream->group->lock); | ||
936 | spin_lock(&substream->self_group.lock); | ||
937 | res = snd_pcm_action_group(ops, substream, state, 1); | ||
938 | spin_unlock(&substream->self_group.lock); | ||
939 | spin_unlock(&substream->group->lock); | ||
940 | } else { | ||
941 | spin_lock(&substream->self_group.lock); | ||
942 | res = snd_pcm_action_single(ops, substream, state); | ||
943 | spin_unlock(&substream->self_group.lock); | ||
944 | } | ||
945 | read_unlock_irq(&snd_pcm_link_rwlock); | ||
946 | return res; | 947 | return res; |
947 | } | 948 | } |
948 | 949 | ||
@@ -1051,10 +1052,10 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state) | |||
1051 | struct snd_pcm_runtime *runtime = substream->runtime; | 1052 | struct snd_pcm_runtime *runtime = substream->runtime; |
1052 | if (runtime->status->state != state) { | 1053 | if (runtime->status->state != state) { |
1053 | snd_pcm_trigger_tstamp(substream); | 1054 | snd_pcm_trigger_tstamp(substream); |
1055 | runtime->status->state = state; | ||
1054 | if (substream->timer) | 1056 | if (substream->timer) |
1055 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, | 1057 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, |
1056 | &runtime->trigger_tstamp); | 1058 | &runtime->trigger_tstamp); |
1057 | runtime->status->state = state; | ||
1058 | } | 1059 | } |
1059 | wake_up(&runtime->sleep); | 1060 | wake_up(&runtime->sleep); |
1060 | wake_up(&runtime->tsleep); | 1061 | wake_up(&runtime->tsleep); |
@@ -1097,6 +1098,28 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream) | |||
1097 | SNDRV_PCM_STATE_SETUP); | 1098 | SNDRV_PCM_STATE_SETUP); |
1098 | } | 1099 | } |
1099 | 1100 | ||
1101 | /** | ||
1102 | * snd_pcm_stop_xrun - stop the running streams as XRUN | ||
1103 | * @substream: the PCM substream instance | ||
1104 | * | ||
1105 | * This stops the given running substream (and all linked substreams) as XRUN. | ||
1106 | * Unlike snd_pcm_stop(), this function takes the substream lock by itself. | ||
1107 | * | ||
1108 | * Return: Zero if successful, or a negative error code. | ||
1109 | */ | ||
1110 | int snd_pcm_stop_xrun(struct snd_pcm_substream *substream) | ||
1111 | { | ||
1112 | unsigned long flags; | ||
1113 | int ret = 0; | ||
1114 | |||
1115 | snd_pcm_stream_lock_irqsave(substream, flags); | ||
1116 | if (snd_pcm_running(substream)) | ||
1117 | ret = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
1118 | snd_pcm_stream_unlock_irqrestore(substream, flags); | ||
1119 | return ret; | ||
1120 | } | ||
1121 | EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun); | ||
1122 | |||
1100 | /* | 1123 | /* |
1101 | * pause callbacks | 1124 | * pause callbacks |
1102 | */ | 1125 | */ |
@@ -1203,11 +1226,11 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state) | |||
1203 | { | 1226 | { |
1204 | struct snd_pcm_runtime *runtime = substream->runtime; | 1227 | struct snd_pcm_runtime *runtime = substream->runtime; |
1205 | snd_pcm_trigger_tstamp(substream); | 1228 | snd_pcm_trigger_tstamp(substream); |
1229 | runtime->status->suspended_state = runtime->status->state; | ||
1230 | runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; | ||
1206 | if (substream->timer) | 1231 | if (substream->timer) |
1207 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND, | 1232 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND, |
1208 | &runtime->trigger_tstamp); | 1233 | &runtime->trigger_tstamp); |
1209 | runtime->status->suspended_state = runtime->status->state; | ||
1210 | runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; | ||
1211 | wake_up(&runtime->sleep); | 1234 | wake_up(&runtime->sleep); |
1212 | wake_up(&runtime->tsleep); | 1235 | wake_up(&runtime->tsleep); |
1213 | } | 1236 | } |
@@ -1310,10 +1333,10 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state) | |||
1310 | { | 1333 | { |
1311 | struct snd_pcm_runtime *runtime = substream->runtime; | 1334 | struct snd_pcm_runtime *runtime = substream->runtime; |
1312 | snd_pcm_trigger_tstamp(substream); | 1335 | snd_pcm_trigger_tstamp(substream); |
1336 | runtime->status->state = runtime->status->suspended_state; | ||
1313 | if (substream->timer) | 1337 | if (substream->timer) |
1314 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME, | 1338 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME, |
1315 | &runtime->trigger_tstamp); | 1339 | &runtime->trigger_tstamp); |
1316 | runtime->status->state = runtime->status->suspended_state; | ||
1317 | } | 1340 | } |
1318 | 1341 | ||
1319 | static struct action_ops snd_pcm_action_resume = { | 1342 | static struct action_ops snd_pcm_action_resume = { |
@@ -2070,7 +2093,7 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) | |||
2070 | mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; | 2093 | mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; |
2071 | if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) | 2094 | if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) |
2072 | mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; | 2095 | mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; |
2073 | if (hw->info & SNDRV_PCM_INFO_MMAP) { | 2096 | if (hw_support_mmap(substream)) { |
2074 | if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) | 2097 | if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) |
2075 | mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; | 2098 | mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; |
2076 | if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) | 2099 | if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) |
@@ -3249,20 +3272,6 @@ static inline struct page * | |||
3249 | snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) | 3272 | snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) |
3250 | { | 3273 | { |
3251 | void *vaddr = substream->runtime->dma_area + ofs; | 3274 | void *vaddr = substream->runtime->dma_area + ofs; |
3252 | #if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) | ||
3253 | if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) | ||
3254 | return virt_to_page(CAC_ADDR(vaddr)); | ||
3255 | #endif | ||
3256 | #if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE) | ||
3257 | if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) { | ||
3258 | dma_addr_t addr = substream->runtime->dma_addr + ofs; | ||
3259 | addr -= get_dma_offset(substream->dma_buffer.dev.dev); | ||
3260 | /* assume dma_handle set via pfn_to_phys() in | ||
3261 | * mm/dma-noncoherent.c | ||
3262 | */ | ||
3263 | return pfn_to_page(addr >> PAGE_SHIFT); | ||
3264 | } | ||
3265 | #endif | ||
3266 | return virt_to_page(vaddr); | 3275 | return virt_to_page(vaddr); |
3267 | } | 3276 | } |
3268 | 3277 | ||
@@ -3307,16 +3316,18 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { | |||
3307 | .fault = snd_pcm_mmap_data_fault, | 3316 | .fault = snd_pcm_mmap_data_fault, |
3308 | }; | 3317 | }; |
3309 | 3318 | ||
3310 | #ifndef ARCH_HAS_DMA_MMAP_COHERENT | ||
3311 | /* This should be defined / handled globally! */ | ||
3312 | #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) | ||
3313 | #define ARCH_HAS_DMA_MMAP_COHERENT | ||
3314 | #endif | ||
3315 | #endif | ||
3316 | |||
3317 | /* | 3319 | /* |
3318 | * mmap the DMA buffer on RAM | 3320 | * mmap the DMA buffer on RAM |
3319 | */ | 3321 | */ |
3322 | |||
3323 | /** | ||
3324 | * snd_pcm_lib_default_mmap - Default PCM data mmap function | ||
3325 | * @substream: PCM substream | ||
3326 | * @area: VMA | ||
3327 | * | ||
3328 | * This is the default mmap handler for PCM data. When mmap pcm_ops is NULL, | ||
3329 | * this function is invoked implicitly. | ||
3330 | */ | ||
3320 | int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, | 3331 | int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, |
3321 | struct vm_area_struct *area) | 3332 | struct vm_area_struct *area) |
3322 | { | 3333 | { |
@@ -3329,7 +3340,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, | |||
3329 | area->vm_end - area->vm_start, area->vm_page_prot); | 3340 | area->vm_end - area->vm_start, area->vm_page_prot); |
3330 | } | 3341 | } |
3331 | #endif /* CONFIG_GENERIC_ALLOCATOR */ | 3342 | #endif /* CONFIG_GENERIC_ALLOCATOR */ |
3332 | #ifdef ARCH_HAS_DMA_MMAP_COHERENT | 3343 | #ifndef CONFIG_X86 /* for avoiding warnings arch/x86/mm/pat.c */ |
3333 | if (!substream->ops->page && | 3344 | if (!substream->ops->page && |
3334 | substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) | 3345 | substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) |
3335 | return dma_mmap_coherent(substream->dma_buffer.dev.dev, | 3346 | return dma_mmap_coherent(substream->dma_buffer.dev.dev, |
@@ -3337,11 +3348,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, | |||
3337 | substream->runtime->dma_area, | 3348 | substream->runtime->dma_area, |
3338 | substream->runtime->dma_addr, | 3349 | substream->runtime->dma_addr, |
3339 | area->vm_end - area->vm_start); | 3350 | area->vm_end - area->vm_start); |
3340 | #elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) | 3351 | #endif /* CONFIG_X86 */ |
3341 | if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV && | ||
3342 | !plat_device_is_coherent(substream->dma_buffer.dev.dev)) | ||
3343 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | ||
3344 | #endif /* ARCH_HAS_DMA_MMAP_COHERENT */ | ||
3345 | /* mmap with fault handler */ | 3352 | /* mmap with fault handler */ |
3346 | area->vm_ops = &snd_pcm_vm_ops_data_fault; | 3353 | area->vm_ops = &snd_pcm_vm_ops_data_fault; |
3347 | return 0; | 3354 | return 0; |
@@ -3352,6 +3359,15 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); | |||
3352 | * mmap the DMA buffer on I/O memory area | 3359 | * mmap the DMA buffer on I/O memory area |
3353 | */ | 3360 | */ |
3354 | #if SNDRV_PCM_INFO_MMAP_IOMEM | 3361 | #if SNDRV_PCM_INFO_MMAP_IOMEM |
3362 | /** | ||
3363 | * snd_pcm_lib_mmap_iomem - Default PCM data mmap function for I/O mem | ||
3364 | * @substream: PCM substream | ||
3365 | * @area: VMA | ||
3366 | * | ||
3367 | * When your hardware uses the iomapped pages as the hardware buffer and | ||
3368 | * wants to mmap it, pass this function as mmap pcm_ops. Note that this | ||
3369 | * is supposed to work only on limited architectures. | ||
3370 | */ | ||
3355 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | 3371 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, |
3356 | struct vm_area_struct *area) | 3372 | struct vm_area_struct *area) |
3357 | { | 3373 | { |
diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h new file mode 100644 index 000000000000..b63b654da5ff --- /dev/null +++ b/sound/core/pcm_trace.h | |||
@@ -0,0 +1,110 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM snd_pcm | ||
3 | #define TRACE_INCLUDE_FILE pcm_trace | ||
4 | |||
5 | #if !defined(_PCM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
6 | #define _PCM_TRACE_H | ||
7 | |||
8 | #include <linux/tracepoint.h> | ||
9 | |||
10 | TRACE_EVENT(hwptr, | ||
11 | TP_PROTO(struct snd_pcm_substream *substream, snd_pcm_uframes_t pos, bool irq), | ||
12 | TP_ARGS(substream, pos, irq), | ||
13 | TP_STRUCT__entry( | ||
14 | __field( bool, in_interrupt ) | ||
15 | __field( unsigned int, card ) | ||
16 | __field( unsigned int, device ) | ||
17 | __field( unsigned int, number ) | ||
18 | __field( unsigned int, stream ) | ||
19 | __field( snd_pcm_uframes_t, pos ) | ||
20 | __field( snd_pcm_uframes_t, period_size ) | ||
21 | __field( snd_pcm_uframes_t, buffer_size ) | ||
22 | __field( snd_pcm_uframes_t, old_hw_ptr ) | ||
23 | __field( snd_pcm_uframes_t, hw_ptr_base ) | ||
24 | ), | ||
25 | TP_fast_assign( | ||
26 | __entry->in_interrupt = (irq); | ||
27 | __entry->card = (substream)->pcm->card->number; | ||
28 | __entry->device = (substream)->pcm->device; | ||
29 | __entry->number = (substream)->number; | ||
30 | __entry->stream = (substream)->stream; | ||
31 | __entry->pos = (pos); | ||
32 | __entry->period_size = (substream)->runtime->period_size; | ||
33 | __entry->buffer_size = (substream)->runtime->buffer_size; | ||
34 | __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; | ||
35 | __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; | ||
36 | ), | ||
37 | TP_printk("pcmC%dD%d%c/sub%d: %s: pos=%lu, old=%lu, base=%lu, period=%lu, buf=%lu", | ||
38 | __entry->card, __entry->device, | ||
39 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', | ||
40 | __entry->number, | ||
41 | __entry->in_interrupt ? "IRQ" : "POS", | ||
42 | (unsigned long)__entry->pos, | ||
43 | (unsigned long)__entry->old_hw_ptr, | ||
44 | (unsigned long)__entry->hw_ptr_base, | ||
45 | (unsigned long)__entry->period_size, | ||
46 | (unsigned long)__entry->buffer_size) | ||
47 | ); | ||
48 | |||
49 | TRACE_EVENT(xrun, | ||
50 | TP_PROTO(struct snd_pcm_substream *substream), | ||
51 | TP_ARGS(substream), | ||
52 | TP_STRUCT__entry( | ||
53 | __field( unsigned int, card ) | ||
54 | __field( unsigned int, device ) | ||
55 | __field( unsigned int, number ) | ||
56 | __field( unsigned int, stream ) | ||
57 | __field( snd_pcm_uframes_t, period_size ) | ||
58 | __field( snd_pcm_uframes_t, buffer_size ) | ||
59 | __field( snd_pcm_uframes_t, old_hw_ptr ) | ||
60 | __field( snd_pcm_uframes_t, hw_ptr_base ) | ||
61 | ), | ||
62 | TP_fast_assign( | ||
63 | __entry->card = (substream)->pcm->card->number; | ||
64 | __entry->device = (substream)->pcm->device; | ||
65 | __entry->number = (substream)->number; | ||
66 | __entry->stream = (substream)->stream; | ||
67 | __entry->period_size = (substream)->runtime->period_size; | ||
68 | __entry->buffer_size = (substream)->runtime->buffer_size; | ||
69 | __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; | ||
70 | __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; | ||
71 | ), | ||
72 | TP_printk("pcmC%dD%d%c/sub%d: XRUN: old=%lu, base=%lu, period=%lu, buf=%lu", | ||
73 | __entry->card, __entry->device, | ||
74 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', | ||
75 | __entry->number, | ||
76 | (unsigned long)__entry->old_hw_ptr, | ||
77 | (unsigned long)__entry->hw_ptr_base, | ||
78 | (unsigned long)__entry->period_size, | ||
79 | (unsigned long)__entry->buffer_size) | ||
80 | ); | ||
81 | |||
82 | TRACE_EVENT(hw_ptr_error, | ||
83 | TP_PROTO(struct snd_pcm_substream *substream, const char *why), | ||
84 | TP_ARGS(substream, why), | ||
85 | TP_STRUCT__entry( | ||
86 | __field( unsigned int, card ) | ||
87 | __field( unsigned int, device ) | ||
88 | __field( unsigned int, number ) | ||
89 | __field( unsigned int, stream ) | ||
90 | __field( const char *, reason ) | ||
91 | ), | ||
92 | TP_fast_assign( | ||
93 | __entry->card = (substream)->pcm->card->number; | ||
94 | __entry->device = (substream)->pcm->device; | ||
95 | __entry->number = (substream)->number; | ||
96 | __entry->stream = (substream)->stream; | ||
97 | __entry->reason = (why); | ||
98 | ), | ||
99 | TP_printk("pcmC%dD%d%c/sub%d: ERROR: %s", | ||
100 | __entry->card, __entry->device, | ||
101 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', | ||
102 | __entry->number, __entry->reason) | ||
103 | ); | ||
104 | |||
105 | #endif /* _PCM_TRACE_H */ | ||
106 | |||
107 | /* This part must be outside protection */ | ||
108 | #undef TRACE_INCLUDE_PATH | ||
109 | #define TRACE_INCLUDE_PATH . | ||
110 | #include <trace/define_trace.h> | ||
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index b9184d20c39f..b0e32e161dd1 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c | |||
@@ -403,14 +403,11 @@ free_devinfo(void *private) | |||
403 | { | 403 | { |
404 | struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private; | 404 | struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private; |
405 | 405 | ||
406 | if (dp->timer) | 406 | snd_seq_oss_timer_delete(dp->timer); |
407 | snd_seq_oss_timer_delete(dp->timer); | ||
408 | 407 | ||
409 | if (dp->writeq) | 408 | snd_seq_oss_writeq_delete(dp->writeq); |
410 | snd_seq_oss_writeq_delete(dp->writeq); | ||
411 | 409 | ||
412 | if (dp->readq) | 410 | snd_seq_oss_readq_delete(dp->readq); |
413 | snd_seq_oss_readq_delete(dp->readq); | ||
414 | 411 | ||
415 | kfree(dp); | 412 | kfree(dp); |
416 | } | 413 | } |
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 712110561082..7e0aabb808a6 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c | |||
@@ -86,7 +86,6 @@ static int __init alsa_seq_init(void) | |||
86 | { | 86 | { |
87 | int err; | 87 | int err; |
88 | 88 | ||
89 | snd_seq_autoload_lock(); | ||
90 | if ((err = client_init_data()) < 0) | 89 | if ((err = client_init_data()) < 0) |
91 | goto error; | 90 | goto error; |
92 | 91 | ||
@@ -110,8 +109,8 @@ static int __init alsa_seq_init(void) | |||
110 | if ((err = snd_seq_system_client_init()) < 0) | 109 | if ((err = snd_seq_system_client_init()) < 0) |
111 | goto error; | 110 | goto error; |
112 | 111 | ||
112 | snd_seq_autoload_init(); | ||
113 | error: | 113 | error: |
114 | snd_seq_autoload_unlock(); | ||
115 | return err; | 114 | return err; |
116 | } | 115 | } |
117 | 116 | ||
@@ -131,6 +130,8 @@ static void __exit alsa_seq_exit(void) | |||
131 | 130 | ||
132 | /* release event memory */ | 131 | /* release event memory */ |
133 | snd_sequencer_memory_done(); | 132 | snd_sequencer_memory_done(); |
133 | |||
134 | snd_seq_autoload_exit(); | ||
134 | } | 135 | } |
135 | 136 | ||
136 | module_init(alsa_seq_init) | 137 | module_init(alsa_seq_init) |
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 91a786a783e1..0631bdadd12b 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c | |||
@@ -56,6 +56,7 @@ MODULE_LICENSE("GPL"); | |||
56 | #define DRIVER_LOADED (1<<0) | 56 | #define DRIVER_LOADED (1<<0) |
57 | #define DRIVER_REQUESTED (1<<1) | 57 | #define DRIVER_REQUESTED (1<<1) |
58 | #define DRIVER_LOCKED (1<<2) | 58 | #define DRIVER_LOCKED (1<<2) |
59 | #define DRIVER_REQUESTING (1<<3) | ||
59 | 60 | ||
60 | struct ops_list { | 61 | struct ops_list { |
61 | char id[ID_LEN]; /* driver id */ | 62 | char id[ID_LEN]; /* driver id */ |
@@ -127,42 +128,82 @@ static void snd_seq_device_info(struct snd_info_entry *entry, | |||
127 | 128 | ||
128 | #ifdef CONFIG_MODULES | 129 | #ifdef CONFIG_MODULES |
129 | /* avoid auto-loading during module_init() */ | 130 | /* avoid auto-loading during module_init() */ |
130 | static int snd_seq_in_init; | 131 | static atomic_t snd_seq_in_init = ATOMIC_INIT(1); /* blocked as default */ |
131 | void snd_seq_autoload_lock(void) | 132 | void snd_seq_autoload_lock(void) |
132 | { | 133 | { |
133 | snd_seq_in_init++; | 134 | atomic_inc(&snd_seq_in_init); |
134 | } | 135 | } |
135 | 136 | ||
136 | void snd_seq_autoload_unlock(void) | 137 | void snd_seq_autoload_unlock(void) |
137 | { | 138 | { |
138 | snd_seq_in_init--; | 139 | atomic_dec(&snd_seq_in_init); |
139 | } | 140 | } |
140 | #endif | ||
141 | 141 | ||
142 | void snd_seq_device_load_drivers(void) | 142 | static void autoload_drivers(void) |
143 | { | 143 | { |
144 | #ifdef CONFIG_MODULES | 144 | /* avoid reentrance */ |
145 | struct ops_list *ops; | 145 | if (atomic_inc_return(&snd_seq_in_init) == 1) { |
146 | struct ops_list *ops; | ||
147 | |||
148 | mutex_lock(&ops_mutex); | ||
149 | list_for_each_entry(ops, &opslist, list) { | ||
150 | if ((ops->driver & DRIVER_REQUESTING) && | ||
151 | !(ops->driver & DRIVER_REQUESTED)) { | ||
152 | ops->used++; | ||
153 | mutex_unlock(&ops_mutex); | ||
154 | ops->driver |= DRIVER_REQUESTED; | ||
155 | request_module("snd-%s", ops->id); | ||
156 | mutex_lock(&ops_mutex); | ||
157 | ops->used--; | ||
158 | } | ||
159 | } | ||
160 | mutex_unlock(&ops_mutex); | ||
161 | } | ||
162 | atomic_dec(&snd_seq_in_init); | ||
163 | } | ||
146 | 164 | ||
147 | /* Calling request_module during module_init() | 165 | static void call_autoload(struct work_struct *work) |
148 | * may cause blocking. | 166 | { |
149 | */ | 167 | autoload_drivers(); |
150 | if (snd_seq_in_init) | 168 | } |
151 | return; | ||
152 | 169 | ||
153 | mutex_lock(&ops_mutex); | 170 | static DECLARE_WORK(autoload_work, call_autoload); |
154 | list_for_each_entry(ops, &opslist, list) { | 171 | |
155 | if (! (ops->driver & DRIVER_LOADED) && | 172 | static void try_autoload(struct ops_list *ops) |
156 | ! (ops->driver & DRIVER_REQUESTED)) { | 173 | { |
157 | ops->used++; | 174 | if (!ops->driver) { |
158 | mutex_unlock(&ops_mutex); | 175 | ops->driver |= DRIVER_REQUESTING; |
159 | ops->driver |= DRIVER_REQUESTED; | 176 | schedule_work(&autoload_work); |
160 | request_module("snd-%s", ops->id); | ||
161 | mutex_lock(&ops_mutex); | ||
162 | ops->used--; | ||
163 | } | ||
164 | } | 177 | } |
178 | } | ||
179 | |||
180 | static void queue_autoload_drivers(void) | ||
181 | { | ||
182 | struct ops_list *ops; | ||
183 | |||
184 | mutex_lock(&ops_mutex); | ||
185 | list_for_each_entry(ops, &opslist, list) | ||
186 | try_autoload(ops); | ||
165 | mutex_unlock(&ops_mutex); | 187 | mutex_unlock(&ops_mutex); |
188 | } | ||
189 | |||
190 | void snd_seq_autoload_init(void) | ||
191 | { | ||
192 | atomic_dec(&snd_seq_in_init); | ||
193 | #ifdef CONFIG_SND_SEQUENCER_MODULE | ||
194 | /* initial autoload only when snd-seq is a module */ | ||
195 | queue_autoload_drivers(); | ||
196 | #endif | ||
197 | } | ||
198 | #else | ||
199 | #define try_autoload(ops) /* NOP */ | ||
200 | #endif | ||
201 | |||
202 | void snd_seq_device_load_drivers(void) | ||
203 | { | ||
204 | #ifdef CONFIG_MODULES | ||
205 | queue_autoload_drivers(); | ||
206 | flush_work(&autoload_work); | ||
166 | #endif | 207 | #endif |
167 | } | 208 | } |
168 | 209 | ||
@@ -214,13 +255,14 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, | |||
214 | ops->num_devices++; | 255 | ops->num_devices++; |
215 | mutex_unlock(&ops->reg_mutex); | 256 | mutex_unlock(&ops->reg_mutex); |
216 | 257 | ||
217 | unlock_driver(ops); | ||
218 | |||
219 | if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) { | 258 | if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) { |
220 | snd_seq_device_free(dev); | 259 | snd_seq_device_free(dev); |
221 | return err; | 260 | return err; |
222 | } | 261 | } |
223 | 262 | ||
263 | try_autoload(ops); | ||
264 | unlock_driver(ops); | ||
265 | |||
224 | if (result) | 266 | if (result) |
225 | *result = dev; | 267 | *result = dev; |
226 | 268 | ||
@@ -318,16 +360,12 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, | |||
318 | entry->init_device == NULL || entry->free_device == NULL) | 360 | entry->init_device == NULL || entry->free_device == NULL) |
319 | return -EINVAL; | 361 | return -EINVAL; |
320 | 362 | ||
321 | snd_seq_autoload_lock(); | ||
322 | ops = find_driver(id, 1); | 363 | ops = find_driver(id, 1); |
323 | if (ops == NULL) { | 364 | if (ops == NULL) |
324 | snd_seq_autoload_unlock(); | ||
325 | return -ENOMEM; | 365 | return -ENOMEM; |
326 | } | ||
327 | if (ops->driver & DRIVER_LOADED) { | 366 | if (ops->driver & DRIVER_LOADED) { |
328 | pr_warn("ALSA: seq: driver_register: driver '%s' already exists\n", id); | 367 | pr_warn("ALSA: seq: driver_register: driver '%s' already exists\n", id); |
329 | unlock_driver(ops); | 368 | unlock_driver(ops); |
330 | snd_seq_autoload_unlock(); | ||
331 | return -EBUSY; | 369 | return -EBUSY; |
332 | } | 370 | } |
333 | 371 | ||
@@ -344,7 +382,6 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, | |||
344 | mutex_unlock(&ops->reg_mutex); | 382 | mutex_unlock(&ops->reg_mutex); |
345 | 383 | ||
346 | unlock_driver(ops); | 384 | unlock_driver(ops); |
347 | snd_seq_autoload_unlock(); | ||
348 | 385 | ||
349 | return 0; | 386 | return 0; |
350 | } | 387 | } |
@@ -554,6 +591,9 @@ static int __init alsa_seq_device_init(void) | |||
554 | 591 | ||
555 | static void __exit alsa_seq_device_exit(void) | 592 | static void __exit alsa_seq_device_exit(void) |
556 | { | 593 | { |
594 | #ifdef CONFIG_MODULES | ||
595 | cancel_work_sync(&autoload_work); | ||
596 | #endif | ||
557 | remove_drivers(); | 597 | remove_drivers(); |
558 | #ifdef CONFIG_PROC_FS | 598 | #ifdef CONFIG_PROC_FS |
559 | snd_info_free_entry(info_entry); | 599 | snd_info_free_entry(info_entry); |
@@ -570,6 +610,7 @@ EXPORT_SYMBOL(snd_seq_device_new); | |||
570 | EXPORT_SYMBOL(snd_seq_device_register_driver); | 610 | EXPORT_SYMBOL(snd_seq_device_register_driver); |
571 | EXPORT_SYMBOL(snd_seq_device_unregister_driver); | 611 | EXPORT_SYMBOL(snd_seq_device_unregister_driver); |
572 | #ifdef CONFIG_MODULES | 612 | #ifdef CONFIG_MODULES |
613 | EXPORT_SYMBOL(snd_seq_autoload_init); | ||
573 | EXPORT_SYMBOL(snd_seq_autoload_lock); | 614 | EXPORT_SYMBOL(snd_seq_autoload_lock); |
574 | EXPORT_SYMBOL(snd_seq_autoload_unlock); | 615 | EXPORT_SYMBOL(snd_seq_autoload_unlock); |
575 | #endif | 616 | #endif |
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index 0a418503ec41..84fffabdd129 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c | |||
@@ -39,8 +39,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) | |||
39 | if (! sgbuf) | 39 | if (! sgbuf) |
40 | return -EINVAL; | 40 | return -EINVAL; |
41 | 41 | ||
42 | if (dmab->area) | 42 | vunmap(dmab->area); |
43 | vunmap(dmab->area); | ||
44 | dmab->area = NULL; | 43 | dmab->area = NULL; |
45 | 44 | ||
46 | tmpb.dev.type = SNDRV_DMA_TYPE_DEV; | 45 | tmpb.dev.type = SNDRV_DMA_TYPE_DEV; |
diff --git a/sound/core/sound.c b/sound/core/sound.c index 38ad1a0dd3f7..f1333060bf1c 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -355,8 +355,13 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
355 | 355 | ||
356 | EXPORT_SYMBOL(snd_unregister_device); | 356 | EXPORT_SYMBOL(snd_unregister_device); |
357 | 357 | ||
358 | /* get the assigned device to the given type and device number; | 358 | /** |
359 | * the caller needs to release it via put_device() after using it | 359 | * snd_get_device - get the assigned device to the given type and device number |
360 | * @type: the device type, SNDRV_DEVICE_TYPE_XXX | ||
361 | * @card:the card instance | ||
362 | * @dev: the device index | ||
363 | * | ||
364 | * The caller needs to release it via put_device() after using it. | ||
360 | */ | 365 | */ |
361 | struct device *snd_get_device(int type, struct snd_card *card, int dev) | 366 | struct device *snd_get_device(int type, struct snd_card *card, int dev) |
362 | { | 367 | { |
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index f5fd448dbc57..0388fbbd2c06 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c | |||
@@ -604,21 +604,11 @@ static struct snd_kcontrol_new mts64_ctl_smpte_time_frames = { | |||
604 | static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl, | 604 | static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl, |
605 | struct snd_ctl_elem_info *uinfo) | 605 | struct snd_ctl_elem_info *uinfo) |
606 | { | 606 | { |
607 | static char *texts[5] = { "24", | 607 | static const char * const texts[5] = { |
608 | "25", | 608 | "24", "25", "29.97", "30D", "30" |
609 | "29.97", | 609 | }; |
610 | "30D", | ||
611 | "30" }; | ||
612 | 610 | ||
613 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 611 | return snd_ctl_enum_info(uinfo, 1, 5, texts); |
614 | uinfo->count = 1; | ||
615 | uinfo->value.enumerated.items = 5; | ||
616 | if (uinfo->value.enumerated.item > 4) | ||
617 | uinfo->value.enumerated.item = 4; | ||
618 | strcpy(uinfo->value.enumerated.name, | ||
619 | texts[uinfo->value.enumerated.item]); | ||
620 | |||
621 | return 0; | ||
622 | } | 612 | } |
623 | 613 | ||
624 | static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl, | 614 | static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl, |
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index b178724295f3..d28d8706443c 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c | |||
@@ -99,30 +99,33 @@ static int snd_virmidi_probe(struct platform_device *devptr) | |||
99 | 99 | ||
100 | if (midi_devs[dev] > MAX_MIDI_DEVICES) { | 100 | if (midi_devs[dev] > MAX_MIDI_DEVICES) { |
101 | snd_printk(KERN_WARNING | 101 | snd_printk(KERN_WARNING |
102 | "too much midi devices for virmidi %d: " | 102 | "too much midi devices for virmidi %d: force to use %d\n", |
103 | "force to use %d\n", dev, MAX_MIDI_DEVICES); | 103 | dev, MAX_MIDI_DEVICES); |
104 | midi_devs[dev] = MAX_MIDI_DEVICES; | 104 | midi_devs[dev] = MAX_MIDI_DEVICES; |
105 | } | 105 | } |
106 | for (idx = 0; idx < midi_devs[dev]; idx++) { | 106 | for (idx = 0; idx < midi_devs[dev]; idx++) { |
107 | struct snd_rawmidi *rmidi; | 107 | struct snd_rawmidi *rmidi; |
108 | struct snd_virmidi_dev *rdev; | 108 | struct snd_virmidi_dev *rdev; |
109 | if ((err = snd_virmidi_new(card, idx, &rmidi)) < 0) | 109 | |
110 | err = snd_virmidi_new(card, idx, &rmidi); | ||
111 | if (err < 0) | ||
110 | goto __nodev; | 112 | goto __nodev; |
111 | rdev = rmidi->private_data; | 113 | rdev = rmidi->private_data; |
112 | vmidi->midi[idx] = rmidi; | 114 | vmidi->midi[idx] = rmidi; |
113 | strcpy(rmidi->name, "Virtual Raw MIDI"); | 115 | strcpy(rmidi->name, "Virtual Raw MIDI"); |
114 | rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; | 116 | rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; |
115 | } | 117 | } |
116 | 118 | ||
117 | strcpy(card->driver, "VirMIDI"); | 119 | strcpy(card->driver, "VirMIDI"); |
118 | strcpy(card->shortname, "VirMIDI"); | 120 | strcpy(card->shortname, "VirMIDI"); |
119 | sprintf(card->longname, "Virtual MIDI Card %i", dev + 1); | 121 | sprintf(card->longname, "Virtual MIDI Card %i", dev + 1); |
120 | 122 | ||
121 | if ((err = snd_card_register(card)) == 0) { | 123 | err = snd_card_register(card); |
124 | if (!err) { | ||
122 | platform_set_drvdata(devptr, card); | 125 | platform_set_drvdata(devptr, card); |
123 | return 0; | 126 | return 0; |
124 | } | 127 | } |
125 | __nodev: | 128 | __nodev: |
126 | snd_card_free(card); | 129 | snd_card_free(card); |
127 | return err; | 130 | return err; |
128 | } | 131 | } |
@@ -157,13 +160,15 @@ static int __init alsa_card_virmidi_init(void) | |||
157 | { | 160 | { |
158 | int i, cards, err; | 161 | int i, cards, err; |
159 | 162 | ||
160 | if ((err = platform_driver_register(&snd_virmidi_driver)) < 0) | 163 | err = platform_driver_register(&snd_virmidi_driver); |
164 | if (err < 0) | ||
161 | return err; | 165 | return err; |
162 | 166 | ||
163 | cards = 0; | 167 | cards = 0; |
164 | for (i = 0; i < SNDRV_CARDS; i++) { | 168 | for (i = 0; i < SNDRV_CARDS; i++) { |
165 | struct platform_device *device; | 169 | struct platform_device *device; |
166 | if (! enable[i]) | 170 | |
171 | if (!enable[i]) | ||
167 | continue; | 172 | continue; |
168 | device = platform_device_register_simple(SND_VIRMIDI_DRIVER, | 173 | device = platform_device_register_simple(SND_VIRMIDI_DRIVER, |
169 | i, NULL, 0); | 174 | i, NULL, 0); |
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index e8cc16993903..fc05a37fd017 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c | |||
@@ -416,6 +416,7 @@ int vx_send_rih(struct vx_core *chip, int cmd) | |||
416 | 416 | ||
417 | /** | 417 | /** |
418 | * snd_vx_boot_xilinx - boot up the xilinx interface | 418 | * snd_vx_boot_xilinx - boot up the xilinx interface |
419 | * @chip: VX core instance | ||
419 | * @boot: the boot record to load | 420 | * @boot: the boot record to load |
420 | */ | 421 | */ |
421 | int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot) | 422 | int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot) |
@@ -538,6 +539,8 @@ EXPORT_SYMBOL(snd_vx_threaded_irq_handler); | |||
538 | 539 | ||
539 | /** | 540 | /** |
540 | * snd_vx_irq_handler - interrupt handler | 541 | * snd_vx_irq_handler - interrupt handler |
542 | * @irq: irq number | ||
543 | * @dev: VX core instance | ||
541 | */ | 544 | */ |
542 | irqreturn_t snd_vx_irq_handler(int irq, void *dev) | 545 | irqreturn_t snd_vx_irq_handler(int irq, void *dev) |
543 | { | 546 | { |
@@ -649,6 +652,8 @@ static void vx_proc_init(struct vx_core *chip) | |||
649 | 652 | ||
650 | /** | 653 | /** |
651 | * snd_vx_dsp_boot - load the DSP boot | 654 | * snd_vx_dsp_boot - load the DSP boot |
655 | * @chip: VX core instance | ||
656 | * @boot: firmware data | ||
652 | */ | 657 | */ |
653 | int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot) | 658 | int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot) |
654 | { | 659 | { |
@@ -669,6 +674,8 @@ EXPORT_SYMBOL(snd_vx_dsp_boot); | |||
669 | 674 | ||
670 | /** | 675 | /** |
671 | * snd_vx_dsp_load - load the DSP image | 676 | * snd_vx_dsp_load - load the DSP image |
677 | * @chip: VX core instance | ||
678 | * @dsp: firmware data | ||
672 | */ | 679 | */ |
673 | int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp) | 680 | int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp) |
674 | { | 681 | { |
@@ -768,7 +775,10 @@ EXPORT_SYMBOL(snd_vx_resume); | |||
768 | 775 | ||
769 | /** | 776 | /** |
770 | * snd_vx_create - constructor for struct vx_core | 777 | * snd_vx_create - constructor for struct vx_core |
778 | * @card: card instance | ||
771 | * @hw: hardware specific record | 779 | * @hw: hardware specific record |
780 | * @ops: VX ops pointer | ||
781 | * @extra_size: extra byte size to allocate appending to chip | ||
772 | * | 782 | * |
773 | * this function allocates the instance and prepare for the hardware | 783 | * this function allocates the instance and prepare for the hardware |
774 | * initialization. | 784 | * initialization. |
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index 3b6823fc0606..be9477e30739 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c | |||
@@ -471,30 +471,18 @@ static struct snd_kcontrol_new vx_control_output_level = { | |||
471 | */ | 471 | */ |
472 | static int vx_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 472 | static int vx_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
473 | { | 473 | { |
474 | static char *texts_mic[3] = { | 474 | static const char * const texts_mic[3] = { |
475 | "Digital", "Line", "Mic" | 475 | "Digital", "Line", "Mic" |
476 | }; | 476 | }; |
477 | static char *texts_vx2[2] = { | 477 | static const char * const texts_vx2[2] = { |
478 | "Digital", "Analog" | 478 | "Digital", "Analog" |
479 | }; | 479 | }; |
480 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 480 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
481 | 481 | ||
482 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 482 | if (chip->type >= VX_TYPE_VXPOCKET) |
483 | uinfo->count = 1; | 483 | return snd_ctl_enum_info(uinfo, 1, 3, texts_mic); |
484 | if (chip->type >= VX_TYPE_VXPOCKET) { | 484 | else |
485 | uinfo->value.enumerated.items = 3; | 485 | return snd_ctl_enum_info(uinfo, 1, 2, texts_vx2); |
486 | if (uinfo->value.enumerated.item > 2) | ||
487 | uinfo->value.enumerated.item = 2; | ||
488 | strcpy(uinfo->value.enumerated.name, | ||
489 | texts_mic[uinfo->value.enumerated.item]); | ||
490 | } else { | ||
491 | uinfo->value.enumerated.items = 2; | ||
492 | if (uinfo->value.enumerated.item > 1) | ||
493 | uinfo->value.enumerated.item = 1; | ||
494 | strcpy(uinfo->value.enumerated.name, | ||
495 | texts_vx2[uinfo->value.enumerated.item]); | ||
496 | } | ||
497 | return 0; | ||
498 | } | 486 | } |
499 | 487 | ||
500 | static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 488 | static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -539,18 +527,11 @@ static struct snd_kcontrol_new vx_control_audio_src = { | |||
539 | */ | 527 | */ |
540 | static int vx_clock_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 528 | static int vx_clock_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
541 | { | 529 | { |
542 | static char *texts[3] = { | 530 | static const char * const texts[3] = { |
543 | "Auto", "Internal", "External" | 531 | "Auto", "Internal", "External" |
544 | }; | 532 | }; |
545 | 533 | ||
546 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 534 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
547 | uinfo->count = 1; | ||
548 | uinfo->value.enumerated.items = 3; | ||
549 | if (uinfo->value.enumerated.item > 2) | ||
550 | uinfo->value.enumerated.item = 2; | ||
551 | strcpy(uinfo->value.enumerated.name, | ||
552 | texts[uinfo->value.enumerated.item]); | ||
553 | return 0; | ||
554 | } | 535 | } |
555 | 536 | ||
556 | static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 537 | static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig index 46dff64908c8..2a5b9a6cb6f8 100644 --- a/sound/firewire/Kconfig +++ b/sound/firewire/Kconfig | |||
@@ -13,12 +13,12 @@ config SND_FIREWIRE_LIB | |||
13 | select SND_RAWMIDI | 13 | select SND_RAWMIDI |
14 | 14 | ||
15 | config SND_DICE | 15 | config SND_DICE |
16 | tristate "DICE-based DACs (EXPERIMENTAL)" | 16 | tristate "DICE-based DACs support" |
17 | select SND_HWDEP | 17 | select SND_HWDEP |
18 | select SND_FIREWIRE_LIB | 18 | select SND_FIREWIRE_LIB |
19 | help | 19 | help |
20 | Say Y here to include support for many DACs based on the DICE | 20 | Say Y here to include support for many DACs based on the DICE |
21 | chip family (DICE-II/Jr/Mini) from TC Applied Technologies. | 21 | chip family (DICE-II/Jr/Mini) which TC Applied Technologies produces. |
22 | 22 | ||
23 | At the moment, this driver supports playback only. If you | 23 | At the moment, this driver supports playback only. If you |
24 | want to use devices that support capturing, use FFADO instead. | 24 | want to use devices that support capturing, use FFADO instead. |
@@ -26,15 +26,17 @@ config SND_DICE | |||
26 | To compile this driver as a module, choose M here: the module | 26 | To compile this driver as a module, choose M here: the module |
27 | will be called snd-dice. | 27 | will be called snd-dice. |
28 | 28 | ||
29 | config SND_FIREWIRE_SPEAKERS | 29 | config SND_OXFW |
30 | tristate "FireWire speakers" | 30 | tristate "Oxford Semiconductor FW970/971 chipset support" |
31 | select SND_FIREWIRE_LIB | 31 | select SND_FIREWIRE_LIB |
32 | help | 32 | help |
33 | Say Y here to include support for the Griffin FireWave Surround | 33 | Say Y here to include support for FireWire devices based on |
34 | and the LaCie FireWire Speakers. | 34 | Oxford Semiconductor FW970/971 chipset. |
35 | * Griffin Firewave | ||
36 | * LaCie Firewire Speakers | ||
35 | 37 | ||
36 | To compile this driver as a module, choose M here: the module | 38 | To compile this driver as a module, choose M here: the module |
37 | will be called snd-firewire-speakers. | 39 | will be called snd-oxfw. |
38 | 40 | ||
39 | config SND_ISIGHT | 41 | config SND_ISIGHT |
40 | tristate "Apple iSight microphone" | 42 | tristate "Apple iSight microphone" |
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile index fad8d49306ab..8b37f084b2ab 100644 --- a/sound/firewire/Makefile +++ b/sound/firewire/Makefile | |||
@@ -1,13 +1,12 @@ | |||
1 | snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ | 1 | snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ |
2 | fcp.o cmp.o amdtp.o | 2 | fcp.o cmp.o amdtp.o |
3 | snd-dice-objs := dice.o | 3 | snd-oxfw-objs := oxfw.o |
4 | snd-firewire-speakers-objs := speakers.o | ||
5 | snd-isight-objs := isight.o | 4 | snd-isight-objs := isight.o |
6 | snd-scs1x-objs := scs1x.o | 5 | snd-scs1x-objs := scs1x.o |
7 | 6 | ||
8 | obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o | 7 | obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o |
9 | obj-$(CONFIG_SND_DICE) += snd-dice.o | 8 | obj-$(CONFIG_SND_DICE) += dice/ |
10 | obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o | 9 | obj-$(CONFIG_SND_OXFW) += oxfw/ |
11 | obj-$(CONFIG_SND_ISIGHT) += snd-isight.o | 10 | obj-$(CONFIG_SND_ISIGHT) += snd-isight.o |
12 | obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o | 11 | obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o |
13 | obj-$(CONFIG_SND_FIREWORKS) += fireworks/ | 12 | obj-$(CONFIG_SND_FIREWORKS) += fireworks/ |
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 95fc2eaf11dc..3badc70124ab 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
@@ -1006,11 +1006,7 @@ void amdtp_stream_pcm_abort(struct amdtp_stream *s) | |||
1006 | struct snd_pcm_substream *pcm; | 1006 | struct snd_pcm_substream *pcm; |
1007 | 1007 | ||
1008 | pcm = ACCESS_ONCE(s->pcm); | 1008 | pcm = ACCESS_ONCE(s->pcm); |
1009 | if (pcm) { | 1009 | if (pcm) |
1010 | snd_pcm_stream_lock_irq(pcm); | 1010 | snd_pcm_stop_xrun(pcm); |
1011 | if (snd_pcm_running(pcm)) | ||
1012 | snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN); | ||
1013 | snd_pcm_stream_unlock_irq(pcm); | ||
1014 | } | ||
1015 | } | 1011 | } |
1016 | EXPORT_SYMBOL(amdtp_stream_pcm_abort); | 1012 | EXPORT_SYMBOL(amdtp_stream_pcm_abort); |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index 4823c08196ac..e6e8926275b0 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
@@ -23,7 +23,7 @@ | |||
23 | * corresponds to the end of event in the packet. Out of IEC 61883. | 23 | * corresponds to the end of event in the packet. Out of IEC 61883. |
24 | * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets. | 24 | * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets. |
25 | * The value of data_block_quadlets is used instead of reported value. | 25 | * The value of data_block_quadlets is used instead of reported value. |
26 | * @SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is | 26 | * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is |
27 | * skipped for detecting discontinuity. | 27 | * skipped for detecting discontinuity. |
28 | * @CIP_SKIP_INIT_DBC_CHECK: Only for in-stream. The value of dbc in first | 28 | * @CIP_SKIP_INIT_DBC_CHECK: Only for in-stream. The value of dbc in first |
29 | * packet is not continuous from an initial value. | 29 | * packet is not continuous from an initial value. |
@@ -43,7 +43,27 @@ enum cip_flags { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * enum cip_sfc - a stream's sample rate | 46 | * enum cip_sfc - supported Sampling Frequency Codes (SFCs) |
47 | * @CIP_SFC_32000: 32,000 data blocks | ||
48 | * @CIP_SFC_44100: 44,100 data blocks | ||
49 | * @CIP_SFC_48000: 48,000 data blocks | ||
50 | * @CIP_SFC_88200: 88,200 data blocks | ||
51 | * @CIP_SFC_96000: 96,000 data blocks | ||
52 | * @CIP_SFC_176400: 176,400 data blocks | ||
53 | * @CIP_SFC_192000: 192,000 data blocks | ||
54 | * @CIP_SFC_COUNT: the number of supported SFCs | ||
55 | * | ||
56 | * These values are used to show nominal Sampling Frequency Code in | ||
57 | * Format Dependent Field (FDF) of AMDTP packet header. In IEC 61883-6:2002, | ||
58 | * this code means the number of events per second. Actually the code | ||
59 | * represents the number of data blocks transferred per second in an AMDTP | ||
60 | * stream. | ||
61 | * | ||
62 | * In IEC 61883-6:2005, some extensions were added to support more types of | ||
63 | * data such as 'One Bit LInear Audio', therefore the meaning of SFC became | ||
64 | * different depending on the types. | ||
65 | * | ||
66 | * Currently our implementation is compatible with IEC 61883-6:2002. | ||
47 | */ | 67 | */ |
48 | enum cip_sfc { | 68 | enum cip_sfc { |
49 | CIP_SFC_32000 = 0, | 69 | CIP_SFC_32000 = 0, |
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h index e13eef99c27a..dfbcd233178c 100644 --- a/sound/firewire/bebob/bebob.h +++ b/sound/firewire/bebob/bebob.h | |||
@@ -52,7 +52,7 @@ extern const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES]; | |||
52 | #define SND_BEBOB_CLOCK_INTERNAL "Internal" | 52 | #define SND_BEBOB_CLOCK_INTERNAL "Internal" |
53 | struct snd_bebob_clock_spec { | 53 | struct snd_bebob_clock_spec { |
54 | unsigned int num; | 54 | unsigned int num; |
55 | char *const *labels; | 55 | const char *const *labels; |
56 | int (*get)(struct snd_bebob *bebob, unsigned int *id); | 56 | int (*get)(struct snd_bebob *bebob, unsigned int *id); |
57 | }; | 57 | }; |
58 | struct snd_bebob_rate_spec { | 58 | struct snd_bebob_rate_spec { |
@@ -61,7 +61,7 @@ struct snd_bebob_rate_spec { | |||
61 | }; | 61 | }; |
62 | struct snd_bebob_meter_spec { | 62 | struct snd_bebob_meter_spec { |
63 | unsigned int num; | 63 | unsigned int num; |
64 | char *const *labels; | 64 | const char *const *labels; |
65 | int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size); | 65 | int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size); |
66 | }; | 66 | }; |
67 | struct snd_bebob_spec { | 67 | struct snd_bebob_spec { |
diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c index 3b052ed0fbf5..fc67c1b7cb5b 100644 --- a/sound/firewire/bebob/bebob_focusrite.c +++ b/sound/firewire/bebob/bebob_focusrite.c | |||
@@ -103,10 +103,10 @@ saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) | |||
103 | &data, sizeof(__be32), 0); | 103 | &data, sizeof(__be32), 0); |
104 | } | 104 | } |
105 | 105 | ||
106 | static char *const saffirepro_10_clk_src_labels[] = { | 106 | static const char *const saffirepro_10_clk_src_labels[] = { |
107 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" | 107 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" |
108 | }; | 108 | }; |
109 | static char *const saffirepro_26_clk_src_labels[] = { | 109 | static const char *const saffirepro_26_clk_src_labels[] = { |
110 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" | 110 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" |
111 | }; | 111 | }; |
112 | /* Value maps between registers and labels for SaffirePro 10/26. */ | 112 | /* Value maps between registers and labels for SaffirePro 10/26. */ |
@@ -195,7 +195,7 @@ end: | |||
195 | } | 195 | } |
196 | 196 | ||
197 | struct snd_bebob_spec saffire_le_spec; | 197 | struct snd_bebob_spec saffire_le_spec; |
198 | static char *const saffire_both_clk_src_labels[] = { | 198 | static const char *const saffire_both_clk_src_labels[] = { |
199 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF" | 199 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF" |
200 | }; | 200 | }; |
201 | static int | 201 | static int |
@@ -210,12 +210,12 @@ saffire_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | |||
210 | 210 | ||
211 | return err; | 211 | return err; |
212 | }; | 212 | }; |
213 | static char *const saffire_le_meter_labels[] = { | 213 | static const char *const saffire_le_meter_labels[] = { |
214 | ANA_IN, ANA_IN, DIG_IN, | 214 | ANA_IN, ANA_IN, DIG_IN, |
215 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, | 215 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, |
216 | STM_IN, STM_IN | 216 | STM_IN, STM_IN |
217 | }; | 217 | }; |
218 | static char *const saffire_meter_labels[] = { | 218 | static const char *const saffire_meter_labels[] = { |
219 | ANA_IN, ANA_IN, | 219 | ANA_IN, ANA_IN, |
220 | STM_IN, STM_IN, STM_IN, STM_IN, STM_IN, | 220 | STM_IN, STM_IN, STM_IN, STM_IN, STM_IN, |
221 | }; | 221 | }; |
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c index 70faa3a32526..a422aaa3bb0c 100644 --- a/sound/firewire/bebob/bebob_maudio.c +++ b/sound/firewire/bebob/bebob_maudio.c | |||
@@ -340,7 +340,7 @@ end: | |||
340 | } | 340 | } |
341 | 341 | ||
342 | /* Clock source control for special firmware */ | 342 | /* Clock source control for special firmware */ |
343 | static char *const special_clk_labels[] = { | 343 | static const char *const special_clk_labels[] = { |
344 | SND_BEBOB_CLOCK_INTERNAL " with Digital Mute", "Digital", | 344 | SND_BEBOB_CLOCK_INTERNAL " with Digital Mute", "Digital", |
345 | "Word Clock", SND_BEBOB_CLOCK_INTERNAL}; | 345 | "Word Clock", SND_BEBOB_CLOCK_INTERNAL}; |
346 | static int special_clk_get(struct snd_bebob *bebob, unsigned int *id) | 346 | static int special_clk_get(struct snd_bebob *bebob, unsigned int *id) |
@@ -352,17 +352,8 @@ static int special_clk_get(struct snd_bebob *bebob, unsigned int *id) | |||
352 | static int special_clk_ctl_info(struct snd_kcontrol *kctl, | 352 | static int special_clk_ctl_info(struct snd_kcontrol *kctl, |
353 | struct snd_ctl_elem_info *einf) | 353 | struct snd_ctl_elem_info *einf) |
354 | { | 354 | { |
355 | einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 355 | return snd_ctl_enum_info(einf, 1, ARRAY_SIZE(special_clk_labels), |
356 | einf->count = 1; | 356 | special_clk_labels); |
357 | einf->value.enumerated.items = ARRAY_SIZE(special_clk_labels); | ||
358 | |||
359 | if (einf->value.enumerated.item >= einf->value.enumerated.items) | ||
360 | einf->value.enumerated.item = einf->value.enumerated.items - 1; | ||
361 | |||
362 | strcpy(einf->value.enumerated.name, | ||
363 | special_clk_labels[einf->value.enumerated.item]); | ||
364 | |||
365 | return 0; | ||
366 | } | 357 | } |
367 | static int special_clk_ctl_get(struct snd_kcontrol *kctl, | 358 | static int special_clk_ctl_get(struct snd_kcontrol *kctl, |
368 | struct snd_ctl_elem_value *uval) | 359 | struct snd_ctl_elem_value *uval) |
@@ -438,23 +429,15 @@ static struct snd_kcontrol_new special_sync_ctl = { | |||
438 | }; | 429 | }; |
439 | 430 | ||
440 | /* Digital input interface control for special firmware */ | 431 | /* Digital input interface control for special firmware */ |
441 | static char *const special_dig_in_iface_labels[] = { | 432 | static const char *const special_dig_in_iface_labels[] = { |
442 | "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical" | 433 | "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical" |
443 | }; | 434 | }; |
444 | static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl, | 435 | static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl, |
445 | struct snd_ctl_elem_info *einf) | 436 | struct snd_ctl_elem_info *einf) |
446 | { | 437 | { |
447 | einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 438 | return snd_ctl_enum_info(einf, 1, |
448 | einf->count = 1; | 439 | ARRAY_SIZE(special_dig_in_iface_labels), |
449 | einf->value.enumerated.items = ARRAY_SIZE(special_dig_in_iface_labels); | 440 | special_dig_in_iface_labels); |
450 | |||
451 | if (einf->value.enumerated.item >= einf->value.enumerated.items) | ||
452 | einf->value.enumerated.item = einf->value.enumerated.items - 1; | ||
453 | |||
454 | strcpy(einf->value.enumerated.name, | ||
455 | special_dig_in_iface_labels[einf->value.enumerated.item]); | ||
456 | |||
457 | return 0; | ||
458 | } | 441 | } |
459 | static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl, | 442 | static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl, |
460 | struct snd_ctl_elem_value *uval) | 443 | struct snd_ctl_elem_value *uval) |
@@ -539,23 +522,15 @@ static struct snd_kcontrol_new special_dig_in_iface_ctl = { | |||
539 | }; | 522 | }; |
540 | 523 | ||
541 | /* Digital output interface control for special firmware */ | 524 | /* Digital output interface control for special firmware */ |
542 | static char *const special_dig_out_iface_labels[] = { | 525 | static const char *const special_dig_out_iface_labels[] = { |
543 | "S/PDIF Optical and Coaxial", "ADAT Optical" | 526 | "S/PDIF Optical and Coaxial", "ADAT Optical" |
544 | }; | 527 | }; |
545 | static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl, | 528 | static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl, |
546 | struct snd_ctl_elem_info *einf) | 529 | struct snd_ctl_elem_info *einf) |
547 | { | 530 | { |
548 | einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 531 | return snd_ctl_enum_info(einf, 1, |
549 | einf->count = 1; | 532 | ARRAY_SIZE(special_dig_out_iface_labels), |
550 | einf->value.enumerated.items = ARRAY_SIZE(special_dig_out_iface_labels); | 533 | special_dig_out_iface_labels); |
551 | |||
552 | if (einf->value.enumerated.item >= einf->value.enumerated.items) | ||
553 | einf->value.enumerated.item = einf->value.enumerated.items - 1; | ||
554 | |||
555 | strcpy(einf->value.enumerated.name, | ||
556 | special_dig_out_iface_labels[einf->value.enumerated.item]); | ||
557 | |||
558 | return 0; | ||
559 | } | 534 | } |
560 | static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl, | 535 | static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl, |
561 | struct snd_ctl_elem_value *uval) | 536 | struct snd_ctl_elem_value *uval) |
@@ -631,7 +606,7 @@ end: | |||
631 | } | 606 | } |
632 | 607 | ||
633 | /* Hardware metering for special firmware */ | 608 | /* Hardware metering for special firmware */ |
634 | static char *const special_meter_labels[] = { | 609 | static const char *const special_meter_labels[] = { |
635 | ANA_IN, ANA_IN, ANA_IN, ANA_IN, | 610 | ANA_IN, ANA_IN, ANA_IN, ANA_IN, |
636 | SPDIF_IN, | 611 | SPDIF_IN, |
637 | ADAT_IN, ADAT_IN, ADAT_IN, ADAT_IN, | 612 | ADAT_IN, ADAT_IN, ADAT_IN, ADAT_IN, |
@@ -671,30 +646,30 @@ end: | |||
671 | } | 646 | } |
672 | 647 | ||
673 | /* last 4 bytes are omitted because it's clock info. */ | 648 | /* last 4 bytes are omitted because it's clock info. */ |
674 | static char *const fw410_meter_labels[] = { | 649 | static const char *const fw410_meter_labels[] = { |
675 | ANA_IN, DIG_IN, | 650 | ANA_IN, DIG_IN, |
676 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, DIG_OUT, | 651 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, DIG_OUT, |
677 | HP_OUT | 652 | HP_OUT |
678 | }; | 653 | }; |
679 | static char *const audiophile_meter_labels[] = { | 654 | static const char *const audiophile_meter_labels[] = { |
680 | ANA_IN, DIG_IN, | 655 | ANA_IN, DIG_IN, |
681 | ANA_OUT, ANA_OUT, DIG_OUT, | 656 | ANA_OUT, ANA_OUT, DIG_OUT, |
682 | HP_OUT, AUX_OUT, | 657 | HP_OUT, AUX_OUT, |
683 | }; | 658 | }; |
684 | static char *const solo_meter_labels[] = { | 659 | static const char *const solo_meter_labels[] = { |
685 | ANA_IN, DIG_IN, | 660 | ANA_IN, DIG_IN, |
686 | STRM_IN, STRM_IN, | 661 | STRM_IN, STRM_IN, |
687 | ANA_OUT, DIG_OUT | 662 | ANA_OUT, DIG_OUT |
688 | }; | 663 | }; |
689 | 664 | ||
690 | /* no clock info */ | 665 | /* no clock info */ |
691 | static char *const ozonic_meter_labels[] = { | 666 | static const char *const ozonic_meter_labels[] = { |
692 | ANA_IN, ANA_IN, | 667 | ANA_IN, ANA_IN, |
693 | STRM_IN, STRM_IN, | 668 | STRM_IN, STRM_IN, |
694 | ANA_OUT, ANA_OUT | 669 | ANA_OUT, ANA_OUT |
695 | }; | 670 | }; |
696 | /* TODO: need testers. these positions are based on authour's assumption */ | 671 | /* TODO: need testers. these positions are based on authour's assumption */ |
697 | static char *const nrv10_meter_labels[] = { | 672 | static const char *const nrv10_meter_labels[] = { |
698 | ANA_IN, ANA_IN, ANA_IN, ANA_IN, | 673 | ANA_IN, ANA_IN, ANA_IN, ANA_IN, |
699 | DIG_IN, | 674 | DIG_IN, |
700 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, | 675 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, |
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c index 9940611f2e1b..ad635004d699 100644 --- a/sound/firewire/bebob/bebob_terratec.c +++ b/sound/firewire/bebob/bebob_terratec.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #include "./bebob.h" | 9 | #include "./bebob.h" |
10 | 10 | ||
11 | static char *const phase88_rack_clk_src_labels[] = { | 11 | static const char *const phase88_rack_clk_src_labels[] = { |
12 | SND_BEBOB_CLOCK_INTERNAL, "Digital In", "Word Clock" | 12 | SND_BEBOB_CLOCK_INTERNAL, "Digital In", "Word Clock" |
13 | }; | 13 | }; |
14 | static int | 14 | static int |
@@ -34,7 +34,7 @@ end: | |||
34 | return err; | 34 | return err; |
35 | } | 35 | } |
36 | 36 | ||
37 | static char *const phase24_series_clk_src_labels[] = { | 37 | static const char *const phase24_series_clk_src_labels[] = { |
38 | SND_BEBOB_CLOCK_INTERNAL, "Digital In" | 38 | SND_BEBOB_CLOCK_INTERNAL, "Digital In" |
39 | }; | 39 | }; |
40 | static int | 40 | static int |
diff --git a/sound/firewire/bebob/bebob_yamaha.c b/sound/firewire/bebob/bebob_yamaha.c index 9b7e798180ff..ef1fe3823a9c 100644 --- a/sound/firewire/bebob/bebob_yamaha.c +++ b/sound/firewire/bebob/bebob_yamaha.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * reccomend users to close ffado-mixer at 192.0kHz if mixer is needless. | 28 | * reccomend users to close ffado-mixer at 192.0kHz if mixer is needless. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | static char *const clk_src_labels[] = {SND_BEBOB_CLOCK_INTERNAL, "SPDIF"}; | 31 | static const char *const clk_src_labels[] = {SND_BEBOB_CLOCK_INTERNAL, "SPDIF"}; |
32 | static int | 32 | static int |
33 | clk_src_get(struct snd_bebob *bebob, unsigned int *id) | 33 | clk_src_get(struct snd_bebob *bebob, unsigned int *id) |
34 | { | 34 | { |
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index ba8df5a1be39..ae3bc1940efa 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c | |||
@@ -114,6 +114,7 @@ static int pcr_modify(struct cmp_connection *c, | |||
114 | * cmp_connection_init - initializes a connection manager | 114 | * cmp_connection_init - initializes a connection manager |
115 | * @c: the connection manager to initialize | 115 | * @c: the connection manager to initialize |
116 | * @unit: a unit of the target device | 116 | * @unit: a unit of the target device |
117 | * @direction: input or output | ||
117 | * @pcr_index: the index of the iPCR/oPCR on the target device | 118 | * @pcr_index: the index of the iPCR/oPCR on the target device |
118 | */ | 119 | */ |
119 | int cmp_connection_init(struct cmp_connection *c, | 120 | int cmp_connection_init(struct cmp_connection *c, |
@@ -154,6 +155,7 @@ EXPORT_SYMBOL(cmp_connection_init); | |||
154 | /** | 155 | /** |
155 | * cmp_connection_check_used - check connection is already esablished or not | 156 | * cmp_connection_check_used - check connection is already esablished or not |
156 | * @c: the connection manager to be checked | 157 | * @c: the connection manager to be checked |
158 | * @used: the pointer to store the result of checking the connection | ||
157 | */ | 159 | */ |
158 | int cmp_connection_check_used(struct cmp_connection *c, bool *used) | 160 | int cmp_connection_check_used(struct cmp_connection *c, bool *used) |
159 | { | 161 | { |
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c deleted file mode 100644 index e3a04d69c853..000000000000 --- a/sound/firewire/dice.c +++ /dev/null | |||
@@ -1,1511 +0,0 @@ | |||
1 | /* | ||
2 | * TC Applied Technologies Digital Interface Communications Engine driver | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/compat.h> | ||
9 | #include <linux/completion.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/firewire.h> | ||
13 | #include <linux/firewire-constants.h> | ||
14 | #include <linux/jiffies.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/mod_devicetable.h> | ||
17 | #include <linux/mutex.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <sound/control.h> | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/firewire.h> | ||
24 | #include <sound/hwdep.h> | ||
25 | #include <sound/info.h> | ||
26 | #include <sound/initval.h> | ||
27 | #include <sound/pcm.h> | ||
28 | #include <sound/pcm_params.h> | ||
29 | #include "amdtp.h" | ||
30 | #include "iso-resources.h" | ||
31 | #include "lib.h" | ||
32 | #include "dice-interface.h" | ||
33 | |||
34 | |||
35 | struct dice { | ||
36 | struct snd_card *card; | ||
37 | struct fw_unit *unit; | ||
38 | spinlock_t lock; | ||
39 | struct mutex mutex; | ||
40 | unsigned int global_offset; | ||
41 | unsigned int rx_offset; | ||
42 | unsigned int clock_caps; | ||
43 | unsigned int rx_channels[3]; | ||
44 | unsigned int rx_midi_ports[3]; | ||
45 | struct fw_address_handler notification_handler; | ||
46 | int owner_generation; | ||
47 | int dev_lock_count; /* > 0 driver, < 0 userspace */ | ||
48 | bool dev_lock_changed; | ||
49 | bool global_enabled; | ||
50 | struct completion clock_accepted; | ||
51 | wait_queue_head_t hwdep_wait; | ||
52 | u32 notification_bits; | ||
53 | struct fw_iso_resources resources; | ||
54 | struct amdtp_stream stream; | ||
55 | }; | ||
56 | |||
57 | MODULE_DESCRIPTION("DICE driver"); | ||
58 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
59 | MODULE_LICENSE("GPL v2"); | ||
60 | |||
61 | static const unsigned int dice_rates[] = { | ||
62 | /* mode 0 */ | ||
63 | [0] = 32000, | ||
64 | [1] = 44100, | ||
65 | [2] = 48000, | ||
66 | /* mode 1 */ | ||
67 | [3] = 88200, | ||
68 | [4] = 96000, | ||
69 | /* mode 2 */ | ||
70 | [5] = 176400, | ||
71 | [6] = 192000, | ||
72 | }; | ||
73 | |||
74 | static unsigned int rate_to_index(unsigned int rate) | ||
75 | { | ||
76 | unsigned int i; | ||
77 | |||
78 | for (i = 0; i < ARRAY_SIZE(dice_rates); ++i) | ||
79 | if (dice_rates[i] == rate) | ||
80 | return i; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static unsigned int rate_index_to_mode(unsigned int rate_index) | ||
86 | { | ||
87 | return ((int)rate_index - 1) / 2; | ||
88 | } | ||
89 | |||
90 | static void dice_lock_changed(struct dice *dice) | ||
91 | { | ||
92 | dice->dev_lock_changed = true; | ||
93 | wake_up(&dice->hwdep_wait); | ||
94 | } | ||
95 | |||
96 | static int dice_try_lock(struct dice *dice) | ||
97 | { | ||
98 | int err; | ||
99 | |||
100 | spin_lock_irq(&dice->lock); | ||
101 | |||
102 | if (dice->dev_lock_count < 0) { | ||
103 | err = -EBUSY; | ||
104 | goto out; | ||
105 | } | ||
106 | |||
107 | if (dice->dev_lock_count++ == 0) | ||
108 | dice_lock_changed(dice); | ||
109 | err = 0; | ||
110 | |||
111 | out: | ||
112 | spin_unlock_irq(&dice->lock); | ||
113 | |||
114 | return err; | ||
115 | } | ||
116 | |||
117 | static void dice_unlock(struct dice *dice) | ||
118 | { | ||
119 | spin_lock_irq(&dice->lock); | ||
120 | |||
121 | if (WARN_ON(dice->dev_lock_count <= 0)) | ||
122 | goto out; | ||
123 | |||
124 | if (--dice->dev_lock_count == 0) | ||
125 | dice_lock_changed(dice); | ||
126 | |||
127 | out: | ||
128 | spin_unlock_irq(&dice->lock); | ||
129 | } | ||
130 | |||
131 | static inline u64 global_address(struct dice *dice, unsigned int offset) | ||
132 | { | ||
133 | return DICE_PRIVATE_SPACE + dice->global_offset + offset; | ||
134 | } | ||
135 | |||
136 | // TODO: rx index | ||
137 | static inline u64 rx_address(struct dice *dice, unsigned int offset) | ||
138 | { | ||
139 | return DICE_PRIVATE_SPACE + dice->rx_offset + offset; | ||
140 | } | ||
141 | |||
142 | static int dice_owner_set(struct dice *dice) | ||
143 | { | ||
144 | struct fw_device *device = fw_parent_device(dice->unit); | ||
145 | __be64 *buffer; | ||
146 | int err, errors = 0; | ||
147 | |||
148 | buffer = kmalloc(2 * 8, GFP_KERNEL); | ||
149 | if (!buffer) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | for (;;) { | ||
153 | buffer[0] = cpu_to_be64(OWNER_NO_OWNER); | ||
154 | buffer[1] = cpu_to_be64( | ||
155 | ((u64)device->card->node_id << OWNER_NODE_SHIFT) | | ||
156 | dice->notification_handler.offset); | ||
157 | |||
158 | dice->owner_generation = device->generation; | ||
159 | smp_rmb(); /* node_id vs. generation */ | ||
160 | err = snd_fw_transaction(dice->unit, | ||
161 | TCODE_LOCK_COMPARE_SWAP, | ||
162 | global_address(dice, GLOBAL_OWNER), | ||
163 | buffer, 2 * 8, | ||
164 | FW_FIXED_GENERATION | | ||
165 | dice->owner_generation); | ||
166 | |||
167 | if (err == 0) { | ||
168 | if (buffer[0] != cpu_to_be64(OWNER_NO_OWNER)) { | ||
169 | dev_err(&dice->unit->device, | ||
170 | "device is already in use\n"); | ||
171 | err = -EBUSY; | ||
172 | } | ||
173 | break; | ||
174 | } | ||
175 | if (err != -EAGAIN || ++errors >= 3) | ||
176 | break; | ||
177 | |||
178 | msleep(20); | ||
179 | } | ||
180 | |||
181 | kfree(buffer); | ||
182 | |||
183 | return err; | ||
184 | } | ||
185 | |||
186 | static int dice_owner_update(struct dice *dice) | ||
187 | { | ||
188 | struct fw_device *device = fw_parent_device(dice->unit); | ||
189 | __be64 *buffer; | ||
190 | int err; | ||
191 | |||
192 | if (dice->owner_generation == -1) | ||
193 | return 0; | ||
194 | |||
195 | buffer = kmalloc(2 * 8, GFP_KERNEL); | ||
196 | if (!buffer) | ||
197 | return -ENOMEM; | ||
198 | |||
199 | buffer[0] = cpu_to_be64(OWNER_NO_OWNER); | ||
200 | buffer[1] = cpu_to_be64( | ||
201 | ((u64)device->card->node_id << OWNER_NODE_SHIFT) | | ||
202 | dice->notification_handler.offset); | ||
203 | |||
204 | dice->owner_generation = device->generation; | ||
205 | smp_rmb(); /* node_id vs. generation */ | ||
206 | err = snd_fw_transaction(dice->unit, TCODE_LOCK_COMPARE_SWAP, | ||
207 | global_address(dice, GLOBAL_OWNER), | ||
208 | buffer, 2 * 8, | ||
209 | FW_FIXED_GENERATION | dice->owner_generation); | ||
210 | |||
211 | if (err == 0) { | ||
212 | if (buffer[0] != cpu_to_be64(OWNER_NO_OWNER)) { | ||
213 | dev_err(&dice->unit->device, | ||
214 | "device is already in use\n"); | ||
215 | err = -EBUSY; | ||
216 | } | ||
217 | } else if (err == -EAGAIN) { | ||
218 | err = 0; /* try again later */ | ||
219 | } | ||
220 | |||
221 | kfree(buffer); | ||
222 | |||
223 | if (err < 0) | ||
224 | dice->owner_generation = -1; | ||
225 | |||
226 | return err; | ||
227 | } | ||
228 | |||
229 | static void dice_owner_clear(struct dice *dice) | ||
230 | { | ||
231 | struct fw_device *device = fw_parent_device(dice->unit); | ||
232 | __be64 *buffer; | ||
233 | |||
234 | buffer = kmalloc(2 * 8, GFP_KERNEL); | ||
235 | if (!buffer) | ||
236 | return; | ||
237 | |||
238 | buffer[0] = cpu_to_be64( | ||
239 | ((u64)device->card->node_id << OWNER_NODE_SHIFT) | | ||
240 | dice->notification_handler.offset); | ||
241 | buffer[1] = cpu_to_be64(OWNER_NO_OWNER); | ||
242 | snd_fw_transaction(dice->unit, TCODE_LOCK_COMPARE_SWAP, | ||
243 | global_address(dice, GLOBAL_OWNER), | ||
244 | buffer, 2 * 8, FW_QUIET | | ||
245 | FW_FIXED_GENERATION | dice->owner_generation); | ||
246 | |||
247 | kfree(buffer); | ||
248 | |||
249 | dice->owner_generation = -1; | ||
250 | } | ||
251 | |||
252 | static int dice_enable_set(struct dice *dice) | ||
253 | { | ||
254 | __be32 value; | ||
255 | int err; | ||
256 | |||
257 | value = cpu_to_be32(1); | ||
258 | err = snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
259 | global_address(dice, GLOBAL_ENABLE), | ||
260 | &value, 4, | ||
261 | FW_FIXED_GENERATION | dice->owner_generation); | ||
262 | if (err < 0) | ||
263 | return err; | ||
264 | |||
265 | dice->global_enabled = true; | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static void dice_enable_clear(struct dice *dice) | ||
271 | { | ||
272 | __be32 value; | ||
273 | |||
274 | if (!dice->global_enabled) | ||
275 | return; | ||
276 | |||
277 | value = 0; | ||
278 | snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
279 | global_address(dice, GLOBAL_ENABLE), | ||
280 | &value, 4, FW_QUIET | | ||
281 | FW_FIXED_GENERATION | dice->owner_generation); | ||
282 | |||
283 | dice->global_enabled = false; | ||
284 | } | ||
285 | |||
286 | static void dice_notification(struct fw_card *card, struct fw_request *request, | ||
287 | int tcode, int destination, int source, | ||
288 | int generation, unsigned long long offset, | ||
289 | void *data, size_t length, void *callback_data) | ||
290 | { | ||
291 | struct dice *dice = callback_data; | ||
292 | u32 bits; | ||
293 | unsigned long flags; | ||
294 | |||
295 | if (tcode != TCODE_WRITE_QUADLET_REQUEST) { | ||
296 | fw_send_response(card, request, RCODE_TYPE_ERROR); | ||
297 | return; | ||
298 | } | ||
299 | if ((offset & 3) != 0) { | ||
300 | fw_send_response(card, request, RCODE_ADDRESS_ERROR); | ||
301 | return; | ||
302 | } | ||
303 | |||
304 | bits = be32_to_cpup(data); | ||
305 | |||
306 | spin_lock_irqsave(&dice->lock, flags); | ||
307 | dice->notification_bits |= bits; | ||
308 | spin_unlock_irqrestore(&dice->lock, flags); | ||
309 | |||
310 | fw_send_response(card, request, RCODE_COMPLETE); | ||
311 | |||
312 | if (bits & NOTIFY_CLOCK_ACCEPTED) | ||
313 | complete(&dice->clock_accepted); | ||
314 | wake_up(&dice->hwdep_wait); | ||
315 | } | ||
316 | |||
317 | static int dice_rate_constraint(struct snd_pcm_hw_params *params, | ||
318 | struct snd_pcm_hw_rule *rule) | ||
319 | { | ||
320 | struct dice *dice = rule->private; | ||
321 | const struct snd_interval *channels = | ||
322 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
323 | struct snd_interval *rate = | ||
324 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
325 | struct snd_interval allowed_rates = { | ||
326 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
327 | }; | ||
328 | unsigned int i, mode; | ||
329 | |||
330 | for (i = 0; i < ARRAY_SIZE(dice_rates); ++i) { | ||
331 | mode = rate_index_to_mode(i); | ||
332 | if ((dice->clock_caps & (1 << i)) && | ||
333 | snd_interval_test(channels, dice->rx_channels[mode])) { | ||
334 | allowed_rates.min = min(allowed_rates.min, | ||
335 | dice_rates[i]); | ||
336 | allowed_rates.max = max(allowed_rates.max, | ||
337 | dice_rates[i]); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | return snd_interval_refine(rate, &allowed_rates); | ||
342 | } | ||
343 | |||
344 | static int dice_channels_constraint(struct snd_pcm_hw_params *params, | ||
345 | struct snd_pcm_hw_rule *rule) | ||
346 | { | ||
347 | struct dice *dice = rule->private; | ||
348 | const struct snd_interval *rate = | ||
349 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); | ||
350 | struct snd_interval *channels = | ||
351 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
352 | struct snd_interval allowed_channels = { | ||
353 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
354 | }; | ||
355 | unsigned int i, mode; | ||
356 | |||
357 | for (i = 0; i < ARRAY_SIZE(dice_rates); ++i) | ||
358 | if ((dice->clock_caps & (1 << i)) && | ||
359 | snd_interval_test(rate, dice_rates[i])) { | ||
360 | mode = rate_index_to_mode(i); | ||
361 | allowed_channels.min = min(allowed_channels.min, | ||
362 | dice->rx_channels[mode]); | ||
363 | allowed_channels.max = max(allowed_channels.max, | ||
364 | dice->rx_channels[mode]); | ||
365 | } | ||
366 | |||
367 | return snd_interval_refine(channels, &allowed_channels); | ||
368 | } | ||
369 | |||
370 | static int dice_open(struct snd_pcm_substream *substream) | ||
371 | { | ||
372 | static const struct snd_pcm_hardware hardware = { | ||
373 | .info = SNDRV_PCM_INFO_MMAP | | ||
374 | SNDRV_PCM_INFO_MMAP_VALID | | ||
375 | SNDRV_PCM_INFO_BATCH | | ||
376 | SNDRV_PCM_INFO_INTERLEAVED | | ||
377 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
378 | .formats = AMDTP_OUT_PCM_FORMAT_BITS, | ||
379 | .channels_min = UINT_MAX, | ||
380 | .channels_max = 0, | ||
381 | .buffer_bytes_max = 16 * 1024 * 1024, | ||
382 | .period_bytes_min = 1, | ||
383 | .period_bytes_max = UINT_MAX, | ||
384 | .periods_min = 1, | ||
385 | .periods_max = UINT_MAX, | ||
386 | }; | ||
387 | struct dice *dice = substream->private_data; | ||
388 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
389 | unsigned int i; | ||
390 | int err; | ||
391 | |||
392 | err = dice_try_lock(dice); | ||
393 | if (err < 0) | ||
394 | goto error; | ||
395 | |||
396 | runtime->hw = hardware; | ||
397 | |||
398 | for (i = 0; i < ARRAY_SIZE(dice_rates); ++i) | ||
399 | if (dice->clock_caps & (1 << i)) | ||
400 | runtime->hw.rates |= | ||
401 | snd_pcm_rate_to_rate_bit(dice_rates[i]); | ||
402 | snd_pcm_limit_hw_rates(runtime); | ||
403 | |||
404 | for (i = 0; i < 3; ++i) | ||
405 | if (dice->rx_channels[i]) { | ||
406 | runtime->hw.channels_min = min(runtime->hw.channels_min, | ||
407 | dice->rx_channels[i]); | ||
408 | runtime->hw.channels_max = max(runtime->hw.channels_max, | ||
409 | dice->rx_channels[i]); | ||
410 | } | ||
411 | |||
412 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
413 | dice_rate_constraint, dice, | ||
414 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
415 | if (err < 0) | ||
416 | goto err_lock; | ||
417 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
418 | dice_channels_constraint, dice, | ||
419 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
420 | if (err < 0) | ||
421 | goto err_lock; | ||
422 | |||
423 | err = amdtp_stream_add_pcm_hw_constraints(&dice->stream, runtime); | ||
424 | if (err < 0) | ||
425 | goto err_lock; | ||
426 | |||
427 | return 0; | ||
428 | |||
429 | err_lock: | ||
430 | dice_unlock(dice); | ||
431 | error: | ||
432 | return err; | ||
433 | } | ||
434 | |||
435 | static int dice_close(struct snd_pcm_substream *substream) | ||
436 | { | ||
437 | struct dice *dice = substream->private_data; | ||
438 | |||
439 | dice_unlock(dice); | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int dice_stream_start_packets(struct dice *dice) | ||
445 | { | ||
446 | int err; | ||
447 | |||
448 | if (amdtp_stream_running(&dice->stream)) | ||
449 | return 0; | ||
450 | |||
451 | err = amdtp_stream_start(&dice->stream, dice->resources.channel, | ||
452 | fw_parent_device(dice->unit)->max_speed); | ||
453 | if (err < 0) | ||
454 | return err; | ||
455 | |||
456 | err = dice_enable_set(dice); | ||
457 | if (err < 0) { | ||
458 | amdtp_stream_stop(&dice->stream); | ||
459 | return err; | ||
460 | } | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int dice_stream_start(struct dice *dice) | ||
466 | { | ||
467 | __be32 channel; | ||
468 | int err; | ||
469 | |||
470 | if (!dice->resources.allocated) { | ||
471 | err = fw_iso_resources_allocate(&dice->resources, | ||
472 | amdtp_stream_get_max_payload(&dice->stream), | ||
473 | fw_parent_device(dice->unit)->max_speed); | ||
474 | if (err < 0) | ||
475 | goto error; | ||
476 | |||
477 | channel = cpu_to_be32(dice->resources.channel); | ||
478 | err = snd_fw_transaction(dice->unit, | ||
479 | TCODE_WRITE_QUADLET_REQUEST, | ||
480 | rx_address(dice, RX_ISOCHRONOUS), | ||
481 | &channel, 4, 0); | ||
482 | if (err < 0) | ||
483 | goto err_resources; | ||
484 | } | ||
485 | |||
486 | err = dice_stream_start_packets(dice); | ||
487 | if (err < 0) | ||
488 | goto err_rx_channel; | ||
489 | |||
490 | return 0; | ||
491 | |||
492 | err_rx_channel: | ||
493 | channel = cpu_to_be32((u32)-1); | ||
494 | snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
495 | rx_address(dice, RX_ISOCHRONOUS), &channel, 4, 0); | ||
496 | err_resources: | ||
497 | fw_iso_resources_free(&dice->resources); | ||
498 | error: | ||
499 | return err; | ||
500 | } | ||
501 | |||
502 | static void dice_stream_stop_packets(struct dice *dice) | ||
503 | { | ||
504 | if (amdtp_stream_running(&dice->stream)) { | ||
505 | dice_enable_clear(dice); | ||
506 | amdtp_stream_stop(&dice->stream); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | static void dice_stream_stop(struct dice *dice) | ||
511 | { | ||
512 | __be32 channel; | ||
513 | |||
514 | dice_stream_stop_packets(dice); | ||
515 | |||
516 | if (!dice->resources.allocated) | ||
517 | return; | ||
518 | |||
519 | channel = cpu_to_be32((u32)-1); | ||
520 | snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
521 | rx_address(dice, RX_ISOCHRONOUS), &channel, 4, 0); | ||
522 | |||
523 | fw_iso_resources_free(&dice->resources); | ||
524 | } | ||
525 | |||
526 | static int dice_change_rate(struct dice *dice, unsigned int clock_rate) | ||
527 | { | ||
528 | __be32 value; | ||
529 | int err; | ||
530 | |||
531 | reinit_completion(&dice->clock_accepted); | ||
532 | |||
533 | value = cpu_to_be32(clock_rate | CLOCK_SOURCE_ARX1); | ||
534 | err = snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
535 | global_address(dice, GLOBAL_CLOCK_SELECT), | ||
536 | &value, 4, 0); | ||
537 | if (err < 0) | ||
538 | return err; | ||
539 | |||
540 | if (!wait_for_completion_timeout(&dice->clock_accepted, | ||
541 | msecs_to_jiffies(100))) | ||
542 | dev_warn(&dice->unit->device, "clock change timed out\n"); | ||
543 | |||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static int dice_hw_params(struct snd_pcm_substream *substream, | ||
548 | struct snd_pcm_hw_params *hw_params) | ||
549 | { | ||
550 | struct dice *dice = substream->private_data; | ||
551 | unsigned int rate_index, mode, rate, channels, i; | ||
552 | int err; | ||
553 | |||
554 | mutex_lock(&dice->mutex); | ||
555 | dice_stream_stop(dice); | ||
556 | mutex_unlock(&dice->mutex); | ||
557 | |||
558 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
559 | params_buffer_bytes(hw_params)); | ||
560 | if (err < 0) | ||
561 | return err; | ||
562 | |||
563 | rate = params_rate(hw_params); | ||
564 | rate_index = rate_to_index(rate); | ||
565 | err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); | ||
566 | if (err < 0) | ||
567 | return err; | ||
568 | |||
569 | /* | ||
570 | * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in | ||
571 | * one data block of AMDTP packet. Thus sampling transfer frequency is | ||
572 | * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are | ||
573 | * transferred on AMDTP packets at 96 kHz. Two successive samples of a | ||
574 | * channel are stored consecutively in the packet. This quirk is called | ||
575 | * as 'Dual Wire'. | ||
576 | * For this quirk, blocking mode is required and PCM buffer size should | ||
577 | * be aligned to SYT_INTERVAL. | ||
578 | */ | ||
579 | channels = params_channels(hw_params); | ||
580 | if (rate_index > 4) { | ||
581 | if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) { | ||
582 | err = -ENOSYS; | ||
583 | return err; | ||
584 | } | ||
585 | |||
586 | rate /= 2; | ||
587 | channels *= 2; | ||
588 | dice->stream.double_pcm_frames = true; | ||
589 | } else { | ||
590 | dice->stream.double_pcm_frames = false; | ||
591 | } | ||
592 | |||
593 | mode = rate_index_to_mode(rate_index); | ||
594 | amdtp_stream_set_parameters(&dice->stream, rate, channels, | ||
595 | dice->rx_midi_ports[mode]); | ||
596 | if (rate_index > 4) { | ||
597 | channels /= 2; | ||
598 | |||
599 | for (i = 0; i < channels; i++) { | ||
600 | dice->stream.pcm_positions[i] = i * 2; | ||
601 | dice->stream.pcm_positions[i + channels] = i * 2 + 1; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | amdtp_stream_set_pcm_format(&dice->stream, | ||
606 | params_format(hw_params)); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static int dice_hw_free(struct snd_pcm_substream *substream) | ||
612 | { | ||
613 | struct dice *dice = substream->private_data; | ||
614 | |||
615 | mutex_lock(&dice->mutex); | ||
616 | dice_stream_stop(dice); | ||
617 | mutex_unlock(&dice->mutex); | ||
618 | |||
619 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
620 | } | ||
621 | |||
622 | static int dice_prepare(struct snd_pcm_substream *substream) | ||
623 | { | ||
624 | struct dice *dice = substream->private_data; | ||
625 | int err; | ||
626 | |||
627 | mutex_lock(&dice->mutex); | ||
628 | |||
629 | if (amdtp_streaming_error(&dice->stream)) | ||
630 | dice_stream_stop_packets(dice); | ||
631 | |||
632 | err = dice_stream_start(dice); | ||
633 | if (err < 0) { | ||
634 | mutex_unlock(&dice->mutex); | ||
635 | return err; | ||
636 | } | ||
637 | |||
638 | mutex_unlock(&dice->mutex); | ||
639 | |||
640 | amdtp_stream_pcm_prepare(&dice->stream); | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | static int dice_trigger(struct snd_pcm_substream *substream, int cmd) | ||
646 | { | ||
647 | struct dice *dice = substream->private_data; | ||
648 | struct snd_pcm_substream *pcm; | ||
649 | |||
650 | switch (cmd) { | ||
651 | case SNDRV_PCM_TRIGGER_START: | ||
652 | pcm = substream; | ||
653 | break; | ||
654 | case SNDRV_PCM_TRIGGER_STOP: | ||
655 | pcm = NULL; | ||
656 | break; | ||
657 | default: | ||
658 | return -EINVAL; | ||
659 | } | ||
660 | amdtp_stream_pcm_trigger(&dice->stream, pcm); | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static snd_pcm_uframes_t dice_pointer(struct snd_pcm_substream *substream) | ||
666 | { | ||
667 | struct dice *dice = substream->private_data; | ||
668 | |||
669 | return amdtp_stream_pcm_pointer(&dice->stream); | ||
670 | } | ||
671 | |||
672 | static int dice_create_pcm(struct dice *dice) | ||
673 | { | ||
674 | static struct snd_pcm_ops ops = { | ||
675 | .open = dice_open, | ||
676 | .close = dice_close, | ||
677 | .ioctl = snd_pcm_lib_ioctl, | ||
678 | .hw_params = dice_hw_params, | ||
679 | .hw_free = dice_hw_free, | ||
680 | .prepare = dice_prepare, | ||
681 | .trigger = dice_trigger, | ||
682 | .pointer = dice_pointer, | ||
683 | .page = snd_pcm_lib_get_vmalloc_page, | ||
684 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
685 | }; | ||
686 | struct snd_pcm *pcm; | ||
687 | int err; | ||
688 | |||
689 | err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm); | ||
690 | if (err < 0) | ||
691 | return err; | ||
692 | pcm->private_data = dice; | ||
693 | strcpy(pcm->name, dice->card->shortname); | ||
694 | pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->ops = &ops; | ||
695 | |||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static long dice_hwdep_read(struct snd_hwdep *hwdep, char __user *buf, | ||
700 | long count, loff_t *offset) | ||
701 | { | ||
702 | struct dice *dice = hwdep->private_data; | ||
703 | DEFINE_WAIT(wait); | ||
704 | union snd_firewire_event event; | ||
705 | |||
706 | spin_lock_irq(&dice->lock); | ||
707 | |||
708 | while (!dice->dev_lock_changed && dice->notification_bits == 0) { | ||
709 | prepare_to_wait(&dice->hwdep_wait, &wait, TASK_INTERRUPTIBLE); | ||
710 | spin_unlock_irq(&dice->lock); | ||
711 | schedule(); | ||
712 | finish_wait(&dice->hwdep_wait, &wait); | ||
713 | if (signal_pending(current)) | ||
714 | return -ERESTARTSYS; | ||
715 | spin_lock_irq(&dice->lock); | ||
716 | } | ||
717 | |||
718 | memset(&event, 0, sizeof(event)); | ||
719 | if (dice->dev_lock_changed) { | ||
720 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | ||
721 | event.lock_status.status = dice->dev_lock_count > 0; | ||
722 | dice->dev_lock_changed = false; | ||
723 | |||
724 | count = min(count, (long)sizeof(event.lock_status)); | ||
725 | } else { | ||
726 | event.dice_notification.type = SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION; | ||
727 | event.dice_notification.notification = dice->notification_bits; | ||
728 | dice->notification_bits = 0; | ||
729 | |||
730 | count = min(count, (long)sizeof(event.dice_notification)); | ||
731 | } | ||
732 | |||
733 | spin_unlock_irq(&dice->lock); | ||
734 | |||
735 | if (copy_to_user(buf, &event, count)) | ||
736 | return -EFAULT; | ||
737 | |||
738 | return count; | ||
739 | } | ||
740 | |||
741 | static unsigned int dice_hwdep_poll(struct snd_hwdep *hwdep, struct file *file, | ||
742 | poll_table *wait) | ||
743 | { | ||
744 | struct dice *dice = hwdep->private_data; | ||
745 | unsigned int events; | ||
746 | |||
747 | poll_wait(file, &dice->hwdep_wait, wait); | ||
748 | |||
749 | spin_lock_irq(&dice->lock); | ||
750 | if (dice->dev_lock_changed || dice->notification_bits != 0) | ||
751 | events = POLLIN | POLLRDNORM; | ||
752 | else | ||
753 | events = 0; | ||
754 | spin_unlock_irq(&dice->lock); | ||
755 | |||
756 | return events; | ||
757 | } | ||
758 | |||
759 | static int dice_hwdep_get_info(struct dice *dice, void __user *arg) | ||
760 | { | ||
761 | struct fw_device *dev = fw_parent_device(dice->unit); | ||
762 | struct snd_firewire_get_info info; | ||
763 | |||
764 | memset(&info, 0, sizeof(info)); | ||
765 | info.type = SNDRV_FIREWIRE_TYPE_DICE; | ||
766 | info.card = dev->card->index; | ||
767 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | ||
768 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | ||
769 | strlcpy(info.device_name, dev_name(&dev->device), | ||
770 | sizeof(info.device_name)); | ||
771 | |||
772 | if (copy_to_user(arg, &info, sizeof(info))) | ||
773 | return -EFAULT; | ||
774 | |||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | static int dice_hwdep_lock(struct dice *dice) | ||
779 | { | ||
780 | int err; | ||
781 | |||
782 | spin_lock_irq(&dice->lock); | ||
783 | |||
784 | if (dice->dev_lock_count == 0) { | ||
785 | dice->dev_lock_count = -1; | ||
786 | err = 0; | ||
787 | } else { | ||
788 | err = -EBUSY; | ||
789 | } | ||
790 | |||
791 | spin_unlock_irq(&dice->lock); | ||
792 | |||
793 | return err; | ||
794 | } | ||
795 | |||
796 | static int dice_hwdep_unlock(struct dice *dice) | ||
797 | { | ||
798 | int err; | ||
799 | |||
800 | spin_lock_irq(&dice->lock); | ||
801 | |||
802 | if (dice->dev_lock_count == -1) { | ||
803 | dice->dev_lock_count = 0; | ||
804 | err = 0; | ||
805 | } else { | ||
806 | err = -EBADFD; | ||
807 | } | ||
808 | |||
809 | spin_unlock_irq(&dice->lock); | ||
810 | |||
811 | return err; | ||
812 | } | ||
813 | |||
814 | static int dice_hwdep_release(struct snd_hwdep *hwdep, struct file *file) | ||
815 | { | ||
816 | struct dice *dice = hwdep->private_data; | ||
817 | |||
818 | spin_lock_irq(&dice->lock); | ||
819 | if (dice->dev_lock_count == -1) | ||
820 | dice->dev_lock_count = 0; | ||
821 | spin_unlock_irq(&dice->lock); | ||
822 | |||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static int dice_hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
827 | unsigned int cmd, unsigned long arg) | ||
828 | { | ||
829 | struct dice *dice = hwdep->private_data; | ||
830 | |||
831 | switch (cmd) { | ||
832 | case SNDRV_FIREWIRE_IOCTL_GET_INFO: | ||
833 | return dice_hwdep_get_info(dice, (void __user *)arg); | ||
834 | case SNDRV_FIREWIRE_IOCTL_LOCK: | ||
835 | return dice_hwdep_lock(dice); | ||
836 | case SNDRV_FIREWIRE_IOCTL_UNLOCK: | ||
837 | return dice_hwdep_unlock(dice); | ||
838 | default: | ||
839 | return -ENOIOCTLCMD; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | #ifdef CONFIG_COMPAT | ||
844 | static int dice_hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
845 | unsigned int cmd, unsigned long arg) | ||
846 | { | ||
847 | return dice_hwdep_ioctl(hwdep, file, cmd, | ||
848 | (unsigned long)compat_ptr(arg)); | ||
849 | } | ||
850 | #else | ||
851 | #define dice_hwdep_compat_ioctl NULL | ||
852 | #endif | ||
853 | |||
854 | static int dice_create_hwdep(struct dice *dice) | ||
855 | { | ||
856 | static const struct snd_hwdep_ops ops = { | ||
857 | .read = dice_hwdep_read, | ||
858 | .release = dice_hwdep_release, | ||
859 | .poll = dice_hwdep_poll, | ||
860 | .ioctl = dice_hwdep_ioctl, | ||
861 | .ioctl_compat = dice_hwdep_compat_ioctl, | ||
862 | }; | ||
863 | struct snd_hwdep *hwdep; | ||
864 | int err; | ||
865 | |||
866 | err = snd_hwdep_new(dice->card, "DICE", 0, &hwdep); | ||
867 | if (err < 0) | ||
868 | return err; | ||
869 | strcpy(hwdep->name, "DICE"); | ||
870 | hwdep->iface = SNDRV_HWDEP_IFACE_FW_DICE; | ||
871 | hwdep->ops = ops; | ||
872 | hwdep->private_data = dice; | ||
873 | hwdep->exclusive = true; | ||
874 | |||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | static int dice_proc_read_mem(struct dice *dice, void *buffer, | ||
879 | unsigned int offset_q, unsigned int quadlets) | ||
880 | { | ||
881 | unsigned int i; | ||
882 | int err; | ||
883 | |||
884 | err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, | ||
885 | DICE_PRIVATE_SPACE + 4 * offset_q, | ||
886 | buffer, 4 * quadlets, 0); | ||
887 | if (err < 0) | ||
888 | return err; | ||
889 | |||
890 | for (i = 0; i < quadlets; ++i) | ||
891 | be32_to_cpus(&((u32 *)buffer)[i]); | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static const char *str_from_array(const char *const strs[], unsigned int count, | ||
897 | unsigned int i) | ||
898 | { | ||
899 | if (i < count) | ||
900 | return strs[i]; | ||
901 | else | ||
902 | return "(unknown)"; | ||
903 | } | ||
904 | |||
905 | static void dice_proc_fixup_string(char *s, unsigned int size) | ||
906 | { | ||
907 | unsigned int i; | ||
908 | |||
909 | for (i = 0; i < size; i += 4) | ||
910 | cpu_to_le32s((u32 *)(s + i)); | ||
911 | |||
912 | for (i = 0; i < size - 2; ++i) { | ||
913 | if (s[i] == '\0') | ||
914 | return; | ||
915 | if (s[i] == '\\' && s[i + 1] == '\\') { | ||
916 | s[i + 2] = '\0'; | ||
917 | return; | ||
918 | } | ||
919 | } | ||
920 | s[size - 1] = '\0'; | ||
921 | } | ||
922 | |||
923 | static void dice_proc_read(struct snd_info_entry *entry, | ||
924 | struct snd_info_buffer *buffer) | ||
925 | { | ||
926 | static const char *const section_names[5] = { | ||
927 | "global", "tx", "rx", "ext_sync", "unused2" | ||
928 | }; | ||
929 | static const char *const clock_sources[] = { | ||
930 | "aes1", "aes2", "aes3", "aes4", "aes", "adat", "tdif", | ||
931 | "wc", "arx1", "arx2", "arx3", "arx4", "internal" | ||
932 | }; | ||
933 | static const char *const rates[] = { | ||
934 | "32000", "44100", "48000", "88200", "96000", "176400", "192000", | ||
935 | "any low", "any mid", "any high", "none" | ||
936 | }; | ||
937 | struct dice *dice = entry->private_data; | ||
938 | u32 sections[ARRAY_SIZE(section_names) * 2]; | ||
939 | struct { | ||
940 | u32 number; | ||
941 | u32 size; | ||
942 | } tx_rx_header; | ||
943 | union { | ||
944 | struct { | ||
945 | u32 owner_hi, owner_lo; | ||
946 | u32 notification; | ||
947 | char nick_name[NICK_NAME_SIZE]; | ||
948 | u32 clock_select; | ||
949 | u32 enable; | ||
950 | u32 status; | ||
951 | u32 extended_status; | ||
952 | u32 sample_rate; | ||
953 | u32 version; | ||
954 | u32 clock_caps; | ||
955 | char clock_source_names[CLOCK_SOURCE_NAMES_SIZE]; | ||
956 | } global; | ||
957 | struct { | ||
958 | u32 iso; | ||
959 | u32 number_audio; | ||
960 | u32 number_midi; | ||
961 | u32 speed; | ||
962 | char names[TX_NAMES_SIZE]; | ||
963 | u32 ac3_caps; | ||
964 | u32 ac3_enable; | ||
965 | } tx; | ||
966 | struct { | ||
967 | u32 iso; | ||
968 | u32 seq_start; | ||
969 | u32 number_audio; | ||
970 | u32 number_midi; | ||
971 | char names[RX_NAMES_SIZE]; | ||
972 | u32 ac3_caps; | ||
973 | u32 ac3_enable; | ||
974 | } rx; | ||
975 | struct { | ||
976 | u32 clock_source; | ||
977 | u32 locked; | ||
978 | u32 rate; | ||
979 | u32 adat_user_data; | ||
980 | } ext_sync; | ||
981 | } buf; | ||
982 | unsigned int quadlets, stream, i; | ||
983 | |||
984 | if (dice_proc_read_mem(dice, sections, 0, ARRAY_SIZE(sections)) < 0) | ||
985 | return; | ||
986 | snd_iprintf(buffer, "sections:\n"); | ||
987 | for (i = 0; i < ARRAY_SIZE(section_names); ++i) | ||
988 | snd_iprintf(buffer, " %s: offset %u, size %u\n", | ||
989 | section_names[i], | ||
990 | sections[i * 2], sections[i * 2 + 1]); | ||
991 | |||
992 | quadlets = min_t(u32, sections[1], sizeof(buf.global) / 4); | ||
993 | if (dice_proc_read_mem(dice, &buf.global, sections[0], quadlets) < 0) | ||
994 | return; | ||
995 | snd_iprintf(buffer, "global:\n"); | ||
996 | snd_iprintf(buffer, " owner: %04x:%04x%08x\n", | ||
997 | buf.global.owner_hi >> 16, | ||
998 | buf.global.owner_hi & 0xffff, buf.global.owner_lo); | ||
999 | snd_iprintf(buffer, " notification: %08x\n", buf.global.notification); | ||
1000 | dice_proc_fixup_string(buf.global.nick_name, NICK_NAME_SIZE); | ||
1001 | snd_iprintf(buffer, " nick name: %s\n", buf.global.nick_name); | ||
1002 | snd_iprintf(buffer, " clock select: %s %s\n", | ||
1003 | str_from_array(clock_sources, ARRAY_SIZE(clock_sources), | ||
1004 | buf.global.clock_select & CLOCK_SOURCE_MASK), | ||
1005 | str_from_array(rates, ARRAY_SIZE(rates), | ||
1006 | (buf.global.clock_select & CLOCK_RATE_MASK) | ||
1007 | >> CLOCK_RATE_SHIFT)); | ||
1008 | snd_iprintf(buffer, " enable: %u\n", buf.global.enable); | ||
1009 | snd_iprintf(buffer, " status: %slocked %s\n", | ||
1010 | buf.global.status & STATUS_SOURCE_LOCKED ? "" : "un", | ||
1011 | str_from_array(rates, ARRAY_SIZE(rates), | ||
1012 | (buf.global.status & | ||
1013 | STATUS_NOMINAL_RATE_MASK) | ||
1014 | >> CLOCK_RATE_SHIFT)); | ||
1015 | snd_iprintf(buffer, " ext status: %08x\n", buf.global.extended_status); | ||
1016 | snd_iprintf(buffer, " sample rate: %u\n", buf.global.sample_rate); | ||
1017 | snd_iprintf(buffer, " version: %u.%u.%u.%u\n", | ||
1018 | (buf.global.version >> 24) & 0xff, | ||
1019 | (buf.global.version >> 16) & 0xff, | ||
1020 | (buf.global.version >> 8) & 0xff, | ||
1021 | (buf.global.version >> 0) & 0xff); | ||
1022 | if (quadlets >= 90) { | ||
1023 | snd_iprintf(buffer, " clock caps:"); | ||
1024 | for (i = 0; i <= 6; ++i) | ||
1025 | if (buf.global.clock_caps & (1 << i)) | ||
1026 | snd_iprintf(buffer, " %s", rates[i]); | ||
1027 | for (i = 0; i <= 12; ++i) | ||
1028 | if (buf.global.clock_caps & (1 << (16 + i))) | ||
1029 | snd_iprintf(buffer, " %s", clock_sources[i]); | ||
1030 | snd_iprintf(buffer, "\n"); | ||
1031 | dice_proc_fixup_string(buf.global.clock_source_names, | ||
1032 | CLOCK_SOURCE_NAMES_SIZE); | ||
1033 | snd_iprintf(buffer, " clock source names: %s\n", | ||
1034 | buf.global.clock_source_names); | ||
1035 | } | ||
1036 | |||
1037 | if (dice_proc_read_mem(dice, &tx_rx_header, sections[2], 2) < 0) | ||
1038 | return; | ||
1039 | quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx) / 4); | ||
1040 | for (stream = 0; stream < tx_rx_header.number; ++stream) { | ||
1041 | if (dice_proc_read_mem(dice, &buf.tx, sections[2] + 2 + | ||
1042 | stream * tx_rx_header.size, | ||
1043 | quadlets) < 0) | ||
1044 | break; | ||
1045 | snd_iprintf(buffer, "tx %u:\n", stream); | ||
1046 | snd_iprintf(buffer, " iso channel: %d\n", (int)buf.tx.iso); | ||
1047 | snd_iprintf(buffer, " audio channels: %u\n", | ||
1048 | buf.tx.number_audio); | ||
1049 | snd_iprintf(buffer, " midi ports: %u\n", buf.tx.number_midi); | ||
1050 | snd_iprintf(buffer, " speed: S%u\n", 100u << buf.tx.speed); | ||
1051 | if (quadlets >= 68) { | ||
1052 | dice_proc_fixup_string(buf.tx.names, TX_NAMES_SIZE); | ||
1053 | snd_iprintf(buffer, " names: %s\n", buf.tx.names); | ||
1054 | } | ||
1055 | if (quadlets >= 70) { | ||
1056 | snd_iprintf(buffer, " ac3 caps: %08x\n", | ||
1057 | buf.tx.ac3_caps); | ||
1058 | snd_iprintf(buffer, " ac3 enable: %08x\n", | ||
1059 | buf.tx.ac3_enable); | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1063 | if (dice_proc_read_mem(dice, &tx_rx_header, sections[4], 2) < 0) | ||
1064 | return; | ||
1065 | quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx) / 4); | ||
1066 | for (stream = 0; stream < tx_rx_header.number; ++stream) { | ||
1067 | if (dice_proc_read_mem(dice, &buf.rx, sections[4] + 2 + | ||
1068 | stream * tx_rx_header.size, | ||
1069 | quadlets) < 0) | ||
1070 | break; | ||
1071 | snd_iprintf(buffer, "rx %u:\n", stream); | ||
1072 | snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso); | ||
1073 | snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); | ||
1074 | snd_iprintf(buffer, " audio channels: %u\n", | ||
1075 | buf.rx.number_audio); | ||
1076 | snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi); | ||
1077 | if (quadlets >= 68) { | ||
1078 | dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE); | ||
1079 | snd_iprintf(buffer, " names: %s\n", buf.rx.names); | ||
1080 | } | ||
1081 | if (quadlets >= 70) { | ||
1082 | snd_iprintf(buffer, " ac3 caps: %08x\n", | ||
1083 | buf.rx.ac3_caps); | ||
1084 | snd_iprintf(buffer, " ac3 enable: %08x\n", | ||
1085 | buf.rx.ac3_enable); | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | quadlets = min_t(u32, sections[7], sizeof(buf.ext_sync) / 4); | ||
1090 | if (quadlets >= 4) { | ||
1091 | if (dice_proc_read_mem(dice, &buf.ext_sync, | ||
1092 | sections[6], 4) < 0) | ||
1093 | return; | ||
1094 | snd_iprintf(buffer, "ext status:\n"); | ||
1095 | snd_iprintf(buffer, " clock source: %s\n", | ||
1096 | str_from_array(clock_sources, | ||
1097 | ARRAY_SIZE(clock_sources), | ||
1098 | buf.ext_sync.clock_source)); | ||
1099 | snd_iprintf(buffer, " locked: %u\n", buf.ext_sync.locked); | ||
1100 | snd_iprintf(buffer, " rate: %s\n", | ||
1101 | str_from_array(rates, ARRAY_SIZE(rates), | ||
1102 | buf.ext_sync.rate)); | ||
1103 | snd_iprintf(buffer, " adat user data: "); | ||
1104 | if (buf.ext_sync.adat_user_data & ADAT_USER_DATA_NO_DATA) | ||
1105 | snd_iprintf(buffer, "-\n"); | ||
1106 | else | ||
1107 | snd_iprintf(buffer, "%x\n", | ||
1108 | buf.ext_sync.adat_user_data); | ||
1109 | } | ||
1110 | } | ||
1111 | |||
1112 | static void dice_create_proc(struct dice *dice) | ||
1113 | { | ||
1114 | struct snd_info_entry *entry; | ||
1115 | |||
1116 | if (!snd_card_proc_new(dice->card, "dice", &entry)) | ||
1117 | snd_info_set_text_ops(entry, dice, dice_proc_read); | ||
1118 | } | ||
1119 | |||
1120 | static void dice_card_free(struct snd_card *card) | ||
1121 | { | ||
1122 | struct dice *dice = card->private_data; | ||
1123 | |||
1124 | amdtp_stream_destroy(&dice->stream); | ||
1125 | fw_core_remove_address_handler(&dice->notification_handler); | ||
1126 | mutex_destroy(&dice->mutex); | ||
1127 | } | ||
1128 | |||
1129 | #define OUI_WEISS 0x001c6a | ||
1130 | |||
1131 | #define DICE_CATEGORY_ID 0x04 | ||
1132 | #define WEISS_CATEGORY_ID 0x00 | ||
1133 | |||
1134 | static int dice_interface_check(struct fw_unit *unit) | ||
1135 | { | ||
1136 | static const int min_values[10] = { | ||
1137 | 10, 0x64 / 4, | ||
1138 | 10, 0x18 / 4, | ||
1139 | 10, 0x18 / 4, | ||
1140 | 0, 0, | ||
1141 | 0, 0, | ||
1142 | }; | ||
1143 | struct fw_device *device = fw_parent_device(unit); | ||
1144 | struct fw_csr_iterator it; | ||
1145 | int key, value, vendor = -1, model = -1, err; | ||
1146 | unsigned int category, i; | ||
1147 | __be32 pointers[ARRAY_SIZE(min_values)]; | ||
1148 | __be32 tx_data[4]; | ||
1149 | __be32 version; | ||
1150 | |||
1151 | /* | ||
1152 | * Check that GUID and unit directory are constructed according to DICE | ||
1153 | * rules, i.e., that the specifier ID is the GUID's OUI, and that the | ||
1154 | * GUID chip ID consists of the 8-bit category ID, the 10-bit product | ||
1155 | * ID, and a 22-bit serial number. | ||
1156 | */ | ||
1157 | fw_csr_iterator_init(&it, unit->directory); | ||
1158 | while (fw_csr_iterator_next(&it, &key, &value)) { | ||
1159 | switch (key) { | ||
1160 | case CSR_SPECIFIER_ID: | ||
1161 | vendor = value; | ||
1162 | break; | ||
1163 | case CSR_MODEL: | ||
1164 | model = value; | ||
1165 | break; | ||
1166 | } | ||
1167 | } | ||
1168 | if (vendor == OUI_WEISS) | ||
1169 | category = WEISS_CATEGORY_ID; | ||
1170 | else | ||
1171 | category = DICE_CATEGORY_ID; | ||
1172 | if (device->config_rom[3] != ((vendor << 8) | category) || | ||
1173 | device->config_rom[4] >> 22 != model) | ||
1174 | return -ENODEV; | ||
1175 | |||
1176 | /* | ||
1177 | * Check that the sub address spaces exist and are located inside the | ||
1178 | * private address space. The minimum values are chosen so that all | ||
1179 | * minimally required registers are included. | ||
1180 | */ | ||
1181 | err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST, | ||
1182 | DICE_PRIVATE_SPACE, | ||
1183 | pointers, sizeof(pointers), 0); | ||
1184 | if (err < 0) | ||
1185 | return -ENODEV; | ||
1186 | for (i = 0; i < ARRAY_SIZE(pointers); ++i) { | ||
1187 | value = be32_to_cpu(pointers[i]); | ||
1188 | if (value < min_values[i] || value >= 0x40000) | ||
1189 | return -ENODEV; | ||
1190 | } | ||
1191 | |||
1192 | /* We support playback only. Let capture devices be handled by FFADO. */ | ||
1193 | err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST, | ||
1194 | DICE_PRIVATE_SPACE + | ||
1195 | be32_to_cpu(pointers[2]) * 4, | ||
1196 | tx_data, sizeof(tx_data), 0); | ||
1197 | if (err < 0 || (tx_data[0] && tx_data[3])) | ||
1198 | return -ENODEV; | ||
1199 | |||
1200 | /* | ||
1201 | * Check that the implemented DICE driver specification major version | ||
1202 | * number matches. | ||
1203 | */ | ||
1204 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | ||
1205 | DICE_PRIVATE_SPACE + | ||
1206 | be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION, | ||
1207 | &version, 4, 0); | ||
1208 | if (err < 0) | ||
1209 | return -ENODEV; | ||
1210 | if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) { | ||
1211 | dev_err(&unit->device, | ||
1212 | "unknown DICE version: 0x%08x\n", be32_to_cpu(version)); | ||
1213 | return -ENODEV; | ||
1214 | } | ||
1215 | |||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | static int highest_supported_mode_rate(struct dice *dice, unsigned int mode) | ||
1220 | { | ||
1221 | int i; | ||
1222 | |||
1223 | for (i = ARRAY_SIZE(dice_rates) - 1; i >= 0; --i) | ||
1224 | if ((dice->clock_caps & (1 << i)) && | ||
1225 | rate_index_to_mode(i) == mode) | ||
1226 | return i; | ||
1227 | |||
1228 | return -1; | ||
1229 | } | ||
1230 | |||
1231 | static int dice_read_mode_params(struct dice *dice, unsigned int mode) | ||
1232 | { | ||
1233 | __be32 values[2]; | ||
1234 | int rate_index, err; | ||
1235 | |||
1236 | rate_index = highest_supported_mode_rate(dice, mode); | ||
1237 | if (rate_index < 0) { | ||
1238 | dice->rx_channels[mode] = 0; | ||
1239 | dice->rx_midi_ports[mode] = 0; | ||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); | ||
1244 | if (err < 0) | ||
1245 | return err; | ||
1246 | |||
1247 | err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, | ||
1248 | rx_address(dice, RX_NUMBER_AUDIO), | ||
1249 | values, 2 * 4, 0); | ||
1250 | if (err < 0) | ||
1251 | return err; | ||
1252 | |||
1253 | dice->rx_channels[mode] = be32_to_cpu(values[0]); | ||
1254 | dice->rx_midi_ports[mode] = be32_to_cpu(values[1]); | ||
1255 | |||
1256 | return 0; | ||
1257 | } | ||
1258 | |||
1259 | static int dice_read_params(struct dice *dice) | ||
1260 | { | ||
1261 | __be32 pointers[6]; | ||
1262 | __be32 value; | ||
1263 | int mode, err; | ||
1264 | |||
1265 | err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, | ||
1266 | DICE_PRIVATE_SPACE, | ||
1267 | pointers, sizeof(pointers), 0); | ||
1268 | if (err < 0) | ||
1269 | return err; | ||
1270 | |||
1271 | dice->global_offset = be32_to_cpu(pointers[0]) * 4; | ||
1272 | dice->rx_offset = be32_to_cpu(pointers[4]) * 4; | ||
1273 | |||
1274 | /* some very old firmwares don't tell about their clock support */ | ||
1275 | if (be32_to_cpu(pointers[1]) * 4 >= GLOBAL_CLOCK_CAPABILITIES + 4) { | ||
1276 | err = snd_fw_transaction( | ||
1277 | dice->unit, TCODE_READ_QUADLET_REQUEST, | ||
1278 | global_address(dice, GLOBAL_CLOCK_CAPABILITIES), | ||
1279 | &value, 4, 0); | ||
1280 | if (err < 0) | ||
1281 | return err; | ||
1282 | dice->clock_caps = be32_to_cpu(value); | ||
1283 | } else { | ||
1284 | /* this should be supported by any device */ | ||
1285 | dice->clock_caps = CLOCK_CAP_RATE_44100 | | ||
1286 | CLOCK_CAP_RATE_48000 | | ||
1287 | CLOCK_CAP_SOURCE_ARX1 | | ||
1288 | CLOCK_CAP_SOURCE_INTERNAL; | ||
1289 | } | ||
1290 | |||
1291 | for (mode = 2; mode >= 0; --mode) { | ||
1292 | err = dice_read_mode_params(dice, mode); | ||
1293 | if (err < 0) | ||
1294 | return err; | ||
1295 | } | ||
1296 | |||
1297 | return 0; | ||
1298 | } | ||
1299 | |||
1300 | static void dice_card_strings(struct dice *dice) | ||
1301 | { | ||
1302 | struct snd_card *card = dice->card; | ||
1303 | struct fw_device *dev = fw_parent_device(dice->unit); | ||
1304 | char vendor[32], model[32]; | ||
1305 | unsigned int i; | ||
1306 | int err; | ||
1307 | |||
1308 | strcpy(card->driver, "DICE"); | ||
1309 | |||
1310 | strcpy(card->shortname, "DICE"); | ||
1311 | BUILD_BUG_ON(NICK_NAME_SIZE < sizeof(card->shortname)); | ||
1312 | err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, | ||
1313 | global_address(dice, GLOBAL_NICK_NAME), | ||
1314 | card->shortname, sizeof(card->shortname), 0); | ||
1315 | if (err >= 0) { | ||
1316 | /* DICE strings are returned in "always-wrong" endianness */ | ||
1317 | BUILD_BUG_ON(sizeof(card->shortname) % 4 != 0); | ||
1318 | for (i = 0; i < sizeof(card->shortname); i += 4) | ||
1319 | swab32s((u32 *)&card->shortname[i]); | ||
1320 | card->shortname[sizeof(card->shortname) - 1] = '\0'; | ||
1321 | } | ||
1322 | |||
1323 | strcpy(vendor, "?"); | ||
1324 | fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor)); | ||
1325 | strcpy(model, "?"); | ||
1326 | fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model)); | ||
1327 | snprintf(card->longname, sizeof(card->longname), | ||
1328 | "%s %s (serial %u) at %s, S%d", | ||
1329 | vendor, model, dev->config_rom[4] & 0x3fffff, | ||
1330 | dev_name(&dice->unit->device), 100 << dev->max_speed); | ||
1331 | |||
1332 | strcpy(card->mixername, "DICE"); | ||
1333 | } | ||
1334 | |||
1335 | static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | ||
1336 | { | ||
1337 | struct snd_card *card; | ||
1338 | struct dice *dice; | ||
1339 | __be32 clock_sel; | ||
1340 | int err; | ||
1341 | |||
1342 | err = dice_interface_check(unit); | ||
1343 | if (err < 0) | ||
1344 | return err; | ||
1345 | |||
1346 | err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, | ||
1347 | sizeof(*dice), &card); | ||
1348 | if (err < 0) | ||
1349 | return err; | ||
1350 | |||
1351 | dice = card->private_data; | ||
1352 | dice->card = card; | ||
1353 | spin_lock_init(&dice->lock); | ||
1354 | mutex_init(&dice->mutex); | ||
1355 | dice->unit = unit; | ||
1356 | init_completion(&dice->clock_accepted); | ||
1357 | init_waitqueue_head(&dice->hwdep_wait); | ||
1358 | |||
1359 | dice->notification_handler.length = 4; | ||
1360 | dice->notification_handler.address_callback = dice_notification; | ||
1361 | dice->notification_handler.callback_data = dice; | ||
1362 | err = fw_core_add_address_handler(&dice->notification_handler, | ||
1363 | &fw_high_memory_region); | ||
1364 | if (err < 0) | ||
1365 | goto err_mutex; | ||
1366 | |||
1367 | err = dice_owner_set(dice); | ||
1368 | if (err < 0) | ||
1369 | goto err_notification_handler; | ||
1370 | |||
1371 | err = dice_read_params(dice); | ||
1372 | if (err < 0) | ||
1373 | goto err_owner; | ||
1374 | |||
1375 | err = fw_iso_resources_init(&dice->resources, unit); | ||
1376 | if (err < 0) | ||
1377 | goto err_owner; | ||
1378 | dice->resources.channels_mask = 0x00000000ffffffffuLL; | ||
1379 | |||
1380 | err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM, | ||
1381 | CIP_BLOCKING); | ||
1382 | if (err < 0) | ||
1383 | goto err_resources; | ||
1384 | |||
1385 | card->private_free = dice_card_free; | ||
1386 | |||
1387 | dice_card_strings(dice); | ||
1388 | |||
1389 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | ||
1390 | global_address(dice, GLOBAL_CLOCK_SELECT), | ||
1391 | &clock_sel, 4, 0); | ||
1392 | if (err < 0) | ||
1393 | goto error; | ||
1394 | clock_sel &= cpu_to_be32(~CLOCK_SOURCE_MASK); | ||
1395 | clock_sel |= cpu_to_be32(CLOCK_SOURCE_ARX1); | ||
1396 | err = snd_fw_transaction(unit, TCODE_WRITE_QUADLET_REQUEST, | ||
1397 | global_address(dice, GLOBAL_CLOCK_SELECT), | ||
1398 | &clock_sel, 4, 0); | ||
1399 | if (err < 0) | ||
1400 | goto error; | ||
1401 | |||
1402 | err = dice_create_pcm(dice); | ||
1403 | if (err < 0) | ||
1404 | goto error; | ||
1405 | |||
1406 | err = dice_create_hwdep(dice); | ||
1407 | if (err < 0) | ||
1408 | goto error; | ||
1409 | |||
1410 | dice_create_proc(dice); | ||
1411 | |||
1412 | err = snd_card_register(card); | ||
1413 | if (err < 0) | ||
1414 | goto error; | ||
1415 | |||
1416 | dev_set_drvdata(&unit->device, dice); | ||
1417 | |||
1418 | return 0; | ||
1419 | |||
1420 | err_resources: | ||
1421 | fw_iso_resources_destroy(&dice->resources); | ||
1422 | err_owner: | ||
1423 | dice_owner_clear(dice); | ||
1424 | err_notification_handler: | ||
1425 | fw_core_remove_address_handler(&dice->notification_handler); | ||
1426 | err_mutex: | ||
1427 | mutex_destroy(&dice->mutex); | ||
1428 | error: | ||
1429 | snd_card_free(card); | ||
1430 | return err; | ||
1431 | } | ||
1432 | |||
1433 | static void dice_remove(struct fw_unit *unit) | ||
1434 | { | ||
1435 | struct dice *dice = dev_get_drvdata(&unit->device); | ||
1436 | |||
1437 | amdtp_stream_pcm_abort(&dice->stream); | ||
1438 | |||
1439 | snd_card_disconnect(dice->card); | ||
1440 | |||
1441 | mutex_lock(&dice->mutex); | ||
1442 | |||
1443 | dice_stream_stop(dice); | ||
1444 | dice_owner_clear(dice); | ||
1445 | |||
1446 | mutex_unlock(&dice->mutex); | ||
1447 | |||
1448 | snd_card_free_when_closed(dice->card); | ||
1449 | } | ||
1450 | |||
1451 | static void dice_bus_reset(struct fw_unit *unit) | ||
1452 | { | ||
1453 | struct dice *dice = dev_get_drvdata(&unit->device); | ||
1454 | |||
1455 | /* | ||
1456 | * On a bus reset, the DICE firmware disables streaming and then goes | ||
1457 | * off contemplating its own navel for hundreds of milliseconds before | ||
1458 | * it can react to any of our attempts to reenable streaming. This | ||
1459 | * means that we lose synchronization anyway, so we force our streams | ||
1460 | * to stop so that the application can restart them in an orderly | ||
1461 | * manner. | ||
1462 | */ | ||
1463 | amdtp_stream_pcm_abort(&dice->stream); | ||
1464 | |||
1465 | mutex_lock(&dice->mutex); | ||
1466 | |||
1467 | dice->global_enabled = false; | ||
1468 | dice_stream_stop_packets(dice); | ||
1469 | |||
1470 | dice_owner_update(dice); | ||
1471 | |||
1472 | fw_iso_resources_update(&dice->resources); | ||
1473 | |||
1474 | mutex_unlock(&dice->mutex); | ||
1475 | } | ||
1476 | |||
1477 | #define DICE_INTERFACE 0x000001 | ||
1478 | |||
1479 | static const struct ieee1394_device_id dice_id_table[] = { | ||
1480 | { | ||
1481 | .match_flags = IEEE1394_MATCH_VERSION, | ||
1482 | .version = DICE_INTERFACE, | ||
1483 | }, | ||
1484 | { } | ||
1485 | }; | ||
1486 | MODULE_DEVICE_TABLE(ieee1394, dice_id_table); | ||
1487 | |||
1488 | static struct fw_driver dice_driver = { | ||
1489 | .driver = { | ||
1490 | .owner = THIS_MODULE, | ||
1491 | .name = KBUILD_MODNAME, | ||
1492 | .bus = &fw_bus_type, | ||
1493 | }, | ||
1494 | .probe = dice_probe, | ||
1495 | .update = dice_bus_reset, | ||
1496 | .remove = dice_remove, | ||
1497 | .id_table = dice_id_table, | ||
1498 | }; | ||
1499 | |||
1500 | static int __init alsa_dice_init(void) | ||
1501 | { | ||
1502 | return driver_register(&dice_driver.driver); | ||
1503 | } | ||
1504 | |||
1505 | static void __exit alsa_dice_exit(void) | ||
1506 | { | ||
1507 | driver_unregister(&dice_driver.driver); | ||
1508 | } | ||
1509 | |||
1510 | module_init(alsa_dice_init); | ||
1511 | module_exit(alsa_dice_exit); | ||
diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile new file mode 100644 index 000000000000..9a48289eb9cb --- /dev/null +++ b/sound/firewire/dice/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-pcm.o \ | ||
2 | dice-hwdep.o dice.o | ||
3 | obj-m += snd-dice.o | ||
diff --git a/sound/firewire/dice/dice-hwdep.c b/sound/firewire/dice/dice-hwdep.c new file mode 100644 index 000000000000..a4dc02a86f12 --- /dev/null +++ b/sound/firewire/dice/dice-hwdep.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | * dice_hwdep.c - a part of driver for DICE based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp> | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #include "dice.h" | ||
11 | |||
12 | static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, | ||
13 | long count, loff_t *offset) | ||
14 | { | ||
15 | struct snd_dice *dice = hwdep->private_data; | ||
16 | DEFINE_WAIT(wait); | ||
17 | union snd_firewire_event event; | ||
18 | |||
19 | spin_lock_irq(&dice->lock); | ||
20 | |||
21 | while (!dice->dev_lock_changed && dice->notification_bits == 0) { | ||
22 | prepare_to_wait(&dice->hwdep_wait, &wait, TASK_INTERRUPTIBLE); | ||
23 | spin_unlock_irq(&dice->lock); | ||
24 | schedule(); | ||
25 | finish_wait(&dice->hwdep_wait, &wait); | ||
26 | if (signal_pending(current)) | ||
27 | return -ERESTARTSYS; | ||
28 | spin_lock_irq(&dice->lock); | ||
29 | } | ||
30 | |||
31 | memset(&event, 0, sizeof(event)); | ||
32 | if (dice->dev_lock_changed) { | ||
33 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | ||
34 | event.lock_status.status = dice->dev_lock_count > 0; | ||
35 | dice->dev_lock_changed = false; | ||
36 | |||
37 | count = min_t(long, count, sizeof(event.lock_status)); | ||
38 | } else { | ||
39 | event.dice_notification.type = | ||
40 | SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION; | ||
41 | event.dice_notification.notification = dice->notification_bits; | ||
42 | dice->notification_bits = 0; | ||
43 | |||
44 | count = min_t(long, count, sizeof(event.dice_notification)); | ||
45 | } | ||
46 | |||
47 | spin_unlock_irq(&dice->lock); | ||
48 | |||
49 | if (copy_to_user(buf, &event, count)) | ||
50 | return -EFAULT; | ||
51 | |||
52 | return count; | ||
53 | } | ||
54 | |||
55 | static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file, | ||
56 | poll_table *wait) | ||
57 | { | ||
58 | struct snd_dice *dice = hwdep->private_data; | ||
59 | unsigned int events; | ||
60 | |||
61 | poll_wait(file, &dice->hwdep_wait, wait); | ||
62 | |||
63 | spin_lock_irq(&dice->lock); | ||
64 | if (dice->dev_lock_changed || dice->notification_bits != 0) | ||
65 | events = POLLIN | POLLRDNORM; | ||
66 | else | ||
67 | events = 0; | ||
68 | spin_unlock_irq(&dice->lock); | ||
69 | |||
70 | return events; | ||
71 | } | ||
72 | |||
73 | static int hwdep_get_info(struct snd_dice *dice, void __user *arg) | ||
74 | { | ||
75 | struct fw_device *dev = fw_parent_device(dice->unit); | ||
76 | struct snd_firewire_get_info info; | ||
77 | |||
78 | memset(&info, 0, sizeof(info)); | ||
79 | info.type = SNDRV_FIREWIRE_TYPE_DICE; | ||
80 | info.card = dev->card->index; | ||
81 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | ||
82 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | ||
83 | strlcpy(info.device_name, dev_name(&dev->device), | ||
84 | sizeof(info.device_name)); | ||
85 | |||
86 | if (copy_to_user(arg, &info, sizeof(info))) | ||
87 | return -EFAULT; | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int hwdep_lock(struct snd_dice *dice) | ||
93 | { | ||
94 | int err; | ||
95 | |||
96 | spin_lock_irq(&dice->lock); | ||
97 | |||
98 | if (dice->dev_lock_count == 0) { | ||
99 | dice->dev_lock_count = -1; | ||
100 | err = 0; | ||
101 | } else { | ||
102 | err = -EBUSY; | ||
103 | } | ||
104 | |||
105 | spin_unlock_irq(&dice->lock); | ||
106 | |||
107 | return err; | ||
108 | } | ||
109 | |||
110 | static int hwdep_unlock(struct snd_dice *dice) | ||
111 | { | ||
112 | int err; | ||
113 | |||
114 | spin_lock_irq(&dice->lock); | ||
115 | |||
116 | if (dice->dev_lock_count == -1) { | ||
117 | dice->dev_lock_count = 0; | ||
118 | err = 0; | ||
119 | } else { | ||
120 | err = -EBADFD; | ||
121 | } | ||
122 | |||
123 | spin_unlock_irq(&dice->lock); | ||
124 | |||
125 | return err; | ||
126 | } | ||
127 | |||
128 | static int hwdep_release(struct snd_hwdep *hwdep, struct file *file) | ||
129 | { | ||
130 | struct snd_dice *dice = hwdep->private_data; | ||
131 | |||
132 | spin_lock_irq(&dice->lock); | ||
133 | if (dice->dev_lock_count == -1) | ||
134 | dice->dev_lock_count = 0; | ||
135 | spin_unlock_irq(&dice->lock); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
141 | unsigned int cmd, unsigned long arg) | ||
142 | { | ||
143 | struct snd_dice *dice = hwdep->private_data; | ||
144 | |||
145 | switch (cmd) { | ||
146 | case SNDRV_FIREWIRE_IOCTL_GET_INFO: | ||
147 | return hwdep_get_info(dice, (void __user *)arg); | ||
148 | case SNDRV_FIREWIRE_IOCTL_LOCK: | ||
149 | return hwdep_lock(dice); | ||
150 | case SNDRV_FIREWIRE_IOCTL_UNLOCK: | ||
151 | return hwdep_unlock(dice); | ||
152 | default: | ||
153 | return -ENOIOCTLCMD; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | #ifdef CONFIG_COMPAT | ||
158 | static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
159 | unsigned int cmd, unsigned long arg) | ||
160 | { | ||
161 | return hwdep_ioctl(hwdep, file, cmd, | ||
162 | (unsigned long)compat_ptr(arg)); | ||
163 | } | ||
164 | #else | ||
165 | #define hwdep_compat_ioctl NULL | ||
166 | #endif | ||
167 | |||
168 | int snd_dice_create_hwdep(struct snd_dice *dice) | ||
169 | { | ||
170 | static const struct snd_hwdep_ops ops = { | ||
171 | .read = hwdep_read, | ||
172 | .release = hwdep_release, | ||
173 | .poll = hwdep_poll, | ||
174 | .ioctl = hwdep_ioctl, | ||
175 | .ioctl_compat = hwdep_compat_ioctl, | ||
176 | }; | ||
177 | struct snd_hwdep *hwdep; | ||
178 | int err; | ||
179 | |||
180 | err = snd_hwdep_new(dice->card, "DICE", 0, &hwdep); | ||
181 | if (err < 0) | ||
182 | return err; | ||
183 | strcpy(hwdep->name, "DICE"); | ||
184 | hwdep->iface = SNDRV_HWDEP_IFACE_FW_DICE; | ||
185 | hwdep->ops = ops; | ||
186 | hwdep->private_data = dice; | ||
187 | hwdep->exclusive = true; | ||
188 | |||
189 | return 0; | ||
190 | } | ||
diff --git a/sound/firewire/dice-interface.h b/sound/firewire/dice/dice-interface.h index 27b044f84c81..27b044f84c81 100644 --- a/sound/firewire/dice-interface.h +++ b/sound/firewire/dice/dice-interface.h | |||
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c new file mode 100644 index 000000000000..2e531bd30e28 --- /dev/null +++ b/sound/firewire/dice/dice-pcm.c | |||
@@ -0,0 +1,317 @@ | |||
1 | /* | ||
2 | * dice_pcm.c - a part of driver for DICE based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp> | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #include "dice.h" | ||
11 | |||
12 | static int dice_rate_constraint(struct snd_pcm_hw_params *params, | ||
13 | struct snd_pcm_hw_rule *rule) | ||
14 | { | ||
15 | struct snd_dice *dice = rule->private; | ||
16 | |||
17 | const struct snd_interval *c = | ||
18 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
19 | struct snd_interval *r = | ||
20 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
21 | struct snd_interval rates = { | ||
22 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
23 | }; | ||
24 | unsigned int i, rate, mode, *pcm_channels = dice->rx_channels; | ||
25 | |||
26 | for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { | ||
27 | rate = snd_dice_rates[i]; | ||
28 | if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) | ||
29 | continue; | ||
30 | |||
31 | if (!snd_interval_test(c, pcm_channels[mode])) | ||
32 | continue; | ||
33 | |||
34 | rates.min = min(rates.min, rate); | ||
35 | rates.max = max(rates.max, rate); | ||
36 | } | ||
37 | |||
38 | return snd_interval_refine(r, &rates); | ||
39 | } | ||
40 | |||
41 | static int dice_channels_constraint(struct snd_pcm_hw_params *params, | ||
42 | struct snd_pcm_hw_rule *rule) | ||
43 | { | ||
44 | struct snd_dice *dice = rule->private; | ||
45 | |||
46 | const struct snd_interval *r = | ||
47 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); | ||
48 | struct snd_interval *c = | ||
49 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
50 | struct snd_interval channels = { | ||
51 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
52 | }; | ||
53 | unsigned int i, rate, mode, *pcm_channels = dice->rx_channels; | ||
54 | |||
55 | for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { | ||
56 | rate = snd_dice_rates[i]; | ||
57 | if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) | ||
58 | continue; | ||
59 | |||
60 | if (!snd_interval_test(r, rate)) | ||
61 | continue; | ||
62 | |||
63 | channels.min = min(channels.min, pcm_channels[mode]); | ||
64 | channels.max = max(channels.max, pcm_channels[mode]); | ||
65 | } | ||
66 | |||
67 | return snd_interval_refine(c, &channels); | ||
68 | } | ||
69 | |||
70 | static void limit_channels_and_rates(struct snd_dice *dice, | ||
71 | struct snd_pcm_runtime *runtime, | ||
72 | unsigned int *pcm_channels) | ||
73 | { | ||
74 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
75 | unsigned int i, rate, mode; | ||
76 | |||
77 | hw->channels_min = UINT_MAX; | ||
78 | hw->channels_max = 0; | ||
79 | |||
80 | for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { | ||
81 | rate = snd_dice_rates[i]; | ||
82 | if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) | ||
83 | continue; | ||
84 | hw->rates |= snd_pcm_rate_to_rate_bit(rate); | ||
85 | |||
86 | if (pcm_channels[mode] == 0) | ||
87 | continue; | ||
88 | hw->channels_min = min(hw->channels_min, pcm_channels[mode]); | ||
89 | hw->channels_max = max(hw->channels_max, pcm_channels[mode]); | ||
90 | } | ||
91 | |||
92 | snd_pcm_limit_hw_rates(runtime); | ||
93 | } | ||
94 | |||
95 | static void limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
96 | { | ||
97 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
98 | hw->periods_max = UINT_MAX; | ||
99 | |||
100 | hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */ | ||
101 | |||
102 | /* Just to prevent from allocating much pages. */ | ||
103 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
104 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
105 | } | ||
106 | |||
107 | static int init_hw_info(struct snd_dice *dice, | ||
108 | struct snd_pcm_substream *substream) | ||
109 | { | ||
110 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
111 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
112 | int err; | ||
113 | |||
114 | hw->info = SNDRV_PCM_INFO_MMAP | | ||
115 | SNDRV_PCM_INFO_MMAP_VALID | | ||
116 | SNDRV_PCM_INFO_BATCH | | ||
117 | SNDRV_PCM_INFO_INTERLEAVED | | ||
118 | SNDRV_PCM_INFO_BLOCK_TRANSFER; | ||
119 | hw->formats = AMDTP_OUT_PCM_FORMAT_BITS; | ||
120 | |||
121 | limit_channels_and_rates(dice, runtime, dice->rx_channels); | ||
122 | limit_period_and_buffer(hw); | ||
123 | |||
124 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
125 | dice_rate_constraint, dice, | ||
126 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
127 | if (err < 0) | ||
128 | goto end; | ||
129 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
130 | dice_channels_constraint, dice, | ||
131 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
132 | if (err < 0) | ||
133 | goto end; | ||
134 | |||
135 | err = amdtp_stream_add_pcm_hw_constraints(&dice->rx_stream, runtime); | ||
136 | end: | ||
137 | return err; | ||
138 | } | ||
139 | |||
140 | static int pcm_open(struct snd_pcm_substream *substream) | ||
141 | { | ||
142 | struct snd_dice *dice = substream->private_data; | ||
143 | int err; | ||
144 | |||
145 | err = snd_dice_stream_lock_try(dice); | ||
146 | if (err < 0) | ||
147 | goto end; | ||
148 | |||
149 | err = init_hw_info(dice, substream); | ||
150 | if (err < 0) | ||
151 | goto err_locked; | ||
152 | end: | ||
153 | return err; | ||
154 | err_locked: | ||
155 | snd_dice_stream_lock_release(dice); | ||
156 | return err; | ||
157 | } | ||
158 | |||
159 | static int pcm_close(struct snd_pcm_substream *substream) | ||
160 | { | ||
161 | struct snd_dice *dice = substream->private_data; | ||
162 | |||
163 | snd_dice_stream_lock_release(dice); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int playback_hw_params(struct snd_pcm_substream *substream, | ||
169 | struct snd_pcm_hw_params *hw_params) | ||
170 | { | ||
171 | struct snd_dice *dice = substream->private_data; | ||
172 | unsigned int mode, rate, channels, i; | ||
173 | int err; | ||
174 | |||
175 | mutex_lock(&dice->mutex); | ||
176 | snd_dice_stream_stop(dice); | ||
177 | mutex_unlock(&dice->mutex); | ||
178 | |||
179 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
180 | params_buffer_bytes(hw_params)); | ||
181 | if (err < 0) | ||
182 | return err; | ||
183 | |||
184 | rate = params_rate(hw_params); | ||
185 | err = snd_dice_transaction_set_rate(dice, rate); | ||
186 | if (err < 0) | ||
187 | return err; | ||
188 | |||
189 | if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) | ||
190 | return err; | ||
191 | |||
192 | /* | ||
193 | * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in | ||
194 | * one data block of AMDTP packet. Thus sampling transfer frequency is | ||
195 | * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are | ||
196 | * transferred on AMDTP packets at 96 kHz. Two successive samples of a | ||
197 | * channel are stored consecutively in the packet. This quirk is called | ||
198 | * as 'Dual Wire'. | ||
199 | * For this quirk, blocking mode is required and PCM buffer size should | ||
200 | * be aligned to SYT_INTERVAL. | ||
201 | */ | ||
202 | channels = params_channels(hw_params); | ||
203 | if (mode > 1) { | ||
204 | if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) { | ||
205 | err = -ENOSYS; | ||
206 | return err; | ||
207 | } | ||
208 | |||
209 | rate /= 2; | ||
210 | channels *= 2; | ||
211 | dice->rx_stream.double_pcm_frames = true; | ||
212 | } else { | ||
213 | dice->rx_stream.double_pcm_frames = false; | ||
214 | } | ||
215 | |||
216 | amdtp_stream_set_parameters(&dice->rx_stream, rate, channels, | ||
217 | dice->rx_midi_ports[mode]); | ||
218 | if (mode > 1) { | ||
219 | channels /= 2; | ||
220 | |||
221 | for (i = 0; i < channels; i++) { | ||
222 | dice->rx_stream.pcm_positions[i] = i * 2; | ||
223 | dice->rx_stream.pcm_positions[i + channels] = i * 2 + 1; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | amdtp_stream_set_pcm_format(&dice->rx_stream, | ||
228 | params_format(hw_params)); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int playback_hw_free(struct snd_pcm_substream *substream) | ||
234 | { | ||
235 | struct snd_dice *dice = substream->private_data; | ||
236 | |||
237 | mutex_lock(&dice->mutex); | ||
238 | snd_dice_stream_stop(dice); | ||
239 | mutex_unlock(&dice->mutex); | ||
240 | |||
241 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
242 | } | ||
243 | |||
244 | static int playback_prepare(struct snd_pcm_substream *substream) | ||
245 | { | ||
246 | struct snd_dice *dice = substream->private_data; | ||
247 | int err; | ||
248 | |||
249 | mutex_lock(&dice->mutex); | ||
250 | |||
251 | if (amdtp_streaming_error(&dice->rx_stream)) | ||
252 | snd_dice_stream_stop_packets(dice); | ||
253 | |||
254 | err = snd_dice_stream_start(dice); | ||
255 | if (err < 0) { | ||
256 | mutex_unlock(&dice->mutex); | ||
257 | return err; | ||
258 | } | ||
259 | |||
260 | mutex_unlock(&dice->mutex); | ||
261 | |||
262 | amdtp_stream_pcm_prepare(&dice->rx_stream); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int playback_trigger(struct snd_pcm_substream *substream, int cmd) | ||
268 | { | ||
269 | struct snd_dice *dice = substream->private_data; | ||
270 | |||
271 | switch (cmd) { | ||
272 | case SNDRV_PCM_TRIGGER_START: | ||
273 | amdtp_stream_pcm_trigger(&dice->rx_stream, substream); | ||
274 | break; | ||
275 | case SNDRV_PCM_TRIGGER_STOP: | ||
276 | amdtp_stream_pcm_trigger(&dice->rx_stream, NULL); | ||
277 | break; | ||
278 | default: | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream) | ||
286 | { | ||
287 | struct snd_dice *dice = substream->private_data; | ||
288 | |||
289 | return amdtp_stream_pcm_pointer(&dice->rx_stream); | ||
290 | } | ||
291 | |||
292 | int snd_dice_create_pcm(struct snd_dice *dice) | ||
293 | { | ||
294 | static struct snd_pcm_ops playback_ops = { | ||
295 | .open = pcm_open, | ||
296 | .close = pcm_close, | ||
297 | .ioctl = snd_pcm_lib_ioctl, | ||
298 | .hw_params = playback_hw_params, | ||
299 | .hw_free = playback_hw_free, | ||
300 | .prepare = playback_prepare, | ||
301 | .trigger = playback_trigger, | ||
302 | .pointer = playback_pointer, | ||
303 | .page = snd_pcm_lib_get_vmalloc_page, | ||
304 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
305 | }; | ||
306 | struct snd_pcm *pcm; | ||
307 | int err; | ||
308 | |||
309 | err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm); | ||
310 | if (err < 0) | ||
311 | return err; | ||
312 | pcm->private_data = dice; | ||
313 | strcpy(pcm->name, dice->card->shortname); | ||
314 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
diff --git a/sound/firewire/dice/dice-proc.c b/sound/firewire/dice/dice-proc.c new file mode 100644 index 000000000000..f5c1d1bced59 --- /dev/null +++ b/sound/firewire/dice/dice-proc.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /* | ||
2 | * dice_proc.c - a part of driver for Dice based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch | ||
5 | * Copyright (c) 2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #include "dice.h" | ||
11 | |||
12 | static int dice_proc_read_mem(struct snd_dice *dice, void *buffer, | ||
13 | unsigned int offset_q, unsigned int quadlets) | ||
14 | { | ||
15 | unsigned int i; | ||
16 | int err; | ||
17 | |||
18 | err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, | ||
19 | DICE_PRIVATE_SPACE + 4 * offset_q, | ||
20 | buffer, 4 * quadlets, 0); | ||
21 | if (err < 0) | ||
22 | return err; | ||
23 | |||
24 | for (i = 0; i < quadlets; ++i) | ||
25 | be32_to_cpus(&((u32 *)buffer)[i]); | ||
26 | |||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static const char *str_from_array(const char *const strs[], unsigned int count, | ||
31 | unsigned int i) | ||
32 | { | ||
33 | if (i < count) | ||
34 | return strs[i]; | ||
35 | |||
36 | return "(unknown)"; | ||
37 | } | ||
38 | |||
39 | static void dice_proc_fixup_string(char *s, unsigned int size) | ||
40 | { | ||
41 | unsigned int i; | ||
42 | |||
43 | for (i = 0; i < size; i += 4) | ||
44 | cpu_to_le32s((u32 *)(s + i)); | ||
45 | |||
46 | for (i = 0; i < size - 2; ++i) { | ||
47 | if (s[i] == '\0') | ||
48 | return; | ||
49 | if (s[i] == '\\' && s[i + 1] == '\\') { | ||
50 | s[i + 2] = '\0'; | ||
51 | return; | ||
52 | } | ||
53 | } | ||
54 | s[size - 1] = '\0'; | ||
55 | } | ||
56 | |||
57 | static void dice_proc_read(struct snd_info_entry *entry, | ||
58 | struct snd_info_buffer *buffer) | ||
59 | { | ||
60 | static const char *const section_names[5] = { | ||
61 | "global", "tx", "rx", "ext_sync", "unused2" | ||
62 | }; | ||
63 | static const char *const clock_sources[] = { | ||
64 | "aes1", "aes2", "aes3", "aes4", "aes", "adat", "tdif", | ||
65 | "wc", "arx1", "arx2", "arx3", "arx4", "internal" | ||
66 | }; | ||
67 | static const char *const rates[] = { | ||
68 | "32000", "44100", "48000", "88200", "96000", "176400", "192000", | ||
69 | "any low", "any mid", "any high", "none" | ||
70 | }; | ||
71 | struct snd_dice *dice = entry->private_data; | ||
72 | u32 sections[ARRAY_SIZE(section_names) * 2]; | ||
73 | struct { | ||
74 | u32 number; | ||
75 | u32 size; | ||
76 | } tx_rx_header; | ||
77 | union { | ||
78 | struct { | ||
79 | u32 owner_hi, owner_lo; | ||
80 | u32 notification; | ||
81 | char nick_name[NICK_NAME_SIZE]; | ||
82 | u32 clock_select; | ||
83 | u32 enable; | ||
84 | u32 status; | ||
85 | u32 extended_status; | ||
86 | u32 sample_rate; | ||
87 | u32 version; | ||
88 | u32 clock_caps; | ||
89 | char clock_source_names[CLOCK_SOURCE_NAMES_SIZE]; | ||
90 | } global; | ||
91 | struct { | ||
92 | u32 iso; | ||
93 | u32 number_audio; | ||
94 | u32 number_midi; | ||
95 | u32 speed; | ||
96 | char names[TX_NAMES_SIZE]; | ||
97 | u32 ac3_caps; | ||
98 | u32 ac3_enable; | ||
99 | } tx; | ||
100 | struct { | ||
101 | u32 iso; | ||
102 | u32 seq_start; | ||
103 | u32 number_audio; | ||
104 | u32 number_midi; | ||
105 | char names[RX_NAMES_SIZE]; | ||
106 | u32 ac3_caps; | ||
107 | u32 ac3_enable; | ||
108 | } rx; | ||
109 | struct { | ||
110 | u32 clock_source; | ||
111 | u32 locked; | ||
112 | u32 rate; | ||
113 | u32 adat_user_data; | ||
114 | } ext_sync; | ||
115 | } buf; | ||
116 | unsigned int quadlets, stream, i; | ||
117 | |||
118 | if (dice_proc_read_mem(dice, sections, 0, ARRAY_SIZE(sections)) < 0) | ||
119 | return; | ||
120 | snd_iprintf(buffer, "sections:\n"); | ||
121 | for (i = 0; i < ARRAY_SIZE(section_names); ++i) | ||
122 | snd_iprintf(buffer, " %s: offset %u, size %u\n", | ||
123 | section_names[i], | ||
124 | sections[i * 2], sections[i * 2 + 1]); | ||
125 | |||
126 | quadlets = min_t(u32, sections[1], sizeof(buf.global) / 4); | ||
127 | if (dice_proc_read_mem(dice, &buf.global, sections[0], quadlets) < 0) | ||
128 | return; | ||
129 | snd_iprintf(buffer, "global:\n"); | ||
130 | snd_iprintf(buffer, " owner: %04x:%04x%08x\n", | ||
131 | buf.global.owner_hi >> 16, | ||
132 | buf.global.owner_hi & 0xffff, buf.global.owner_lo); | ||
133 | snd_iprintf(buffer, " notification: %08x\n", buf.global.notification); | ||
134 | dice_proc_fixup_string(buf.global.nick_name, NICK_NAME_SIZE); | ||
135 | snd_iprintf(buffer, " nick name: %s\n", buf.global.nick_name); | ||
136 | snd_iprintf(buffer, " clock select: %s %s\n", | ||
137 | str_from_array(clock_sources, ARRAY_SIZE(clock_sources), | ||
138 | buf.global.clock_select & CLOCK_SOURCE_MASK), | ||
139 | str_from_array(rates, ARRAY_SIZE(rates), | ||
140 | (buf.global.clock_select & CLOCK_RATE_MASK) | ||
141 | >> CLOCK_RATE_SHIFT)); | ||
142 | snd_iprintf(buffer, " enable: %u\n", buf.global.enable); | ||
143 | snd_iprintf(buffer, " status: %slocked %s\n", | ||
144 | buf.global.status & STATUS_SOURCE_LOCKED ? "" : "un", | ||
145 | str_from_array(rates, ARRAY_SIZE(rates), | ||
146 | (buf.global.status & | ||
147 | STATUS_NOMINAL_RATE_MASK) | ||
148 | >> CLOCK_RATE_SHIFT)); | ||
149 | snd_iprintf(buffer, " ext status: %08x\n", buf.global.extended_status); | ||
150 | snd_iprintf(buffer, " sample rate: %u\n", buf.global.sample_rate); | ||
151 | snd_iprintf(buffer, " version: %u.%u.%u.%u\n", | ||
152 | (buf.global.version >> 24) & 0xff, | ||
153 | (buf.global.version >> 16) & 0xff, | ||
154 | (buf.global.version >> 8) & 0xff, | ||
155 | (buf.global.version >> 0) & 0xff); | ||
156 | if (quadlets >= 90) { | ||
157 | snd_iprintf(buffer, " clock caps:"); | ||
158 | for (i = 0; i <= 6; ++i) | ||
159 | if (buf.global.clock_caps & (1 << i)) | ||
160 | snd_iprintf(buffer, " %s", rates[i]); | ||
161 | for (i = 0; i <= 12; ++i) | ||
162 | if (buf.global.clock_caps & (1 << (16 + i))) | ||
163 | snd_iprintf(buffer, " %s", clock_sources[i]); | ||
164 | snd_iprintf(buffer, "\n"); | ||
165 | dice_proc_fixup_string(buf.global.clock_source_names, | ||
166 | CLOCK_SOURCE_NAMES_SIZE); | ||
167 | snd_iprintf(buffer, " clock source names: %s\n", | ||
168 | buf.global.clock_source_names); | ||
169 | } | ||
170 | |||
171 | if (dice_proc_read_mem(dice, &tx_rx_header, sections[2], 2) < 0) | ||
172 | return; | ||
173 | quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx) / 4); | ||
174 | for (stream = 0; stream < tx_rx_header.number; ++stream) { | ||
175 | if (dice_proc_read_mem(dice, &buf.tx, sections[2] + 2 + | ||
176 | stream * tx_rx_header.size, | ||
177 | quadlets) < 0) | ||
178 | break; | ||
179 | snd_iprintf(buffer, "tx %u:\n", stream); | ||
180 | snd_iprintf(buffer, " iso channel: %d\n", (int)buf.tx.iso); | ||
181 | snd_iprintf(buffer, " audio channels: %u\n", | ||
182 | buf.tx.number_audio); | ||
183 | snd_iprintf(buffer, " midi ports: %u\n", buf.tx.number_midi); | ||
184 | snd_iprintf(buffer, " speed: S%u\n", 100u << buf.tx.speed); | ||
185 | if (quadlets >= 68) { | ||
186 | dice_proc_fixup_string(buf.tx.names, TX_NAMES_SIZE); | ||
187 | snd_iprintf(buffer, " names: %s\n", buf.tx.names); | ||
188 | } | ||
189 | if (quadlets >= 70) { | ||
190 | snd_iprintf(buffer, " ac3 caps: %08x\n", | ||
191 | buf.tx.ac3_caps); | ||
192 | snd_iprintf(buffer, " ac3 enable: %08x\n", | ||
193 | buf.tx.ac3_enable); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | if (dice_proc_read_mem(dice, &tx_rx_header, sections[4], 2) < 0) | ||
198 | return; | ||
199 | quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx) / 4); | ||
200 | for (stream = 0; stream < tx_rx_header.number; ++stream) { | ||
201 | if (dice_proc_read_mem(dice, &buf.rx, sections[4] + 2 + | ||
202 | stream * tx_rx_header.size, | ||
203 | quadlets) < 0) | ||
204 | break; | ||
205 | snd_iprintf(buffer, "rx %u:\n", stream); | ||
206 | snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso); | ||
207 | snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); | ||
208 | snd_iprintf(buffer, " audio channels: %u\n", | ||
209 | buf.rx.number_audio); | ||
210 | snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi); | ||
211 | if (quadlets >= 68) { | ||
212 | dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE); | ||
213 | snd_iprintf(buffer, " names: %s\n", buf.rx.names); | ||
214 | } | ||
215 | if (quadlets >= 70) { | ||
216 | snd_iprintf(buffer, " ac3 caps: %08x\n", | ||
217 | buf.rx.ac3_caps); | ||
218 | snd_iprintf(buffer, " ac3 enable: %08x\n", | ||
219 | buf.rx.ac3_enable); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | quadlets = min_t(u32, sections[7], sizeof(buf.ext_sync) / 4); | ||
224 | if (quadlets >= 4) { | ||
225 | if (dice_proc_read_mem(dice, &buf.ext_sync, | ||
226 | sections[6], 4) < 0) | ||
227 | return; | ||
228 | snd_iprintf(buffer, "ext status:\n"); | ||
229 | snd_iprintf(buffer, " clock source: %s\n", | ||
230 | str_from_array(clock_sources, | ||
231 | ARRAY_SIZE(clock_sources), | ||
232 | buf.ext_sync.clock_source)); | ||
233 | snd_iprintf(buffer, " locked: %u\n", buf.ext_sync.locked); | ||
234 | snd_iprintf(buffer, " rate: %s\n", | ||
235 | str_from_array(rates, ARRAY_SIZE(rates), | ||
236 | buf.ext_sync.rate)); | ||
237 | snd_iprintf(buffer, " adat user data: "); | ||
238 | if (buf.ext_sync.adat_user_data & ADAT_USER_DATA_NO_DATA) | ||
239 | snd_iprintf(buffer, "-\n"); | ||
240 | else | ||
241 | snd_iprintf(buffer, "%x\n", | ||
242 | buf.ext_sync.adat_user_data); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | void snd_dice_create_proc(struct snd_dice *dice) | ||
247 | { | ||
248 | struct snd_info_entry *entry; | ||
249 | |||
250 | if (!snd_card_proc_new(dice->card, "dice", &entry)) | ||
251 | snd_info_set_text_ops(entry, dice, dice_proc_read); | ||
252 | } | ||
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c new file mode 100644 index 000000000000..4c4c4fff6272 --- /dev/null +++ b/sound/firewire/dice/dice-stream.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * dice_stream.c - a part of driver for DICE based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp> | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #include "dice.h" | ||
11 | |||
12 | const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = { | ||
13 | /* mode 0 */ | ||
14 | [0] = 32000, | ||
15 | [1] = 44100, | ||
16 | [2] = 48000, | ||
17 | /* mode 1 */ | ||
18 | [3] = 88200, | ||
19 | [4] = 96000, | ||
20 | /* mode 2 */ | ||
21 | [5] = 176400, | ||
22 | [6] = 192000, | ||
23 | }; | ||
24 | |||
25 | int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate, | ||
26 | unsigned int *mode) | ||
27 | { | ||
28 | int i; | ||
29 | |||
30 | for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) { | ||
31 | if (!(dice->clock_caps & BIT(i))) | ||
32 | continue; | ||
33 | if (snd_dice_rates[i] != rate) | ||
34 | continue; | ||
35 | |||
36 | *mode = (i - 1) / 2; | ||
37 | return 0; | ||
38 | } | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | |||
42 | int snd_dice_stream_start_packets(struct snd_dice *dice) | ||
43 | { | ||
44 | int err; | ||
45 | |||
46 | if (amdtp_stream_running(&dice->rx_stream)) | ||
47 | return 0; | ||
48 | |||
49 | err = amdtp_stream_start(&dice->rx_stream, dice->rx_resources.channel, | ||
50 | fw_parent_device(dice->unit)->max_speed); | ||
51 | if (err < 0) | ||
52 | return err; | ||
53 | |||
54 | err = snd_dice_transaction_set_enable(dice); | ||
55 | if (err < 0) { | ||
56 | amdtp_stream_stop(&dice->rx_stream); | ||
57 | return err; | ||
58 | } | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | int snd_dice_stream_start(struct snd_dice *dice) | ||
64 | { | ||
65 | __be32 channel; | ||
66 | int err; | ||
67 | |||
68 | if (!dice->rx_resources.allocated) { | ||
69 | err = fw_iso_resources_allocate(&dice->rx_resources, | ||
70 | amdtp_stream_get_max_payload(&dice->rx_stream), | ||
71 | fw_parent_device(dice->unit)->max_speed); | ||
72 | if (err < 0) | ||
73 | goto error; | ||
74 | |||
75 | channel = cpu_to_be32(dice->rx_resources.channel); | ||
76 | err = snd_dice_transaction_write_tx(dice, RX_ISOCHRONOUS, | ||
77 | &channel, 4); | ||
78 | if (err < 0) | ||
79 | goto err_resources; | ||
80 | } | ||
81 | |||
82 | err = snd_dice_stream_start_packets(dice); | ||
83 | if (err < 0) | ||
84 | goto err_rx_channel; | ||
85 | |||
86 | return 0; | ||
87 | |||
88 | err_rx_channel: | ||
89 | channel = cpu_to_be32((u32)-1); | ||
90 | snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4); | ||
91 | err_resources: | ||
92 | fw_iso_resources_free(&dice->rx_resources); | ||
93 | error: | ||
94 | return err; | ||
95 | } | ||
96 | |||
97 | void snd_dice_stream_stop_packets(struct snd_dice *dice) | ||
98 | { | ||
99 | if (!amdtp_stream_running(&dice->rx_stream)) | ||
100 | return; | ||
101 | |||
102 | snd_dice_transaction_clear_enable(dice); | ||
103 | amdtp_stream_stop(&dice->rx_stream); | ||
104 | } | ||
105 | |||
106 | void snd_dice_stream_stop(struct snd_dice *dice) | ||
107 | { | ||
108 | __be32 channel; | ||
109 | |||
110 | snd_dice_stream_stop_packets(dice); | ||
111 | |||
112 | if (!dice->rx_resources.allocated) | ||
113 | return; | ||
114 | |||
115 | channel = cpu_to_be32((u32)-1); | ||
116 | snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4); | ||
117 | |||
118 | fw_iso_resources_free(&dice->rx_resources); | ||
119 | } | ||
120 | |||
121 | int snd_dice_stream_init(struct snd_dice *dice) | ||
122 | { | ||
123 | int err; | ||
124 | |||
125 | err = fw_iso_resources_init(&dice->rx_resources, dice->unit); | ||
126 | if (err < 0) | ||
127 | goto end; | ||
128 | dice->rx_resources.channels_mask = 0x00000000ffffffffuLL; | ||
129 | |||
130 | err = amdtp_stream_init(&dice->rx_stream, dice->unit, AMDTP_OUT_STREAM, | ||
131 | CIP_BLOCKING); | ||
132 | if (err < 0) | ||
133 | goto error; | ||
134 | |||
135 | err = snd_dice_transaction_set_clock_source(dice, CLOCK_SOURCE_ARX1); | ||
136 | if (err < 0) | ||
137 | goto error; | ||
138 | end: | ||
139 | return err; | ||
140 | error: | ||
141 | amdtp_stream_destroy(&dice->rx_stream); | ||
142 | fw_iso_resources_destroy(&dice->rx_resources); | ||
143 | return err; | ||
144 | } | ||
145 | |||
146 | void snd_dice_stream_destroy(struct snd_dice *dice) | ||
147 | { | ||
148 | amdtp_stream_pcm_abort(&dice->rx_stream); | ||
149 | snd_dice_stream_stop(dice); | ||
150 | amdtp_stream_destroy(&dice->rx_stream); | ||
151 | fw_iso_resources_destroy(&dice->rx_resources); | ||
152 | } | ||
153 | |||
154 | void snd_dice_stream_update(struct snd_dice *dice) | ||
155 | { | ||
156 | /* | ||
157 | * On a bus reset, the DICE firmware disables streaming and then goes | ||
158 | * off contemplating its own navel for hundreds of milliseconds before | ||
159 | * it can react to any of our attempts to reenable streaming. This | ||
160 | * means that we lose synchronization anyway, so we force our streams | ||
161 | * to stop so that the application can restart them in an orderly | ||
162 | * manner. | ||
163 | */ | ||
164 | dice->global_enabled = false; | ||
165 | |||
166 | amdtp_stream_pcm_abort(&dice->rx_stream); | ||
167 | snd_dice_stream_stop_packets(dice); | ||
168 | fw_iso_resources_update(&dice->rx_resources); | ||
169 | } | ||
170 | |||
171 | static void dice_lock_changed(struct snd_dice *dice) | ||
172 | { | ||
173 | dice->dev_lock_changed = true; | ||
174 | wake_up(&dice->hwdep_wait); | ||
175 | } | ||
176 | |||
177 | int snd_dice_stream_lock_try(struct snd_dice *dice) | ||
178 | { | ||
179 | int err; | ||
180 | |||
181 | spin_lock_irq(&dice->lock); | ||
182 | |||
183 | if (dice->dev_lock_count < 0) { | ||
184 | err = -EBUSY; | ||
185 | goto out; | ||
186 | } | ||
187 | |||
188 | if (dice->dev_lock_count++ == 0) | ||
189 | dice_lock_changed(dice); | ||
190 | err = 0; | ||
191 | out: | ||
192 | spin_unlock_irq(&dice->lock); | ||
193 | return err; | ||
194 | } | ||
195 | |||
196 | void snd_dice_stream_lock_release(struct snd_dice *dice) | ||
197 | { | ||
198 | spin_lock_irq(&dice->lock); | ||
199 | |||
200 | if (WARN_ON(dice->dev_lock_count <= 0)) | ||
201 | goto out; | ||
202 | |||
203 | if (--dice->dev_lock_count == 0) | ||
204 | dice_lock_changed(dice); | ||
205 | out: | ||
206 | spin_unlock_irq(&dice->lock); | ||
207 | } | ||
diff --git a/sound/firewire/dice/dice-transaction.c b/sound/firewire/dice/dice-transaction.c new file mode 100644 index 000000000000..1fe304c0a044 --- /dev/null +++ b/sound/firewire/dice/dice-transaction.c | |||
@@ -0,0 +1,387 @@ | |||
1 | /* | ||
2 | * dice_transaction.c - a part of driver for Dice based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch | ||
5 | * Copyright (c) 2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #include "dice.h" | ||
11 | |||
12 | #define NOTIFICATION_TIMEOUT_MS 100 | ||
13 | |||
14 | static u64 get_subaddr(struct snd_dice *dice, enum snd_dice_addr_type type, | ||
15 | u64 offset) | ||
16 | { | ||
17 | switch (type) { | ||
18 | case SND_DICE_ADDR_TYPE_TX: | ||
19 | offset += dice->tx_offset; | ||
20 | break; | ||
21 | case SND_DICE_ADDR_TYPE_RX: | ||
22 | offset += dice->rx_offset; | ||
23 | break; | ||
24 | case SND_DICE_ADDR_TYPE_SYNC: | ||
25 | offset += dice->sync_offset; | ||
26 | break; | ||
27 | case SND_DICE_ADDR_TYPE_RSRV: | ||
28 | offset += dice->rsrv_offset; | ||
29 | break; | ||
30 | case SND_DICE_ADDR_TYPE_GLOBAL: | ||
31 | default: | ||
32 | offset += dice->global_offset; | ||
33 | break; | ||
34 | } | ||
35 | offset += DICE_PRIVATE_SPACE; | ||
36 | return offset; | ||
37 | } | ||
38 | |||
39 | int snd_dice_transaction_write(struct snd_dice *dice, | ||
40 | enum snd_dice_addr_type type, | ||
41 | unsigned int offset, void *buf, unsigned int len) | ||
42 | { | ||
43 | return snd_fw_transaction(dice->unit, | ||
44 | (len == 4) ? TCODE_WRITE_QUADLET_REQUEST : | ||
45 | TCODE_WRITE_BLOCK_REQUEST, | ||
46 | get_subaddr(dice, type, offset), buf, len, 0); | ||
47 | } | ||
48 | |||
49 | int snd_dice_transaction_read(struct snd_dice *dice, | ||
50 | enum snd_dice_addr_type type, unsigned int offset, | ||
51 | void *buf, unsigned int len) | ||
52 | { | ||
53 | return snd_fw_transaction(dice->unit, | ||
54 | (len == 4) ? TCODE_READ_QUADLET_REQUEST : | ||
55 | TCODE_READ_BLOCK_REQUEST, | ||
56 | get_subaddr(dice, type, offset), buf, len, 0); | ||
57 | } | ||
58 | |||
59 | static unsigned int get_clock_info(struct snd_dice *dice, __be32 *info) | ||
60 | { | ||
61 | return snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT, | ||
62 | info, 4); | ||
63 | } | ||
64 | |||
65 | static int set_clock_info(struct snd_dice *dice, | ||
66 | unsigned int rate, unsigned int source) | ||
67 | { | ||
68 | unsigned int retries = 3; | ||
69 | unsigned int i; | ||
70 | __be32 info; | ||
71 | u32 mask; | ||
72 | u32 clock; | ||
73 | int err; | ||
74 | retry: | ||
75 | err = get_clock_info(dice, &info); | ||
76 | if (err < 0) | ||
77 | goto end; | ||
78 | |||
79 | clock = be32_to_cpu(info); | ||
80 | if (source != UINT_MAX) { | ||
81 | mask = CLOCK_SOURCE_MASK; | ||
82 | clock &= ~mask; | ||
83 | clock |= source; | ||
84 | } | ||
85 | if (rate != UINT_MAX) { | ||
86 | for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) { | ||
87 | if (snd_dice_rates[i] == rate) | ||
88 | break; | ||
89 | } | ||
90 | if (i == ARRAY_SIZE(snd_dice_rates)) { | ||
91 | err = -EINVAL; | ||
92 | goto end; | ||
93 | } | ||
94 | |||
95 | mask = CLOCK_RATE_MASK; | ||
96 | clock &= ~mask; | ||
97 | clock |= i << CLOCK_RATE_SHIFT; | ||
98 | } | ||
99 | info = cpu_to_be32(clock); | ||
100 | |||
101 | if (completion_done(&dice->clock_accepted)) | ||
102 | reinit_completion(&dice->clock_accepted); | ||
103 | |||
104 | err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, | ||
105 | &info, 4); | ||
106 | if (err < 0) | ||
107 | goto end; | ||
108 | |||
109 | /* Timeout means it's invalid request, probably bus reset occurred. */ | ||
110 | if (wait_for_completion_timeout(&dice->clock_accepted, | ||
111 | msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { | ||
112 | if (retries-- == 0) { | ||
113 | err = -ETIMEDOUT; | ||
114 | goto end; | ||
115 | } | ||
116 | |||
117 | err = snd_dice_transaction_reinit(dice); | ||
118 | if (err < 0) | ||
119 | goto end; | ||
120 | |||
121 | msleep(500); /* arbitrary */ | ||
122 | goto retry; | ||
123 | } | ||
124 | end: | ||
125 | return err; | ||
126 | } | ||
127 | |||
128 | int snd_dice_transaction_get_clock_source(struct snd_dice *dice, | ||
129 | unsigned int *source) | ||
130 | { | ||
131 | __be32 info; | ||
132 | int err; | ||
133 | |||
134 | err = get_clock_info(dice, &info); | ||
135 | if (err >= 0) | ||
136 | *source = be32_to_cpu(info) & CLOCK_SOURCE_MASK; | ||
137 | |||
138 | return err; | ||
139 | } | ||
140 | int snd_dice_transaction_set_clock_source(struct snd_dice *dice, | ||
141 | unsigned int source) | ||
142 | { | ||
143 | return set_clock_info(dice, UINT_MAX, source); | ||
144 | } | ||
145 | |||
146 | int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate) | ||
147 | { | ||
148 | __be32 info; | ||
149 | unsigned int index; | ||
150 | int err; | ||
151 | |||
152 | err = get_clock_info(dice, &info); | ||
153 | if (err < 0) | ||
154 | goto end; | ||
155 | |||
156 | index = (be32_to_cpu(info) & CLOCK_RATE_MASK) >> CLOCK_RATE_SHIFT; | ||
157 | if (index >= SND_DICE_RATES_COUNT) { | ||
158 | err = -ENOSYS; | ||
159 | goto end; | ||
160 | } | ||
161 | |||
162 | *rate = snd_dice_rates[index]; | ||
163 | end: | ||
164 | return err; | ||
165 | } | ||
166 | int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate) | ||
167 | { | ||
168 | return set_clock_info(dice, rate, UINT_MAX); | ||
169 | } | ||
170 | |||
171 | int snd_dice_transaction_set_enable(struct snd_dice *dice) | ||
172 | { | ||
173 | __be32 value; | ||
174 | int err = 0; | ||
175 | |||
176 | if (dice->global_enabled) | ||
177 | goto end; | ||
178 | |||
179 | value = cpu_to_be32(1); | ||
180 | err = snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
181 | get_subaddr(dice, SND_DICE_ADDR_TYPE_GLOBAL, | ||
182 | GLOBAL_ENABLE), | ||
183 | &value, 4, | ||
184 | FW_FIXED_GENERATION | dice->owner_generation); | ||
185 | if (err < 0) | ||
186 | goto end; | ||
187 | |||
188 | dice->global_enabled = true; | ||
189 | end: | ||
190 | return err; | ||
191 | } | ||
192 | |||
193 | void snd_dice_transaction_clear_enable(struct snd_dice *dice) | ||
194 | { | ||
195 | __be32 value; | ||
196 | |||
197 | value = 0; | ||
198 | snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
199 | get_subaddr(dice, SND_DICE_ADDR_TYPE_GLOBAL, | ||
200 | GLOBAL_ENABLE), | ||
201 | &value, 4, FW_QUIET | | ||
202 | FW_FIXED_GENERATION | dice->owner_generation); | ||
203 | |||
204 | dice->global_enabled = false; | ||
205 | } | ||
206 | |||
207 | static void dice_notification(struct fw_card *card, struct fw_request *request, | ||
208 | int tcode, int destination, int source, | ||
209 | int generation, unsigned long long offset, | ||
210 | void *data, size_t length, void *callback_data) | ||
211 | { | ||
212 | struct snd_dice *dice = callback_data; | ||
213 | u32 bits; | ||
214 | unsigned long flags; | ||
215 | |||
216 | if (tcode != TCODE_WRITE_QUADLET_REQUEST) { | ||
217 | fw_send_response(card, request, RCODE_TYPE_ERROR); | ||
218 | return; | ||
219 | } | ||
220 | if ((offset & 3) != 0) { | ||
221 | fw_send_response(card, request, RCODE_ADDRESS_ERROR); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | bits = be32_to_cpup(data); | ||
226 | |||
227 | spin_lock_irqsave(&dice->lock, flags); | ||
228 | dice->notification_bits |= bits; | ||
229 | spin_unlock_irqrestore(&dice->lock, flags); | ||
230 | |||
231 | fw_send_response(card, request, RCODE_COMPLETE); | ||
232 | |||
233 | if (bits & NOTIFY_CLOCK_ACCEPTED) | ||
234 | complete(&dice->clock_accepted); | ||
235 | wake_up(&dice->hwdep_wait); | ||
236 | } | ||
237 | |||
238 | static int register_notification_address(struct snd_dice *dice, bool retry) | ||
239 | { | ||
240 | struct fw_device *device = fw_parent_device(dice->unit); | ||
241 | __be64 *buffer; | ||
242 | unsigned int retries; | ||
243 | int err; | ||
244 | |||
245 | retries = (retry) ? 3 : 0; | ||
246 | |||
247 | buffer = kmalloc(2 * 8, GFP_KERNEL); | ||
248 | if (!buffer) | ||
249 | return -ENOMEM; | ||
250 | |||
251 | for (;;) { | ||
252 | buffer[0] = cpu_to_be64(OWNER_NO_OWNER); | ||
253 | buffer[1] = cpu_to_be64( | ||
254 | ((u64)device->card->node_id << OWNER_NODE_SHIFT) | | ||
255 | dice->notification_handler.offset); | ||
256 | |||
257 | dice->owner_generation = device->generation; | ||
258 | smp_rmb(); /* node_id vs. generation */ | ||
259 | err = snd_fw_transaction(dice->unit, TCODE_LOCK_COMPARE_SWAP, | ||
260 | get_subaddr(dice, | ||
261 | SND_DICE_ADDR_TYPE_GLOBAL, | ||
262 | GLOBAL_OWNER), | ||
263 | buffer, 2 * 8, | ||
264 | FW_FIXED_GENERATION | | ||
265 | dice->owner_generation); | ||
266 | if (err == 0) { | ||
267 | /* success */ | ||
268 | if (buffer[0] == cpu_to_be64(OWNER_NO_OWNER)) | ||
269 | break; | ||
270 | /* The address seems to be already registered. */ | ||
271 | if (buffer[0] == buffer[1]) | ||
272 | break; | ||
273 | |||
274 | dev_err(&dice->unit->device, | ||
275 | "device is already in use\n"); | ||
276 | err = -EBUSY; | ||
277 | } | ||
278 | if (err != -EAGAIN || retries-- > 0) | ||
279 | break; | ||
280 | |||
281 | msleep(20); | ||
282 | } | ||
283 | |||
284 | kfree(buffer); | ||
285 | |||
286 | if (err < 0) | ||
287 | dice->owner_generation = -1; | ||
288 | |||
289 | return err; | ||
290 | } | ||
291 | |||
292 | static void unregister_notification_address(struct snd_dice *dice) | ||
293 | { | ||
294 | struct fw_device *device = fw_parent_device(dice->unit); | ||
295 | __be64 *buffer; | ||
296 | |||
297 | buffer = kmalloc(2 * 8, GFP_KERNEL); | ||
298 | if (buffer == NULL) | ||
299 | return; | ||
300 | |||
301 | buffer[0] = cpu_to_be64( | ||
302 | ((u64)device->card->node_id << OWNER_NODE_SHIFT) | | ||
303 | dice->notification_handler.offset); | ||
304 | buffer[1] = cpu_to_be64(OWNER_NO_OWNER); | ||
305 | snd_fw_transaction(dice->unit, TCODE_LOCK_COMPARE_SWAP, | ||
306 | get_subaddr(dice, SND_DICE_ADDR_TYPE_GLOBAL, | ||
307 | GLOBAL_OWNER), | ||
308 | buffer, 2 * 8, FW_QUIET | | ||
309 | FW_FIXED_GENERATION | dice->owner_generation); | ||
310 | |||
311 | kfree(buffer); | ||
312 | |||
313 | dice->owner_generation = -1; | ||
314 | } | ||
315 | |||
316 | void snd_dice_transaction_destroy(struct snd_dice *dice) | ||
317 | { | ||
318 | struct fw_address_handler *handler = &dice->notification_handler; | ||
319 | |||
320 | if (handler->callback_data == NULL) | ||
321 | return; | ||
322 | |||
323 | unregister_notification_address(dice); | ||
324 | |||
325 | fw_core_remove_address_handler(handler); | ||
326 | handler->callback_data = NULL; | ||
327 | } | ||
328 | |||
329 | int snd_dice_transaction_reinit(struct snd_dice *dice) | ||
330 | { | ||
331 | struct fw_address_handler *handler = &dice->notification_handler; | ||
332 | |||
333 | if (handler->callback_data == NULL) | ||
334 | return -EINVAL; | ||
335 | |||
336 | return register_notification_address(dice, false); | ||
337 | } | ||
338 | |||
339 | int snd_dice_transaction_init(struct snd_dice *dice) | ||
340 | { | ||
341 | struct fw_address_handler *handler = &dice->notification_handler; | ||
342 | __be32 *pointers; | ||
343 | int err; | ||
344 | |||
345 | /* Use the same way which dice_interface_check() does. */ | ||
346 | pointers = kmalloc(sizeof(__be32) * 10, GFP_KERNEL); | ||
347 | if (pointers == NULL) | ||
348 | return -ENOMEM; | ||
349 | |||
350 | /* Get offsets for sub-addresses */ | ||
351 | err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, | ||
352 | DICE_PRIVATE_SPACE, | ||
353 | pointers, sizeof(__be32) * 10, 0); | ||
354 | if (err < 0) | ||
355 | goto end; | ||
356 | |||
357 | /* Allocation callback in address space over host controller */ | ||
358 | handler->length = 4; | ||
359 | handler->address_callback = dice_notification; | ||
360 | handler->callback_data = dice; | ||
361 | err = fw_core_add_address_handler(handler, &fw_high_memory_region); | ||
362 | if (err < 0) { | ||
363 | handler->callback_data = NULL; | ||
364 | goto end; | ||
365 | } | ||
366 | |||
367 | /* Register the address space */ | ||
368 | err = register_notification_address(dice, true); | ||
369 | if (err < 0) { | ||
370 | fw_core_remove_address_handler(handler); | ||
371 | handler->callback_data = NULL; | ||
372 | goto end; | ||
373 | } | ||
374 | |||
375 | dice->global_offset = be32_to_cpu(pointers[0]) * 4; | ||
376 | dice->tx_offset = be32_to_cpu(pointers[2]) * 4; | ||
377 | dice->rx_offset = be32_to_cpu(pointers[4]) * 4; | ||
378 | dice->sync_offset = be32_to_cpu(pointers[6]) * 4; | ||
379 | dice->rsrv_offset = be32_to_cpu(pointers[8]) * 4; | ||
380 | |||
381 | /* Set up later. */ | ||
382 | if (be32_to_cpu(pointers[1]) * 4 >= GLOBAL_CLOCK_CAPABILITIES + 4) | ||
383 | dice->clock_caps = 1; | ||
384 | end: | ||
385 | kfree(pointers); | ||
386 | return err; | ||
387 | } | ||
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c new file mode 100644 index 000000000000..8e2c172de8a7 --- /dev/null +++ b/sound/firewire/dice/dice.c | |||
@@ -0,0 +1,362 @@ | |||
1 | /* | ||
2 | * TC Applied Technologies Digital Interface Communications Engine driver | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include "dice.h" | ||
9 | |||
10 | MODULE_DESCRIPTION("DICE driver"); | ||
11 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
12 | MODULE_LICENSE("GPL v2"); | ||
13 | |||
14 | #define OUI_WEISS 0x001c6a | ||
15 | |||
16 | #define DICE_CATEGORY_ID 0x04 | ||
17 | #define WEISS_CATEGORY_ID 0x00 | ||
18 | |||
19 | static int dice_interface_check(struct fw_unit *unit) | ||
20 | { | ||
21 | static const int min_values[10] = { | ||
22 | 10, 0x64 / 4, | ||
23 | 10, 0x18 / 4, | ||
24 | 10, 0x18 / 4, | ||
25 | 0, 0, | ||
26 | 0, 0, | ||
27 | }; | ||
28 | struct fw_device *device = fw_parent_device(unit); | ||
29 | struct fw_csr_iterator it; | ||
30 | int key, val, vendor = -1, model = -1, err; | ||
31 | unsigned int category, i; | ||
32 | __be32 *pointers, value; | ||
33 | __be32 tx_data[4]; | ||
34 | __be32 version; | ||
35 | |||
36 | pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32), | ||
37 | GFP_KERNEL); | ||
38 | if (pointers == NULL) | ||
39 | return -ENOMEM; | ||
40 | |||
41 | /* | ||
42 | * Check that GUID and unit directory are constructed according to DICE | ||
43 | * rules, i.e., that the specifier ID is the GUID's OUI, and that the | ||
44 | * GUID chip ID consists of the 8-bit category ID, the 10-bit product | ||
45 | * ID, and a 22-bit serial number. | ||
46 | */ | ||
47 | fw_csr_iterator_init(&it, unit->directory); | ||
48 | while (fw_csr_iterator_next(&it, &key, &val)) { | ||
49 | switch (key) { | ||
50 | case CSR_SPECIFIER_ID: | ||
51 | vendor = val; | ||
52 | break; | ||
53 | case CSR_MODEL: | ||
54 | model = val; | ||
55 | break; | ||
56 | } | ||
57 | } | ||
58 | if (vendor == OUI_WEISS) | ||
59 | category = WEISS_CATEGORY_ID; | ||
60 | else | ||
61 | category = DICE_CATEGORY_ID; | ||
62 | if (device->config_rom[3] != ((vendor << 8) | category) || | ||
63 | device->config_rom[4] >> 22 != model) { | ||
64 | err = -ENODEV; | ||
65 | goto end; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Check that the sub address spaces exist and are located inside the | ||
70 | * private address space. The minimum values are chosen so that all | ||
71 | * minimally required registers are included. | ||
72 | */ | ||
73 | err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST, | ||
74 | DICE_PRIVATE_SPACE, pointers, | ||
75 | sizeof(__be32) * ARRAY_SIZE(min_values), 0); | ||
76 | if (err < 0) { | ||
77 | err = -ENODEV; | ||
78 | goto end; | ||
79 | } | ||
80 | for (i = 0; i < ARRAY_SIZE(min_values); ++i) { | ||
81 | value = be32_to_cpu(pointers[i]); | ||
82 | if (value < min_values[i] || value >= 0x40000) { | ||
83 | err = -ENODEV; | ||
84 | goto end; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* We support playback only. Let capture devices be handled by FFADO. */ | ||
89 | err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST, | ||
90 | DICE_PRIVATE_SPACE + | ||
91 | be32_to_cpu(pointers[2]) * 4, | ||
92 | tx_data, sizeof(tx_data), 0); | ||
93 | if (err < 0 || (tx_data[0] && tx_data[3])) { | ||
94 | err = -ENODEV; | ||
95 | goto end; | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * Check that the implemented DICE driver specification major version | ||
100 | * number matches. | ||
101 | */ | ||
102 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | ||
103 | DICE_PRIVATE_SPACE + | ||
104 | be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION, | ||
105 | &version, 4, 0); | ||
106 | if (err < 0) { | ||
107 | err = -ENODEV; | ||
108 | goto end; | ||
109 | } | ||
110 | if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) { | ||
111 | dev_err(&unit->device, | ||
112 | "unknown DICE version: 0x%08x\n", be32_to_cpu(version)); | ||
113 | err = -ENODEV; | ||
114 | goto end; | ||
115 | } | ||
116 | end: | ||
117 | return err; | ||
118 | } | ||
119 | |||
120 | static int highest_supported_mode_rate(struct snd_dice *dice, | ||
121 | unsigned int mode, unsigned int *rate) | ||
122 | { | ||
123 | unsigned int i, m; | ||
124 | |||
125 | for (i = ARRAY_SIZE(snd_dice_rates); i > 0; i--) { | ||
126 | *rate = snd_dice_rates[i - 1]; | ||
127 | if (snd_dice_stream_get_rate_mode(dice, *rate, &m) < 0) | ||
128 | continue; | ||
129 | if (mode == m) | ||
130 | break; | ||
131 | } | ||
132 | if (i == 0) | ||
133 | return -EINVAL; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode) | ||
139 | { | ||
140 | __be32 values[2]; | ||
141 | unsigned int rate; | ||
142 | int err; | ||
143 | |||
144 | if (highest_supported_mode_rate(dice, mode, &rate) < 0) { | ||
145 | dice->rx_channels[mode] = 0; | ||
146 | dice->rx_midi_ports[mode] = 0; | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | err = snd_dice_transaction_set_rate(dice, rate); | ||
151 | if (err < 0) | ||
152 | return err; | ||
153 | |||
154 | err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO, | ||
155 | values, sizeof(values)); | ||
156 | if (err < 0) | ||
157 | return err; | ||
158 | |||
159 | dice->rx_channels[mode] = be32_to_cpu(values[0]); | ||
160 | dice->rx_midi_ports[mode] = be32_to_cpu(values[1]); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int dice_read_params(struct snd_dice *dice) | ||
166 | { | ||
167 | __be32 value; | ||
168 | int mode, err; | ||
169 | |||
170 | /* some very old firmwares don't tell about their clock support */ | ||
171 | if (dice->clock_caps > 0) { | ||
172 | err = snd_dice_transaction_read_global(dice, | ||
173 | GLOBAL_CLOCK_CAPABILITIES, | ||
174 | &value, 4); | ||
175 | if (err < 0) | ||
176 | return err; | ||
177 | dice->clock_caps = be32_to_cpu(value); | ||
178 | } else { | ||
179 | /* this should be supported by any device */ | ||
180 | dice->clock_caps = CLOCK_CAP_RATE_44100 | | ||
181 | CLOCK_CAP_RATE_48000 | | ||
182 | CLOCK_CAP_SOURCE_ARX1 | | ||
183 | CLOCK_CAP_SOURCE_INTERNAL; | ||
184 | } | ||
185 | |||
186 | for (mode = 2; mode >= 0; --mode) { | ||
187 | err = dice_read_mode_params(dice, mode); | ||
188 | if (err < 0) | ||
189 | return err; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void dice_card_strings(struct snd_dice *dice) | ||
196 | { | ||
197 | struct snd_card *card = dice->card; | ||
198 | struct fw_device *dev = fw_parent_device(dice->unit); | ||
199 | char vendor[32], model[32]; | ||
200 | unsigned int i; | ||
201 | int err; | ||
202 | |||
203 | strcpy(card->driver, "DICE"); | ||
204 | |||
205 | strcpy(card->shortname, "DICE"); | ||
206 | BUILD_BUG_ON(NICK_NAME_SIZE < sizeof(card->shortname)); | ||
207 | err = snd_dice_transaction_read_global(dice, GLOBAL_NICK_NAME, | ||
208 | card->shortname, | ||
209 | sizeof(card->shortname)); | ||
210 | if (err >= 0) { | ||
211 | /* DICE strings are returned in "always-wrong" endianness */ | ||
212 | BUILD_BUG_ON(sizeof(card->shortname) % 4 != 0); | ||
213 | for (i = 0; i < sizeof(card->shortname); i += 4) | ||
214 | swab32s((u32 *)&card->shortname[i]); | ||
215 | card->shortname[sizeof(card->shortname) - 1] = '\0'; | ||
216 | } | ||
217 | |||
218 | strcpy(vendor, "?"); | ||
219 | fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor)); | ||
220 | strcpy(model, "?"); | ||
221 | fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model)); | ||
222 | snprintf(card->longname, sizeof(card->longname), | ||
223 | "%s %s (serial %u) at %s, S%d", | ||
224 | vendor, model, dev->config_rom[4] & 0x3fffff, | ||
225 | dev_name(&dice->unit->device), 100 << dev->max_speed); | ||
226 | |||
227 | strcpy(card->mixername, "DICE"); | ||
228 | } | ||
229 | |||
230 | static void dice_card_free(struct snd_card *card) | ||
231 | { | ||
232 | struct snd_dice *dice = card->private_data; | ||
233 | |||
234 | snd_dice_transaction_destroy(dice); | ||
235 | mutex_destroy(&dice->mutex); | ||
236 | } | ||
237 | |||
238 | static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | ||
239 | { | ||
240 | struct snd_card *card; | ||
241 | struct snd_dice *dice; | ||
242 | int err; | ||
243 | |||
244 | err = dice_interface_check(unit); | ||
245 | if (err < 0) | ||
246 | goto end; | ||
247 | |||
248 | err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, | ||
249 | sizeof(*dice), &card); | ||
250 | if (err < 0) | ||
251 | goto end; | ||
252 | |||
253 | dice = card->private_data; | ||
254 | dice->card = card; | ||
255 | dice->unit = unit; | ||
256 | card->private_free = dice_card_free; | ||
257 | |||
258 | spin_lock_init(&dice->lock); | ||
259 | mutex_init(&dice->mutex); | ||
260 | init_completion(&dice->clock_accepted); | ||
261 | init_waitqueue_head(&dice->hwdep_wait); | ||
262 | |||
263 | err = snd_dice_transaction_init(dice); | ||
264 | if (err < 0) | ||
265 | goto error; | ||
266 | |||
267 | err = dice_read_params(dice); | ||
268 | if (err < 0) | ||
269 | goto error; | ||
270 | |||
271 | dice_card_strings(dice); | ||
272 | |||
273 | err = snd_dice_create_pcm(dice); | ||
274 | if (err < 0) | ||
275 | goto error; | ||
276 | |||
277 | err = snd_dice_create_hwdep(dice); | ||
278 | if (err < 0) | ||
279 | goto error; | ||
280 | |||
281 | snd_dice_create_proc(dice); | ||
282 | |||
283 | err = snd_dice_stream_init(dice); | ||
284 | if (err < 0) | ||
285 | goto error; | ||
286 | |||
287 | err = snd_card_register(card); | ||
288 | if (err < 0) { | ||
289 | snd_dice_stream_destroy(dice); | ||
290 | goto error; | ||
291 | } | ||
292 | |||
293 | dev_set_drvdata(&unit->device, dice); | ||
294 | end: | ||
295 | return err; | ||
296 | error: | ||
297 | snd_card_free(card); | ||
298 | return err; | ||
299 | } | ||
300 | |||
301 | static void dice_remove(struct fw_unit *unit) | ||
302 | { | ||
303 | struct snd_dice *dice = dev_get_drvdata(&unit->device); | ||
304 | |||
305 | snd_card_disconnect(dice->card); | ||
306 | |||
307 | mutex_lock(&dice->mutex); | ||
308 | |||
309 | snd_dice_stream_destroy(dice); | ||
310 | |||
311 | mutex_unlock(&dice->mutex); | ||
312 | |||
313 | snd_card_free_when_closed(dice->card); | ||
314 | } | ||
315 | |||
316 | static void dice_bus_reset(struct fw_unit *unit) | ||
317 | { | ||
318 | struct snd_dice *dice = dev_get_drvdata(&unit->device); | ||
319 | |||
320 | /* The handler address register becomes initialized. */ | ||
321 | snd_dice_transaction_reinit(dice); | ||
322 | |||
323 | mutex_lock(&dice->mutex); | ||
324 | snd_dice_stream_update(dice); | ||
325 | mutex_unlock(&dice->mutex); | ||
326 | } | ||
327 | |||
328 | #define DICE_INTERFACE 0x000001 | ||
329 | |||
330 | static const struct ieee1394_device_id dice_id_table[] = { | ||
331 | { | ||
332 | .match_flags = IEEE1394_MATCH_VERSION, | ||
333 | .version = DICE_INTERFACE, | ||
334 | }, | ||
335 | { } | ||
336 | }; | ||
337 | MODULE_DEVICE_TABLE(ieee1394, dice_id_table); | ||
338 | |||
339 | static struct fw_driver dice_driver = { | ||
340 | .driver = { | ||
341 | .owner = THIS_MODULE, | ||
342 | .name = KBUILD_MODNAME, | ||
343 | .bus = &fw_bus_type, | ||
344 | }, | ||
345 | .probe = dice_probe, | ||
346 | .update = dice_bus_reset, | ||
347 | .remove = dice_remove, | ||
348 | .id_table = dice_id_table, | ||
349 | }; | ||
350 | |||
351 | static int __init alsa_dice_init(void) | ||
352 | { | ||
353 | return driver_register(&dice_driver.driver); | ||
354 | } | ||
355 | |||
356 | static void __exit alsa_dice_exit(void) | ||
357 | { | ||
358 | driver_unregister(&dice_driver.driver); | ||
359 | } | ||
360 | |||
361 | module_init(alsa_dice_init); | ||
362 | module_exit(alsa_dice_exit); | ||
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h new file mode 100644 index 000000000000..969189a6604f --- /dev/null +++ b/sound/firewire/dice/dice.h | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * dice.h - a part of driver for Dice based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch | ||
5 | * Copyright (c) 2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef SOUND_DICE_H_INCLUDED | ||
11 | #define SOUND_DICE_H_INCLUDED | ||
12 | |||
13 | #include <linux/compat.h> | ||
14 | #include <linux/completion.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/firewire.h> | ||
18 | #include <linux/firewire-constants.h> | ||
19 | #include <linux/jiffies.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/mod_devicetable.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/wait.h> | ||
26 | |||
27 | #include <sound/control.h> | ||
28 | #include <sound/core.h> | ||
29 | #include <sound/firewire.h> | ||
30 | #include <sound/hwdep.h> | ||
31 | #include <sound/info.h> | ||
32 | #include <sound/initval.h> | ||
33 | #include <sound/pcm.h> | ||
34 | #include <sound/pcm_params.h> | ||
35 | |||
36 | #include "../amdtp.h" | ||
37 | #include "../iso-resources.h" | ||
38 | #include "../lib.h" | ||
39 | #include "dice-interface.h" | ||
40 | |||
41 | struct snd_dice { | ||
42 | struct snd_card *card; | ||
43 | struct fw_unit *unit; | ||
44 | spinlock_t lock; | ||
45 | struct mutex mutex; | ||
46 | |||
47 | /* Offsets for sub-addresses */ | ||
48 | unsigned int global_offset; | ||
49 | unsigned int rx_offset; | ||
50 | unsigned int tx_offset; | ||
51 | unsigned int sync_offset; | ||
52 | unsigned int rsrv_offset; | ||
53 | |||
54 | unsigned int clock_caps; | ||
55 | unsigned int rx_channels[3]; | ||
56 | unsigned int rx_midi_ports[3]; | ||
57 | struct fw_address_handler notification_handler; | ||
58 | int owner_generation; | ||
59 | int dev_lock_count; /* > 0 driver, < 0 userspace */ | ||
60 | bool dev_lock_changed; | ||
61 | bool global_enabled; | ||
62 | struct completion clock_accepted; | ||
63 | wait_queue_head_t hwdep_wait; | ||
64 | u32 notification_bits; | ||
65 | struct fw_iso_resources rx_resources; | ||
66 | struct amdtp_stream rx_stream; | ||
67 | }; | ||
68 | |||
69 | enum snd_dice_addr_type { | ||
70 | SND_DICE_ADDR_TYPE_PRIVATE, | ||
71 | SND_DICE_ADDR_TYPE_GLOBAL, | ||
72 | SND_DICE_ADDR_TYPE_TX, | ||
73 | SND_DICE_ADDR_TYPE_RX, | ||
74 | SND_DICE_ADDR_TYPE_SYNC, | ||
75 | SND_DICE_ADDR_TYPE_RSRV, | ||
76 | }; | ||
77 | |||
78 | int snd_dice_transaction_write(struct snd_dice *dice, | ||
79 | enum snd_dice_addr_type type, | ||
80 | unsigned int offset, | ||
81 | void *buf, unsigned int len); | ||
82 | int snd_dice_transaction_read(struct snd_dice *dice, | ||
83 | enum snd_dice_addr_type type, unsigned int offset, | ||
84 | void *buf, unsigned int len); | ||
85 | |||
86 | static inline int snd_dice_transaction_write_global(struct snd_dice *dice, | ||
87 | unsigned int offset, | ||
88 | void *buf, unsigned int len) | ||
89 | { | ||
90 | return snd_dice_transaction_write(dice, | ||
91 | SND_DICE_ADDR_TYPE_GLOBAL, offset, | ||
92 | buf, len); | ||
93 | } | ||
94 | static inline int snd_dice_transaction_read_global(struct snd_dice *dice, | ||
95 | unsigned int offset, | ||
96 | void *buf, unsigned int len) | ||
97 | { | ||
98 | return snd_dice_transaction_read(dice, | ||
99 | SND_DICE_ADDR_TYPE_GLOBAL, offset, | ||
100 | buf, len); | ||
101 | } | ||
102 | static inline int snd_dice_transaction_write_tx(struct snd_dice *dice, | ||
103 | unsigned int offset, | ||
104 | void *buf, unsigned int len) | ||
105 | { | ||
106 | return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_TX, offset, | ||
107 | buf, len); | ||
108 | } | ||
109 | static inline int snd_dice_transaction_read_tx(struct snd_dice *dice, | ||
110 | unsigned int offset, | ||
111 | void *buf, unsigned int len) | ||
112 | { | ||
113 | return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_TX, offset, | ||
114 | buf, len); | ||
115 | } | ||
116 | static inline int snd_dice_transaction_write_rx(struct snd_dice *dice, | ||
117 | unsigned int offset, | ||
118 | void *buf, unsigned int len) | ||
119 | { | ||
120 | return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_RX, offset, | ||
121 | buf, len); | ||
122 | } | ||
123 | static inline int snd_dice_transaction_read_rx(struct snd_dice *dice, | ||
124 | unsigned int offset, | ||
125 | void *buf, unsigned int len) | ||
126 | { | ||
127 | return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_RX, offset, | ||
128 | buf, len); | ||
129 | } | ||
130 | static inline int snd_dice_transaction_write_sync(struct snd_dice *dice, | ||
131 | unsigned int offset, | ||
132 | void *buf, unsigned int len) | ||
133 | { | ||
134 | return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_SYNC, offset, | ||
135 | buf, len); | ||
136 | } | ||
137 | static inline int snd_dice_transaction_read_sync(struct snd_dice *dice, | ||
138 | unsigned int offset, | ||
139 | void *buf, unsigned int len) | ||
140 | { | ||
141 | return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_SYNC, offset, | ||
142 | buf, len); | ||
143 | } | ||
144 | |||
145 | int snd_dice_transaction_set_clock_source(struct snd_dice *dice, | ||
146 | unsigned int source); | ||
147 | int snd_dice_transaction_get_clock_source(struct snd_dice *dice, | ||
148 | unsigned int *source); | ||
149 | int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate); | ||
150 | int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate); | ||
151 | int snd_dice_transaction_set_enable(struct snd_dice *dice); | ||
152 | void snd_dice_transaction_clear_enable(struct snd_dice *dice); | ||
153 | int snd_dice_transaction_init(struct snd_dice *dice); | ||
154 | int snd_dice_transaction_reinit(struct snd_dice *dice); | ||
155 | void snd_dice_transaction_destroy(struct snd_dice *dice); | ||
156 | |||
157 | #define SND_DICE_RATES_COUNT 7 | ||
158 | extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT]; | ||
159 | |||
160 | int snd_dice_stream_get_rate_mode(struct snd_dice *dice, | ||
161 | unsigned int rate, unsigned int *mode); | ||
162 | |||
163 | int snd_dice_stream_start_packets(struct snd_dice *dice); | ||
164 | int snd_dice_stream_start(struct snd_dice *dice); | ||
165 | void snd_dice_stream_stop_packets(struct snd_dice *dice); | ||
166 | void snd_dice_stream_stop(struct snd_dice *dice); | ||
167 | int snd_dice_stream_init(struct snd_dice *dice); | ||
168 | void snd_dice_stream_destroy(struct snd_dice *dice); | ||
169 | void snd_dice_stream_update(struct snd_dice *dice); | ||
170 | |||
171 | int snd_dice_stream_lock_try(struct snd_dice *dice); | ||
172 | void snd_dice_stream_lock_release(struct snd_dice *dice); | ||
173 | |||
174 | int snd_dice_create_pcm(struct snd_dice *dice); | ||
175 | |||
176 | int snd_dice_create_hwdep(struct snd_dice *dice); | ||
177 | |||
178 | void snd_dice_create_proc(struct snd_dice *dice); | ||
179 | |||
180 | #endif | ||
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 7ac94439e758..48d6dca471c6 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c | |||
@@ -131,14 +131,8 @@ static void isight_samples(struct isight *isight, | |||
131 | 131 | ||
132 | static void isight_pcm_abort(struct isight *isight) | 132 | static void isight_pcm_abort(struct isight *isight) |
133 | { | 133 | { |
134 | unsigned long flags; | 134 | if (ACCESS_ONCE(isight->pcm_active)) |
135 | 135 | snd_pcm_stop_xrun(isight->pcm); | |
136 | if (ACCESS_ONCE(isight->pcm_active)) { | ||
137 | snd_pcm_stream_lock_irqsave(isight->pcm, flags); | ||
138 | if (snd_pcm_running(isight->pcm)) | ||
139 | snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN); | ||
140 | snd_pcm_stream_unlock_irqrestore(isight->pcm, flags); | ||
141 | } | ||
142 | } | 136 | } |
143 | 137 | ||
144 | static void isight_dropped_samples(struct isight *isight, unsigned int total) | 138 | static void isight_dropped_samples(struct isight *isight, unsigned int total) |
diff --git a/sound/firewire/oxfw/Makefile b/sound/firewire/oxfw/Makefile new file mode 100644 index 000000000000..0cf48fd87688 --- /dev/null +++ b/sound/firewire/oxfw/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | snd-oxfw-objs := oxfw-stream.o oxfw-control.o oxfw-pcm.o oxfw.o | ||
2 | obj-m += snd-oxfw.o | ||
diff --git a/sound/firewire/oxfw/oxfw-control.c b/sound/firewire/oxfw/oxfw-control.c new file mode 100644 index 000000000000..02a1cb90f20d --- /dev/null +++ b/sound/firewire/oxfw/oxfw-control.c | |||
@@ -0,0 +1,283 @@ | |||
1 | /* | ||
2 | * oxfw_stream.c - a part of driver for OXFW970/971 based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include "oxfw.h" | ||
9 | |||
10 | enum control_action { CTL_READ, CTL_WRITE }; | ||
11 | enum control_attribute { | ||
12 | CTL_MIN = 0x02, | ||
13 | CTL_MAX = 0x03, | ||
14 | CTL_CURRENT = 0x10, | ||
15 | }; | ||
16 | |||
17 | static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value, | ||
18 | enum control_action action) | ||
19 | { | ||
20 | u8 *buf; | ||
21 | u8 response_ok; | ||
22 | int err; | ||
23 | |||
24 | buf = kmalloc(11, GFP_KERNEL); | ||
25 | if (!buf) | ||
26 | return -ENOMEM; | ||
27 | |||
28 | if (action == CTL_READ) { | ||
29 | buf[0] = 0x01; /* AV/C, STATUS */ | ||
30 | response_ok = 0x0c; /* STABLE */ | ||
31 | } else { | ||
32 | buf[0] = 0x00; /* AV/C, CONTROL */ | ||
33 | response_ok = 0x09; /* ACCEPTED */ | ||
34 | } | ||
35 | buf[1] = 0x08; /* audio unit 0 */ | ||
36 | buf[2] = 0xb8; /* FUNCTION BLOCK */ | ||
37 | buf[3] = 0x81; /* function block type: feature */ | ||
38 | buf[4] = oxfw->device_info->mute_fb_id; /* function block ID */ | ||
39 | buf[5] = 0x10; /* control attribute: current */ | ||
40 | buf[6] = 0x02; /* selector length */ | ||
41 | buf[7] = 0x00; /* audio channel number */ | ||
42 | buf[8] = 0x01; /* control selector: mute */ | ||
43 | buf[9] = 0x01; /* control data length */ | ||
44 | if (action == CTL_READ) | ||
45 | buf[10] = 0xff; | ||
46 | else | ||
47 | buf[10] = *value ? 0x70 : 0x60; | ||
48 | |||
49 | err = fcp_avc_transaction(oxfw->unit, buf, 11, buf, 11, 0x3fe); | ||
50 | if (err < 0) | ||
51 | goto error; | ||
52 | if (err < 11) { | ||
53 | dev_err(&oxfw->unit->device, "short FCP response\n"); | ||
54 | err = -EIO; | ||
55 | goto error; | ||
56 | } | ||
57 | if (buf[0] != response_ok) { | ||
58 | dev_err(&oxfw->unit->device, "mute command failed\n"); | ||
59 | err = -EIO; | ||
60 | goto error; | ||
61 | } | ||
62 | if (action == CTL_READ) | ||
63 | *value = buf[10] == 0x70; | ||
64 | |||
65 | err = 0; | ||
66 | |||
67 | error: | ||
68 | kfree(buf); | ||
69 | |||
70 | return err; | ||
71 | } | ||
72 | |||
73 | static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value, | ||
74 | unsigned int channel, | ||
75 | enum control_attribute attribute, | ||
76 | enum control_action action) | ||
77 | { | ||
78 | u8 *buf; | ||
79 | u8 response_ok; | ||
80 | int err; | ||
81 | |||
82 | buf = kmalloc(12, GFP_KERNEL); | ||
83 | if (!buf) | ||
84 | return -ENOMEM; | ||
85 | |||
86 | if (action == CTL_READ) { | ||
87 | buf[0] = 0x01; /* AV/C, STATUS */ | ||
88 | response_ok = 0x0c; /* STABLE */ | ||
89 | } else { | ||
90 | buf[0] = 0x00; /* AV/C, CONTROL */ | ||
91 | response_ok = 0x09; /* ACCEPTED */ | ||
92 | } | ||
93 | buf[1] = 0x08; /* audio unit 0 */ | ||
94 | buf[2] = 0xb8; /* FUNCTION BLOCK */ | ||
95 | buf[3] = 0x81; /* function block type: feature */ | ||
96 | buf[4] = oxfw->device_info->volume_fb_id; /* function block ID */ | ||
97 | buf[5] = attribute; /* control attribute */ | ||
98 | buf[6] = 0x02; /* selector length */ | ||
99 | buf[7] = channel; /* audio channel number */ | ||
100 | buf[8] = 0x02; /* control selector: volume */ | ||
101 | buf[9] = 0x02; /* control data length */ | ||
102 | if (action == CTL_READ) { | ||
103 | buf[10] = 0xff; | ||
104 | buf[11] = 0xff; | ||
105 | } else { | ||
106 | buf[10] = *value >> 8; | ||
107 | buf[11] = *value; | ||
108 | } | ||
109 | |||
110 | err = fcp_avc_transaction(oxfw->unit, buf, 12, buf, 12, 0x3fe); | ||
111 | if (err < 0) | ||
112 | goto error; | ||
113 | if (err < 12) { | ||
114 | dev_err(&oxfw->unit->device, "short FCP response\n"); | ||
115 | err = -EIO; | ||
116 | goto error; | ||
117 | } | ||
118 | if (buf[0] != response_ok) { | ||
119 | dev_err(&oxfw->unit->device, "volume command failed\n"); | ||
120 | err = -EIO; | ||
121 | goto error; | ||
122 | } | ||
123 | if (action == CTL_READ) | ||
124 | *value = (buf[10] << 8) | buf[11]; | ||
125 | |||
126 | err = 0; | ||
127 | |||
128 | error: | ||
129 | kfree(buf); | ||
130 | |||
131 | return err; | ||
132 | } | ||
133 | |||
134 | static int oxfw_mute_get(struct snd_kcontrol *control, | ||
135 | struct snd_ctl_elem_value *value) | ||
136 | { | ||
137 | struct snd_oxfw *oxfw = control->private_data; | ||
138 | |||
139 | value->value.integer.value[0] = !oxfw->mute; | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int oxfw_mute_put(struct snd_kcontrol *control, | ||
145 | struct snd_ctl_elem_value *value) | ||
146 | { | ||
147 | struct snd_oxfw *oxfw = control->private_data; | ||
148 | bool mute; | ||
149 | int err; | ||
150 | |||
151 | mute = !value->value.integer.value[0]; | ||
152 | |||
153 | if (mute == oxfw->mute) | ||
154 | return 0; | ||
155 | |||
156 | err = oxfw_mute_command(oxfw, &mute, CTL_WRITE); | ||
157 | if (err < 0) | ||
158 | return err; | ||
159 | oxfw->mute = mute; | ||
160 | |||
161 | return 1; | ||
162 | } | ||
163 | |||
164 | static int oxfw_volume_info(struct snd_kcontrol *control, | ||
165 | struct snd_ctl_elem_info *info) | ||
166 | { | ||
167 | struct snd_oxfw *oxfw = control->private_data; | ||
168 | |||
169 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
170 | info->count = oxfw->device_info->mixer_channels; | ||
171 | info->value.integer.min = oxfw->volume_min; | ||
172 | info->value.integer.max = oxfw->volume_max; | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 }; | ||
178 | |||
179 | static int oxfw_volume_get(struct snd_kcontrol *control, | ||
180 | struct snd_ctl_elem_value *value) | ||
181 | { | ||
182 | struct snd_oxfw *oxfw = control->private_data; | ||
183 | unsigned int i; | ||
184 | |||
185 | for (i = 0; i < oxfw->device_info->mixer_channels; ++i) | ||
186 | value->value.integer.value[channel_map[i]] = oxfw->volume[i]; | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static int oxfw_volume_put(struct snd_kcontrol *control, | ||
192 | struct snd_ctl_elem_value *value) | ||
193 | { | ||
194 | struct snd_oxfw *oxfw = control->private_data; | ||
195 | unsigned int i, changed_channels; | ||
196 | bool equal_values = true; | ||
197 | s16 volume; | ||
198 | int err; | ||
199 | |||
200 | for (i = 0; i < oxfw->device_info->mixer_channels; ++i) { | ||
201 | if (value->value.integer.value[i] < oxfw->volume_min || | ||
202 | value->value.integer.value[i] > oxfw->volume_max) | ||
203 | return -EINVAL; | ||
204 | if (value->value.integer.value[i] != | ||
205 | value->value.integer.value[0]) | ||
206 | equal_values = false; | ||
207 | } | ||
208 | |||
209 | changed_channels = 0; | ||
210 | for (i = 0; i < oxfw->device_info->mixer_channels; ++i) | ||
211 | if (value->value.integer.value[channel_map[i]] != | ||
212 | oxfw->volume[i]) | ||
213 | changed_channels |= 1 << (i + 1); | ||
214 | |||
215 | if (equal_values && changed_channels != 0) | ||
216 | changed_channels = 1 << 0; | ||
217 | |||
218 | for (i = 0; i <= oxfw->device_info->mixer_channels; ++i) { | ||
219 | volume = value->value.integer.value[channel_map[i ? i - 1 : 0]]; | ||
220 | if (changed_channels & (1 << i)) { | ||
221 | err = oxfw_volume_command(oxfw, &volume, i, | ||
222 | CTL_CURRENT, CTL_WRITE); | ||
223 | if (err < 0) | ||
224 | return err; | ||
225 | } | ||
226 | if (i > 0) | ||
227 | oxfw->volume[i - 1] = volume; | ||
228 | } | ||
229 | |||
230 | return changed_channels != 0; | ||
231 | } | ||
232 | |||
233 | int snd_oxfw_create_mixer(struct snd_oxfw *oxfw) | ||
234 | { | ||
235 | static const struct snd_kcontrol_new controls[] = { | ||
236 | { | ||
237 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
238 | .name = "PCM Playback Switch", | ||
239 | .info = snd_ctl_boolean_mono_info, | ||
240 | .get = oxfw_mute_get, | ||
241 | .put = oxfw_mute_put, | ||
242 | }, | ||
243 | { | ||
244 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
245 | .name = "PCM Playback Volume", | ||
246 | .info = oxfw_volume_info, | ||
247 | .get = oxfw_volume_get, | ||
248 | .put = oxfw_volume_put, | ||
249 | }, | ||
250 | }; | ||
251 | unsigned int i, first_ch; | ||
252 | int err; | ||
253 | |||
254 | err = oxfw_volume_command(oxfw, &oxfw->volume_min, | ||
255 | 0, CTL_MIN, CTL_READ); | ||
256 | if (err < 0) | ||
257 | return err; | ||
258 | err = oxfw_volume_command(oxfw, &oxfw->volume_max, | ||
259 | 0, CTL_MAX, CTL_READ); | ||
260 | if (err < 0) | ||
261 | return err; | ||
262 | |||
263 | err = oxfw_mute_command(oxfw, &oxfw->mute, CTL_READ); | ||
264 | if (err < 0) | ||
265 | return err; | ||
266 | |||
267 | first_ch = oxfw->device_info->mixer_channels == 1 ? 0 : 1; | ||
268 | for (i = 0; i < oxfw->device_info->mixer_channels; ++i) { | ||
269 | err = oxfw_volume_command(oxfw, &oxfw->volume[i], | ||
270 | first_ch + i, CTL_CURRENT, CTL_READ); | ||
271 | if (err < 0) | ||
272 | return err; | ||
273 | } | ||
274 | |||
275 | for (i = 0; i < ARRAY_SIZE(controls); ++i) { | ||
276 | err = snd_ctl_add(oxfw->card, | ||
277 | snd_ctl_new1(&controls[i], oxfw)); | ||
278 | if (err < 0) | ||
279 | return err; | ||
280 | } | ||
281 | |||
282 | return 0; | ||
283 | } | ||
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c new file mode 100644 index 000000000000..d39f17a8f8c0 --- /dev/null +++ b/sound/firewire/oxfw/oxfw-pcm.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* | ||
2 | * oxfw_pcm.c - a part of driver for OXFW970/971 based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include "oxfw.h" | ||
9 | |||
10 | static int firewave_rate_constraint(struct snd_pcm_hw_params *params, | ||
11 | struct snd_pcm_hw_rule *rule) | ||
12 | { | ||
13 | static unsigned int stereo_rates[] = { 48000, 96000 }; | ||
14 | struct snd_interval *channels = | ||
15 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
16 | struct snd_interval *rate = | ||
17 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
18 | |||
19 | /* two channels work only at 48/96 kHz */ | ||
20 | if (snd_interval_max(channels) < 6) | ||
21 | return snd_interval_list(rate, 2, stereo_rates, 0); | ||
22 | return 0; | ||
23 | } | ||
24 | |||
25 | static int firewave_channels_constraint(struct snd_pcm_hw_params *params, | ||
26 | struct snd_pcm_hw_rule *rule) | ||
27 | { | ||
28 | static const struct snd_interval all_channels = { .min = 6, .max = 6 }; | ||
29 | struct snd_interval *rate = | ||
30 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
31 | struct snd_interval *channels = | ||
32 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
33 | |||
34 | /* 32/44.1 kHz work only with all six channels */ | ||
35 | if (snd_interval_max(rate) < 48000) | ||
36 | return snd_interval_refine(channels, &all_channels); | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | int firewave_constraints(struct snd_pcm_runtime *runtime) | ||
41 | { | ||
42 | static unsigned int channels_list[] = { 2, 6 }; | ||
43 | static struct snd_pcm_hw_constraint_list channels_list_constraint = { | ||
44 | .count = 2, | ||
45 | .list = channels_list, | ||
46 | }; | ||
47 | int err; | ||
48 | |||
49 | runtime->hw.rates = SNDRV_PCM_RATE_32000 | | ||
50 | SNDRV_PCM_RATE_44100 | | ||
51 | SNDRV_PCM_RATE_48000 | | ||
52 | SNDRV_PCM_RATE_96000; | ||
53 | runtime->hw.channels_max = 6; | ||
54 | |||
55 | err = snd_pcm_hw_constraint_list(runtime, 0, | ||
56 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
57 | &channels_list_constraint); | ||
58 | if (err < 0) | ||
59 | return err; | ||
60 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
61 | firewave_rate_constraint, NULL, | ||
62 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
63 | if (err < 0) | ||
64 | return err; | ||
65 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
66 | firewave_channels_constraint, NULL, | ||
67 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
68 | if (err < 0) | ||
69 | return err; | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int lacie_speakers_constraints(struct snd_pcm_runtime *runtime) | ||
75 | { | ||
76 | runtime->hw.rates = SNDRV_PCM_RATE_32000 | | ||
77 | SNDRV_PCM_RATE_44100 | | ||
78 | SNDRV_PCM_RATE_48000 | | ||
79 | SNDRV_PCM_RATE_88200 | | ||
80 | SNDRV_PCM_RATE_96000; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int pcm_open(struct snd_pcm_substream *substream) | ||
86 | { | ||
87 | static const struct snd_pcm_hardware hardware = { | ||
88 | .info = SNDRV_PCM_INFO_MMAP | | ||
89 | SNDRV_PCM_INFO_MMAP_VALID | | ||
90 | SNDRV_PCM_INFO_BATCH | | ||
91 | SNDRV_PCM_INFO_INTERLEAVED | | ||
92 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
93 | .formats = AMDTP_OUT_PCM_FORMAT_BITS, | ||
94 | .channels_min = 2, | ||
95 | .channels_max = 2, | ||
96 | .buffer_bytes_max = 4 * 1024 * 1024, | ||
97 | .period_bytes_min = 1, | ||
98 | .period_bytes_max = UINT_MAX, | ||
99 | .periods_min = 1, | ||
100 | .periods_max = UINT_MAX, | ||
101 | }; | ||
102 | struct snd_oxfw *oxfw = substream->private_data; | ||
103 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
104 | bool used; | ||
105 | int err; | ||
106 | |||
107 | err = cmp_connection_check_used(&oxfw->in_conn, &used); | ||
108 | if ((err < 0) || used) | ||
109 | goto end; | ||
110 | |||
111 | runtime->hw = hardware; | ||
112 | |||
113 | err = oxfw->device_info->pcm_constraints(runtime); | ||
114 | if (err < 0) | ||
115 | goto end; | ||
116 | err = snd_pcm_limit_hw_rates(runtime); | ||
117 | if (err < 0) | ||
118 | goto end; | ||
119 | |||
120 | err = amdtp_stream_add_pcm_hw_constraints(&oxfw->rx_stream, runtime); | ||
121 | end: | ||
122 | return err; | ||
123 | } | ||
124 | |||
125 | static int pcm_close(struct snd_pcm_substream *substream) | ||
126 | { | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int pcm_hw_params(struct snd_pcm_substream *substream, | ||
131 | struct snd_pcm_hw_params *hw_params) | ||
132 | { | ||
133 | struct snd_oxfw *oxfw = substream->private_data; | ||
134 | int err; | ||
135 | |||
136 | mutex_lock(&oxfw->mutex); | ||
137 | |||
138 | snd_oxfw_stream_stop_simplex(oxfw); | ||
139 | |||
140 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
141 | params_buffer_bytes(hw_params)); | ||
142 | if (err < 0) | ||
143 | goto error; | ||
144 | |||
145 | amdtp_stream_set_parameters(&oxfw->rx_stream, | ||
146 | params_rate(hw_params), | ||
147 | params_channels(hw_params), | ||
148 | 0); | ||
149 | |||
150 | amdtp_stream_set_pcm_format(&oxfw->rx_stream, | ||
151 | params_format(hw_params)); | ||
152 | |||
153 | err = avc_general_set_sig_fmt(oxfw->unit, params_rate(hw_params), | ||
154 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
155 | if (err < 0) { | ||
156 | dev_err(&oxfw->unit->device, "failed to set sample rate\n"); | ||
157 | goto err_buffer; | ||
158 | } | ||
159 | |||
160 | return 0; | ||
161 | |||
162 | err_buffer: | ||
163 | snd_pcm_lib_free_vmalloc_buffer(substream); | ||
164 | error: | ||
165 | mutex_unlock(&oxfw->mutex); | ||
166 | return err; | ||
167 | } | ||
168 | |||
169 | static int pcm_hw_free(struct snd_pcm_substream *substream) | ||
170 | { | ||
171 | struct snd_oxfw *oxfw = substream->private_data; | ||
172 | |||
173 | mutex_lock(&oxfw->mutex); | ||
174 | snd_oxfw_stream_stop_simplex(oxfw); | ||
175 | mutex_unlock(&oxfw->mutex); | ||
176 | |||
177 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
178 | } | ||
179 | |||
180 | static int pcm_prepare(struct snd_pcm_substream *substream) | ||
181 | { | ||
182 | struct snd_oxfw *oxfw = substream->private_data; | ||
183 | int err; | ||
184 | |||
185 | mutex_lock(&oxfw->mutex); | ||
186 | |||
187 | snd_oxfw_stream_stop_simplex(oxfw); | ||
188 | |||
189 | err = snd_oxfw_stream_start_simplex(oxfw); | ||
190 | if (err < 0) | ||
191 | goto end; | ||
192 | |||
193 | amdtp_stream_pcm_prepare(&oxfw->rx_stream); | ||
194 | end: | ||
195 | mutex_unlock(&oxfw->mutex); | ||
196 | return err; | ||
197 | } | ||
198 | |||
199 | static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
200 | { | ||
201 | struct snd_oxfw *oxfw = substream->private_data; | ||
202 | struct snd_pcm_substream *pcm; | ||
203 | |||
204 | switch (cmd) { | ||
205 | case SNDRV_PCM_TRIGGER_START: | ||
206 | pcm = substream; | ||
207 | break; | ||
208 | case SNDRV_PCM_TRIGGER_STOP: | ||
209 | pcm = NULL; | ||
210 | break; | ||
211 | default: | ||
212 | return -EINVAL; | ||
213 | } | ||
214 | amdtp_stream_pcm_trigger(&oxfw->rx_stream, pcm); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) | ||
219 | { | ||
220 | struct snd_oxfw *oxfw = substream->private_data; | ||
221 | |||
222 | return amdtp_stream_pcm_pointer(&oxfw->rx_stream); | ||
223 | } | ||
224 | |||
225 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) | ||
226 | { | ||
227 | static struct snd_pcm_ops ops = { | ||
228 | .open = pcm_open, | ||
229 | .close = pcm_close, | ||
230 | .ioctl = snd_pcm_lib_ioctl, | ||
231 | .hw_params = pcm_hw_params, | ||
232 | .hw_free = pcm_hw_free, | ||
233 | .prepare = pcm_prepare, | ||
234 | .trigger = pcm_trigger, | ||
235 | .pointer = pcm_pointer, | ||
236 | .page = snd_pcm_lib_get_vmalloc_page, | ||
237 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
238 | }; | ||
239 | struct snd_pcm *pcm; | ||
240 | int err; | ||
241 | |||
242 | err = snd_pcm_new(oxfw->card, oxfw->card->driver, 0, 1, 0, &pcm); | ||
243 | if (err < 0) | ||
244 | return err; | ||
245 | pcm->private_data = oxfw; | ||
246 | strcpy(pcm->name, oxfw->card->shortname); | ||
247 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops); | ||
248 | return 0; | ||
249 | } | ||
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c new file mode 100644 index 000000000000..ebd156f3e29d --- /dev/null +++ b/sound/firewire/oxfw/oxfw-stream.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * oxfw_stream.c - a part of driver for OXFW970/971 based devices | ||
3 | * | ||
4 | * Copyright (c) 2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "oxfw.h" | ||
10 | |||
11 | int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw) | ||
12 | { | ||
13 | int err; | ||
14 | |||
15 | err = cmp_connection_init(&oxfw->in_conn, oxfw->unit, | ||
16 | CMP_INPUT, 0); | ||
17 | if (err < 0) | ||
18 | goto end; | ||
19 | |||
20 | err = amdtp_stream_init(&oxfw->rx_stream, oxfw->unit, | ||
21 | AMDTP_OUT_STREAM, CIP_NONBLOCKING); | ||
22 | if (err < 0) { | ||
23 | amdtp_stream_destroy(&oxfw->rx_stream); | ||
24 | cmp_connection_destroy(&oxfw->in_conn); | ||
25 | } | ||
26 | end: | ||
27 | return err; | ||
28 | } | ||
29 | |||
30 | static void stop_stream(struct snd_oxfw *oxfw) | ||
31 | { | ||
32 | amdtp_stream_pcm_abort(&oxfw->rx_stream); | ||
33 | amdtp_stream_stop(&oxfw->rx_stream); | ||
34 | cmp_connection_break(&oxfw->in_conn); | ||
35 | } | ||
36 | |||
37 | int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw) | ||
38 | { | ||
39 | int err = 0; | ||
40 | |||
41 | if (amdtp_streaming_error(&oxfw->rx_stream)) | ||
42 | stop_stream(oxfw); | ||
43 | |||
44 | if (amdtp_stream_running(&oxfw->rx_stream)) | ||
45 | goto end; | ||
46 | |||
47 | err = cmp_connection_establish(&oxfw->in_conn, | ||
48 | amdtp_stream_get_max_payload(&oxfw->rx_stream)); | ||
49 | if (err < 0) | ||
50 | goto end; | ||
51 | |||
52 | err = amdtp_stream_start(&oxfw->rx_stream, | ||
53 | oxfw->in_conn.resources.channel, | ||
54 | oxfw->in_conn.speed); | ||
55 | if (err < 0) | ||
56 | stop_stream(oxfw); | ||
57 | end: | ||
58 | return err; | ||
59 | } | ||
60 | |||
61 | void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw) | ||
62 | { | ||
63 | stop_stream(oxfw); | ||
64 | } | ||
65 | |||
66 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw) | ||
67 | { | ||
68 | stop_stream(oxfw); | ||
69 | |||
70 | amdtp_stream_destroy(&oxfw->rx_stream); | ||
71 | cmp_connection_destroy(&oxfw->in_conn); | ||
72 | } | ||
73 | |||
74 | void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw) | ||
75 | { | ||
76 | if (cmp_connection_update(&oxfw->in_conn) < 0) | ||
77 | stop_stream(oxfw); | ||
78 | else | ||
79 | amdtp_stream_update(&oxfw->rx_stream); | ||
80 | } | ||
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c new file mode 100644 index 000000000000..951d9a4e2102 --- /dev/null +++ b/sound/firewire/oxfw/oxfw.c | |||
@@ -0,0 +1,194 @@ | |||
1 | /* | ||
2 | * oxfw.c - a part of driver for OXFW970/971 based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include "oxfw.h" | ||
9 | |||
10 | #define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000) | ||
11 | /* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */ | ||
12 | |||
13 | #define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020) | ||
14 | #define OXFORD_HARDWARE_ID_OXFW970 0x39443841 | ||
15 | #define OXFORD_HARDWARE_ID_OXFW971 0x39373100 | ||
16 | |||
17 | #define VENDOR_GRIFFIN 0x001292 | ||
18 | #define VENDOR_LACIE 0x00d04b | ||
19 | |||
20 | #define SPECIFIER_1394TA 0x00a02d | ||
21 | #define VERSION_AVC 0x010001 | ||
22 | |||
23 | MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver"); | ||
24 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
25 | MODULE_LICENSE("GPL v2"); | ||
26 | MODULE_ALIAS("snd-firewire-speakers"); | ||
27 | |||
28 | static u32 oxfw_read_firmware_version(struct fw_unit *unit) | ||
29 | { | ||
30 | __be32 data; | ||
31 | int err; | ||
32 | |||
33 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | ||
34 | OXFORD_FIRMWARE_ID_ADDRESS, &data, 4, 0); | ||
35 | return err >= 0 ? be32_to_cpu(data) : 0; | ||
36 | } | ||
37 | |||
38 | static void oxfw_card_free(struct snd_card *card) | ||
39 | { | ||
40 | struct snd_oxfw *oxfw = card->private_data; | ||
41 | |||
42 | mutex_destroy(&oxfw->mutex); | ||
43 | } | ||
44 | |||
45 | static int oxfw_probe(struct fw_unit *unit, | ||
46 | const struct ieee1394_device_id *id) | ||
47 | { | ||
48 | struct fw_device *fw_dev = fw_parent_device(unit); | ||
49 | struct snd_card *card; | ||
50 | struct snd_oxfw *oxfw; | ||
51 | u32 firmware; | ||
52 | int err; | ||
53 | |||
54 | err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, | ||
55 | sizeof(*oxfw), &card); | ||
56 | if (err < 0) | ||
57 | return err; | ||
58 | |||
59 | card->private_free = oxfw_card_free; | ||
60 | oxfw = card->private_data; | ||
61 | oxfw->card = card; | ||
62 | mutex_init(&oxfw->mutex); | ||
63 | oxfw->unit = unit; | ||
64 | oxfw->device_info = (const struct device_info *)id->driver_data; | ||
65 | |||
66 | strcpy(card->driver, oxfw->device_info->driver_name); | ||
67 | strcpy(card->shortname, oxfw->device_info->short_name); | ||
68 | firmware = oxfw_read_firmware_version(unit); | ||
69 | snprintf(card->longname, sizeof(card->longname), | ||
70 | "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d", | ||
71 | oxfw->device_info->long_name, | ||
72 | firmware >> 20, firmware & 0xffff, | ||
73 | fw_dev->config_rom[3], fw_dev->config_rom[4], | ||
74 | dev_name(&unit->device), 100 << fw_dev->max_speed); | ||
75 | strcpy(card->mixername, "OXFW"); | ||
76 | |||
77 | err = snd_oxfw_create_pcm(oxfw); | ||
78 | if (err < 0) | ||
79 | goto error; | ||
80 | |||
81 | err = snd_oxfw_create_mixer(oxfw); | ||
82 | if (err < 0) | ||
83 | goto error; | ||
84 | |||
85 | err = snd_oxfw_stream_init_simplex(oxfw); | ||
86 | if (err < 0) | ||
87 | goto error; | ||
88 | |||
89 | err = snd_card_register(card); | ||
90 | if (err < 0) { | ||
91 | snd_oxfw_stream_destroy_simplex(oxfw); | ||
92 | goto error; | ||
93 | } | ||
94 | dev_set_drvdata(&unit->device, oxfw); | ||
95 | |||
96 | return 0; | ||
97 | error: | ||
98 | snd_card_free(card); | ||
99 | return err; | ||
100 | } | ||
101 | |||
102 | static void oxfw_bus_reset(struct fw_unit *unit) | ||
103 | { | ||
104 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); | ||
105 | |||
106 | fcp_bus_reset(oxfw->unit); | ||
107 | |||
108 | mutex_lock(&oxfw->mutex); | ||
109 | snd_oxfw_stream_update_simplex(oxfw); | ||
110 | mutex_unlock(&oxfw->mutex); | ||
111 | } | ||
112 | |||
113 | static void oxfw_remove(struct fw_unit *unit) | ||
114 | { | ||
115 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); | ||
116 | |||
117 | snd_card_disconnect(oxfw->card); | ||
118 | |||
119 | snd_oxfw_stream_destroy_simplex(oxfw); | ||
120 | |||
121 | snd_card_free_when_closed(oxfw->card); | ||
122 | } | ||
123 | |||
124 | static const struct device_info griffin_firewave = { | ||
125 | .driver_name = "FireWave", | ||
126 | .short_name = "FireWave", | ||
127 | .long_name = "Griffin FireWave Surround", | ||
128 | .pcm_constraints = firewave_constraints, | ||
129 | .mixer_channels = 6, | ||
130 | .mute_fb_id = 0x01, | ||
131 | .volume_fb_id = 0x02, | ||
132 | }; | ||
133 | |||
134 | static const struct device_info lacie_speakers = { | ||
135 | .driver_name = "FWSpeakers", | ||
136 | .short_name = "FireWire Speakers", | ||
137 | .long_name = "LaCie FireWire Speakers", | ||
138 | .pcm_constraints = lacie_speakers_constraints, | ||
139 | .mixer_channels = 1, | ||
140 | .mute_fb_id = 0x01, | ||
141 | .volume_fb_id = 0x01, | ||
142 | }; | ||
143 | |||
144 | static const struct ieee1394_device_id oxfw_id_table[] = { | ||
145 | { | ||
146 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
147 | IEEE1394_MATCH_MODEL_ID | | ||
148 | IEEE1394_MATCH_SPECIFIER_ID | | ||
149 | IEEE1394_MATCH_VERSION, | ||
150 | .vendor_id = VENDOR_GRIFFIN, | ||
151 | .model_id = 0x00f970, | ||
152 | .specifier_id = SPECIFIER_1394TA, | ||
153 | .version = VERSION_AVC, | ||
154 | .driver_data = (kernel_ulong_t)&griffin_firewave, | ||
155 | }, | ||
156 | { | ||
157 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
158 | IEEE1394_MATCH_MODEL_ID | | ||
159 | IEEE1394_MATCH_SPECIFIER_ID | | ||
160 | IEEE1394_MATCH_VERSION, | ||
161 | .vendor_id = VENDOR_LACIE, | ||
162 | .model_id = 0x00f970, | ||
163 | .specifier_id = SPECIFIER_1394TA, | ||
164 | .version = VERSION_AVC, | ||
165 | .driver_data = (kernel_ulong_t)&lacie_speakers, | ||
166 | }, | ||
167 | { } | ||
168 | }; | ||
169 | MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table); | ||
170 | |||
171 | static struct fw_driver oxfw_driver = { | ||
172 | .driver = { | ||
173 | .owner = THIS_MODULE, | ||
174 | .name = KBUILD_MODNAME, | ||
175 | .bus = &fw_bus_type, | ||
176 | }, | ||
177 | .probe = oxfw_probe, | ||
178 | .update = oxfw_bus_reset, | ||
179 | .remove = oxfw_remove, | ||
180 | .id_table = oxfw_id_table, | ||
181 | }; | ||
182 | |||
183 | static int __init snd_oxfw_init(void) | ||
184 | { | ||
185 | return driver_register(&oxfw_driver.driver); | ||
186 | } | ||
187 | |||
188 | static void __exit snd_oxfw_exit(void) | ||
189 | { | ||
190 | driver_unregister(&oxfw_driver.driver); | ||
191 | } | ||
192 | |||
193 | module_init(snd_oxfw_init); | ||
194 | module_exit(snd_oxfw_exit); | ||
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h new file mode 100644 index 000000000000..6164bf3e1f5a --- /dev/null +++ b/sound/firewire/oxfw/oxfw.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * oxfw.h - a part of driver for OXFW970/971 based devices | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/device.h> | ||
9 | #include <linux/firewire.h> | ||
10 | #include <linux/firewire-constants.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/mod_devicetable.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/slab.h> | ||
15 | |||
16 | #include <sound/control.h> | ||
17 | #include <sound/core.h> | ||
18 | #include <sound/initval.h> | ||
19 | #include <sound/pcm.h> | ||
20 | #include <sound/pcm_params.h> | ||
21 | |||
22 | #include "../lib.h" | ||
23 | #include "../fcp.h" | ||
24 | #include "../packets-buffer.h" | ||
25 | #include "../iso-resources.h" | ||
26 | #include "../amdtp.h" | ||
27 | #include "../cmp.h" | ||
28 | |||
29 | struct device_info { | ||
30 | const char *driver_name; | ||
31 | const char *short_name; | ||
32 | const char *long_name; | ||
33 | int (*pcm_constraints)(struct snd_pcm_runtime *runtime); | ||
34 | unsigned int mixer_channels; | ||
35 | u8 mute_fb_id; | ||
36 | u8 volume_fb_id; | ||
37 | }; | ||
38 | |||
39 | struct snd_oxfw { | ||
40 | struct snd_card *card; | ||
41 | struct fw_unit *unit; | ||
42 | const struct device_info *device_info; | ||
43 | struct mutex mutex; | ||
44 | struct cmp_connection in_conn; | ||
45 | struct amdtp_stream rx_stream; | ||
46 | bool mute; | ||
47 | s16 volume[6]; | ||
48 | s16 volume_min; | ||
49 | s16 volume_max; | ||
50 | }; | ||
51 | |||
52 | int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw); | ||
53 | int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw); | ||
54 | void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw); | ||
55 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw); | ||
56 | void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw); | ||
57 | |||
58 | int firewave_constraints(struct snd_pcm_runtime *runtime); | ||
59 | int lacie_speakers_constraints(struct snd_pcm_runtime *runtime); | ||
60 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw); | ||
61 | |||
62 | int snd_oxfw_create_mixer(struct snd_oxfw *oxfw); | ||
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c deleted file mode 100644 index 768d40ddfebb..000000000000 --- a/sound/firewire/speakers.c +++ /dev/null | |||
@@ -1,792 +0,0 @@ | |||
1 | /* | ||
2 | * OXFW970-based speakers driver | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/device.h> | ||
9 | #include <linux/firewire.h> | ||
10 | #include <linux/firewire-constants.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/mod_devicetable.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <sound/control.h> | ||
16 | #include <sound/core.h> | ||
17 | #include <sound/initval.h> | ||
18 | #include <sound/pcm.h> | ||
19 | #include <sound/pcm_params.h> | ||
20 | #include "cmp.h" | ||
21 | #include "fcp.h" | ||
22 | #include "amdtp.h" | ||
23 | #include "lib.h" | ||
24 | |||
25 | #define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000) | ||
26 | /* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */ | ||
27 | |||
28 | #define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020) | ||
29 | #define OXFORD_HARDWARE_ID_OXFW970 0x39443841 | ||
30 | #define OXFORD_HARDWARE_ID_OXFW971 0x39373100 | ||
31 | |||
32 | #define VENDOR_GRIFFIN 0x001292 | ||
33 | #define VENDOR_LACIE 0x00d04b | ||
34 | |||
35 | #define SPECIFIER_1394TA 0x00a02d | ||
36 | #define VERSION_AVC 0x010001 | ||
37 | |||
38 | struct device_info { | ||
39 | const char *driver_name; | ||
40 | const char *short_name; | ||
41 | const char *long_name; | ||
42 | int (*pcm_constraints)(struct snd_pcm_runtime *runtime); | ||
43 | unsigned int mixer_channels; | ||
44 | u8 mute_fb_id; | ||
45 | u8 volume_fb_id; | ||
46 | }; | ||
47 | |||
48 | struct fwspk { | ||
49 | struct snd_card *card; | ||
50 | struct fw_unit *unit; | ||
51 | const struct device_info *device_info; | ||
52 | struct mutex mutex; | ||
53 | struct cmp_connection connection; | ||
54 | struct amdtp_stream stream; | ||
55 | bool mute; | ||
56 | s16 volume[6]; | ||
57 | s16 volume_min; | ||
58 | s16 volume_max; | ||
59 | }; | ||
60 | |||
61 | MODULE_DESCRIPTION("FireWire speakers driver"); | ||
62 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
63 | MODULE_LICENSE("GPL v2"); | ||
64 | |||
65 | static int firewave_rate_constraint(struct snd_pcm_hw_params *params, | ||
66 | struct snd_pcm_hw_rule *rule) | ||
67 | { | ||
68 | static unsigned int stereo_rates[] = { 48000, 96000 }; | ||
69 | struct snd_interval *channels = | ||
70 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
71 | struct snd_interval *rate = | ||
72 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
73 | |||
74 | /* two channels work only at 48/96 kHz */ | ||
75 | if (snd_interval_max(channels) < 6) | ||
76 | return snd_interval_list(rate, 2, stereo_rates, 0); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int firewave_channels_constraint(struct snd_pcm_hw_params *params, | ||
81 | struct snd_pcm_hw_rule *rule) | ||
82 | { | ||
83 | static const struct snd_interval all_channels = { .min = 6, .max = 6 }; | ||
84 | struct snd_interval *rate = | ||
85 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
86 | struct snd_interval *channels = | ||
87 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
88 | |||
89 | /* 32/44.1 kHz work only with all six channels */ | ||
90 | if (snd_interval_max(rate) < 48000) | ||
91 | return snd_interval_refine(channels, &all_channels); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int firewave_constraints(struct snd_pcm_runtime *runtime) | ||
96 | { | ||
97 | static unsigned int channels_list[] = { 2, 6 }; | ||
98 | static struct snd_pcm_hw_constraint_list channels_list_constraint = { | ||
99 | .count = 2, | ||
100 | .list = channels_list, | ||
101 | }; | ||
102 | int err; | ||
103 | |||
104 | runtime->hw.rates = SNDRV_PCM_RATE_32000 | | ||
105 | SNDRV_PCM_RATE_44100 | | ||
106 | SNDRV_PCM_RATE_48000 | | ||
107 | SNDRV_PCM_RATE_96000; | ||
108 | runtime->hw.channels_max = 6; | ||
109 | |||
110 | err = snd_pcm_hw_constraint_list(runtime, 0, | ||
111 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
112 | &channels_list_constraint); | ||
113 | if (err < 0) | ||
114 | return err; | ||
115 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
116 | firewave_rate_constraint, NULL, | ||
117 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
118 | if (err < 0) | ||
119 | return err; | ||
120 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
121 | firewave_channels_constraint, NULL, | ||
122 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
123 | if (err < 0) | ||
124 | return err; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int lacie_speakers_constraints(struct snd_pcm_runtime *runtime) | ||
130 | { | ||
131 | runtime->hw.rates = SNDRV_PCM_RATE_32000 | | ||
132 | SNDRV_PCM_RATE_44100 | | ||
133 | SNDRV_PCM_RATE_48000 | | ||
134 | SNDRV_PCM_RATE_88200 | | ||
135 | SNDRV_PCM_RATE_96000; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int fwspk_open(struct snd_pcm_substream *substream) | ||
141 | { | ||
142 | static const struct snd_pcm_hardware hardware = { | ||
143 | .info = SNDRV_PCM_INFO_MMAP | | ||
144 | SNDRV_PCM_INFO_MMAP_VALID | | ||
145 | SNDRV_PCM_INFO_BATCH | | ||
146 | SNDRV_PCM_INFO_INTERLEAVED | | ||
147 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
148 | .formats = AMDTP_OUT_PCM_FORMAT_BITS, | ||
149 | .channels_min = 2, | ||
150 | .channels_max = 2, | ||
151 | .buffer_bytes_max = 4 * 1024 * 1024, | ||
152 | .period_bytes_min = 1, | ||
153 | .period_bytes_max = UINT_MAX, | ||
154 | .periods_min = 1, | ||
155 | .periods_max = UINT_MAX, | ||
156 | }; | ||
157 | struct fwspk *fwspk = substream->private_data; | ||
158 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
159 | int err; | ||
160 | |||
161 | runtime->hw = hardware; | ||
162 | |||
163 | err = fwspk->device_info->pcm_constraints(runtime); | ||
164 | if (err < 0) | ||
165 | return err; | ||
166 | err = snd_pcm_limit_hw_rates(runtime); | ||
167 | if (err < 0) | ||
168 | return err; | ||
169 | |||
170 | err = amdtp_stream_add_pcm_hw_constraints(&fwspk->stream, runtime); | ||
171 | if (err < 0) | ||
172 | return err; | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int fwspk_close(struct snd_pcm_substream *substream) | ||
178 | { | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static void fwspk_stop_stream(struct fwspk *fwspk) | ||
183 | { | ||
184 | if (amdtp_stream_running(&fwspk->stream)) { | ||
185 | amdtp_stream_stop(&fwspk->stream); | ||
186 | cmp_connection_break(&fwspk->connection); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static int fwspk_hw_params(struct snd_pcm_substream *substream, | ||
191 | struct snd_pcm_hw_params *hw_params) | ||
192 | { | ||
193 | struct fwspk *fwspk = substream->private_data; | ||
194 | int err; | ||
195 | |||
196 | mutex_lock(&fwspk->mutex); | ||
197 | fwspk_stop_stream(fwspk); | ||
198 | mutex_unlock(&fwspk->mutex); | ||
199 | |||
200 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
201 | params_buffer_bytes(hw_params)); | ||
202 | if (err < 0) | ||
203 | goto error; | ||
204 | |||
205 | amdtp_stream_set_parameters(&fwspk->stream, | ||
206 | params_rate(hw_params), | ||
207 | params_channels(hw_params), | ||
208 | 0); | ||
209 | |||
210 | amdtp_stream_set_pcm_format(&fwspk->stream, | ||
211 | params_format(hw_params)); | ||
212 | |||
213 | err = avc_general_set_sig_fmt(fwspk->unit, params_rate(hw_params), | ||
214 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
215 | if (err < 0) { | ||
216 | dev_err(&fwspk->unit->device, "failed to set sample rate\n"); | ||
217 | goto err_buffer; | ||
218 | } | ||
219 | |||
220 | return 0; | ||
221 | |||
222 | err_buffer: | ||
223 | snd_pcm_lib_free_vmalloc_buffer(substream); | ||
224 | error: | ||
225 | return err; | ||
226 | } | ||
227 | |||
228 | static int fwspk_hw_free(struct snd_pcm_substream *substream) | ||
229 | { | ||
230 | struct fwspk *fwspk = substream->private_data; | ||
231 | |||
232 | mutex_lock(&fwspk->mutex); | ||
233 | fwspk_stop_stream(fwspk); | ||
234 | mutex_unlock(&fwspk->mutex); | ||
235 | |||
236 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
237 | } | ||
238 | |||
239 | static int fwspk_prepare(struct snd_pcm_substream *substream) | ||
240 | { | ||
241 | struct fwspk *fwspk = substream->private_data; | ||
242 | int err; | ||
243 | |||
244 | mutex_lock(&fwspk->mutex); | ||
245 | |||
246 | if (amdtp_streaming_error(&fwspk->stream)) | ||
247 | fwspk_stop_stream(fwspk); | ||
248 | |||
249 | if (!amdtp_stream_running(&fwspk->stream)) { | ||
250 | err = cmp_connection_establish(&fwspk->connection, | ||
251 | amdtp_stream_get_max_payload(&fwspk->stream)); | ||
252 | if (err < 0) | ||
253 | goto err_mutex; | ||
254 | |||
255 | err = amdtp_stream_start(&fwspk->stream, | ||
256 | fwspk->connection.resources.channel, | ||
257 | fwspk->connection.speed); | ||
258 | if (err < 0) | ||
259 | goto err_connection; | ||
260 | } | ||
261 | |||
262 | mutex_unlock(&fwspk->mutex); | ||
263 | |||
264 | amdtp_stream_pcm_prepare(&fwspk->stream); | ||
265 | |||
266 | return 0; | ||
267 | |||
268 | err_connection: | ||
269 | cmp_connection_break(&fwspk->connection); | ||
270 | err_mutex: | ||
271 | mutex_unlock(&fwspk->mutex); | ||
272 | |||
273 | return err; | ||
274 | } | ||
275 | |||
276 | static int fwspk_trigger(struct snd_pcm_substream *substream, int cmd) | ||
277 | { | ||
278 | struct fwspk *fwspk = substream->private_data; | ||
279 | struct snd_pcm_substream *pcm; | ||
280 | |||
281 | switch (cmd) { | ||
282 | case SNDRV_PCM_TRIGGER_START: | ||
283 | pcm = substream; | ||
284 | break; | ||
285 | case SNDRV_PCM_TRIGGER_STOP: | ||
286 | pcm = NULL; | ||
287 | break; | ||
288 | default: | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | amdtp_stream_pcm_trigger(&fwspk->stream, pcm); | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static snd_pcm_uframes_t fwspk_pointer(struct snd_pcm_substream *substream) | ||
296 | { | ||
297 | struct fwspk *fwspk = substream->private_data; | ||
298 | |||
299 | return amdtp_stream_pcm_pointer(&fwspk->stream); | ||
300 | } | ||
301 | |||
302 | static int fwspk_create_pcm(struct fwspk *fwspk) | ||
303 | { | ||
304 | static struct snd_pcm_ops ops = { | ||
305 | .open = fwspk_open, | ||
306 | .close = fwspk_close, | ||
307 | .ioctl = snd_pcm_lib_ioctl, | ||
308 | .hw_params = fwspk_hw_params, | ||
309 | .hw_free = fwspk_hw_free, | ||
310 | .prepare = fwspk_prepare, | ||
311 | .trigger = fwspk_trigger, | ||
312 | .pointer = fwspk_pointer, | ||
313 | .page = snd_pcm_lib_get_vmalloc_page, | ||
314 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
315 | }; | ||
316 | struct snd_pcm *pcm; | ||
317 | int err; | ||
318 | |||
319 | err = snd_pcm_new(fwspk->card, "OXFW970", 0, 1, 0, &pcm); | ||
320 | if (err < 0) | ||
321 | return err; | ||
322 | pcm->private_data = fwspk; | ||
323 | strcpy(pcm->name, fwspk->device_info->short_name); | ||
324 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | enum control_action { CTL_READ, CTL_WRITE }; | ||
329 | enum control_attribute { | ||
330 | CTL_MIN = 0x02, | ||
331 | CTL_MAX = 0x03, | ||
332 | CTL_CURRENT = 0x10, | ||
333 | }; | ||
334 | |||
335 | static int fwspk_mute_command(struct fwspk *fwspk, bool *value, | ||
336 | enum control_action action) | ||
337 | { | ||
338 | u8 *buf; | ||
339 | u8 response_ok; | ||
340 | int err; | ||
341 | |||
342 | buf = kmalloc(11, GFP_KERNEL); | ||
343 | if (!buf) | ||
344 | return -ENOMEM; | ||
345 | |||
346 | if (action == CTL_READ) { | ||
347 | buf[0] = 0x01; /* AV/C, STATUS */ | ||
348 | response_ok = 0x0c; /* STABLE */ | ||
349 | } else { | ||
350 | buf[0] = 0x00; /* AV/C, CONTROL */ | ||
351 | response_ok = 0x09; /* ACCEPTED */ | ||
352 | } | ||
353 | buf[1] = 0x08; /* audio unit 0 */ | ||
354 | buf[2] = 0xb8; /* FUNCTION BLOCK */ | ||
355 | buf[3] = 0x81; /* function block type: feature */ | ||
356 | buf[4] = fwspk->device_info->mute_fb_id; /* function block ID */ | ||
357 | buf[5] = 0x10; /* control attribute: current */ | ||
358 | buf[6] = 0x02; /* selector length */ | ||
359 | buf[7] = 0x00; /* audio channel number */ | ||
360 | buf[8] = 0x01; /* control selector: mute */ | ||
361 | buf[9] = 0x01; /* control data length */ | ||
362 | if (action == CTL_READ) | ||
363 | buf[10] = 0xff; | ||
364 | else | ||
365 | buf[10] = *value ? 0x70 : 0x60; | ||
366 | |||
367 | err = fcp_avc_transaction(fwspk->unit, buf, 11, buf, 11, 0x3fe); | ||
368 | if (err < 0) | ||
369 | goto error; | ||
370 | if (err < 11) { | ||
371 | dev_err(&fwspk->unit->device, "short FCP response\n"); | ||
372 | err = -EIO; | ||
373 | goto error; | ||
374 | } | ||
375 | if (buf[0] != response_ok) { | ||
376 | dev_err(&fwspk->unit->device, "mute command failed\n"); | ||
377 | err = -EIO; | ||
378 | goto error; | ||
379 | } | ||
380 | if (action == CTL_READ) | ||
381 | *value = buf[10] == 0x70; | ||
382 | |||
383 | err = 0; | ||
384 | |||
385 | error: | ||
386 | kfree(buf); | ||
387 | |||
388 | return err; | ||
389 | } | ||
390 | |||
391 | static int fwspk_volume_command(struct fwspk *fwspk, s16 *value, | ||
392 | unsigned int channel, | ||
393 | enum control_attribute attribute, | ||
394 | enum control_action action) | ||
395 | { | ||
396 | u8 *buf; | ||
397 | u8 response_ok; | ||
398 | int err; | ||
399 | |||
400 | buf = kmalloc(12, GFP_KERNEL); | ||
401 | if (!buf) | ||
402 | return -ENOMEM; | ||
403 | |||
404 | if (action == CTL_READ) { | ||
405 | buf[0] = 0x01; /* AV/C, STATUS */ | ||
406 | response_ok = 0x0c; /* STABLE */ | ||
407 | } else { | ||
408 | buf[0] = 0x00; /* AV/C, CONTROL */ | ||
409 | response_ok = 0x09; /* ACCEPTED */ | ||
410 | } | ||
411 | buf[1] = 0x08; /* audio unit 0 */ | ||
412 | buf[2] = 0xb8; /* FUNCTION BLOCK */ | ||
413 | buf[3] = 0x81; /* function block type: feature */ | ||
414 | buf[4] = fwspk->device_info->volume_fb_id; /* function block ID */ | ||
415 | buf[5] = attribute; /* control attribute */ | ||
416 | buf[6] = 0x02; /* selector length */ | ||
417 | buf[7] = channel; /* audio channel number */ | ||
418 | buf[8] = 0x02; /* control selector: volume */ | ||
419 | buf[9] = 0x02; /* control data length */ | ||
420 | if (action == CTL_READ) { | ||
421 | buf[10] = 0xff; | ||
422 | buf[11] = 0xff; | ||
423 | } else { | ||
424 | buf[10] = *value >> 8; | ||
425 | buf[11] = *value; | ||
426 | } | ||
427 | |||
428 | err = fcp_avc_transaction(fwspk->unit, buf, 12, buf, 12, 0x3fe); | ||
429 | if (err < 0) | ||
430 | goto error; | ||
431 | if (err < 12) { | ||
432 | dev_err(&fwspk->unit->device, "short FCP response\n"); | ||
433 | err = -EIO; | ||
434 | goto error; | ||
435 | } | ||
436 | if (buf[0] != response_ok) { | ||
437 | dev_err(&fwspk->unit->device, "volume command failed\n"); | ||
438 | err = -EIO; | ||
439 | goto error; | ||
440 | } | ||
441 | if (action == CTL_READ) | ||
442 | *value = (buf[10] << 8) | buf[11]; | ||
443 | |||
444 | err = 0; | ||
445 | |||
446 | error: | ||
447 | kfree(buf); | ||
448 | |||
449 | return err; | ||
450 | } | ||
451 | |||
452 | static int fwspk_mute_get(struct snd_kcontrol *control, | ||
453 | struct snd_ctl_elem_value *value) | ||
454 | { | ||
455 | struct fwspk *fwspk = control->private_data; | ||
456 | |||
457 | value->value.integer.value[0] = !fwspk->mute; | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | static int fwspk_mute_put(struct snd_kcontrol *control, | ||
463 | struct snd_ctl_elem_value *value) | ||
464 | { | ||
465 | struct fwspk *fwspk = control->private_data; | ||
466 | bool mute; | ||
467 | int err; | ||
468 | |||
469 | mute = !value->value.integer.value[0]; | ||
470 | |||
471 | if (mute == fwspk->mute) | ||
472 | return 0; | ||
473 | |||
474 | err = fwspk_mute_command(fwspk, &mute, CTL_WRITE); | ||
475 | if (err < 0) | ||
476 | return err; | ||
477 | fwspk->mute = mute; | ||
478 | |||
479 | return 1; | ||
480 | } | ||
481 | |||
482 | static int fwspk_volume_info(struct snd_kcontrol *control, | ||
483 | struct snd_ctl_elem_info *info) | ||
484 | { | ||
485 | struct fwspk *fwspk = control->private_data; | ||
486 | |||
487 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
488 | info->count = fwspk->device_info->mixer_channels; | ||
489 | info->value.integer.min = fwspk->volume_min; | ||
490 | info->value.integer.max = fwspk->volume_max; | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 }; | ||
496 | |||
497 | static int fwspk_volume_get(struct snd_kcontrol *control, | ||
498 | struct snd_ctl_elem_value *value) | ||
499 | { | ||
500 | struct fwspk *fwspk = control->private_data; | ||
501 | unsigned int i; | ||
502 | |||
503 | for (i = 0; i < fwspk->device_info->mixer_channels; ++i) | ||
504 | value->value.integer.value[channel_map[i]] = fwspk->volume[i]; | ||
505 | |||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static int fwspk_volume_put(struct snd_kcontrol *control, | ||
510 | struct snd_ctl_elem_value *value) | ||
511 | { | ||
512 | struct fwspk *fwspk = control->private_data; | ||
513 | unsigned int i, changed_channels; | ||
514 | bool equal_values = true; | ||
515 | s16 volume; | ||
516 | int err; | ||
517 | |||
518 | for (i = 0; i < fwspk->device_info->mixer_channels; ++i) { | ||
519 | if (value->value.integer.value[i] < fwspk->volume_min || | ||
520 | value->value.integer.value[i] > fwspk->volume_max) | ||
521 | return -EINVAL; | ||
522 | if (value->value.integer.value[i] != | ||
523 | value->value.integer.value[0]) | ||
524 | equal_values = false; | ||
525 | } | ||
526 | |||
527 | changed_channels = 0; | ||
528 | for (i = 0; i < fwspk->device_info->mixer_channels; ++i) | ||
529 | if (value->value.integer.value[channel_map[i]] != | ||
530 | fwspk->volume[i]) | ||
531 | changed_channels |= 1 << (i + 1); | ||
532 | |||
533 | if (equal_values && changed_channels != 0) | ||
534 | changed_channels = 1 << 0; | ||
535 | |||
536 | for (i = 0; i <= fwspk->device_info->mixer_channels; ++i) { | ||
537 | volume = value->value.integer.value[channel_map[i ? i - 1 : 0]]; | ||
538 | if (changed_channels & (1 << i)) { | ||
539 | err = fwspk_volume_command(fwspk, &volume, i, | ||
540 | CTL_CURRENT, CTL_WRITE); | ||
541 | if (err < 0) | ||
542 | return err; | ||
543 | } | ||
544 | if (i > 0) | ||
545 | fwspk->volume[i - 1] = volume; | ||
546 | } | ||
547 | |||
548 | return changed_channels != 0; | ||
549 | } | ||
550 | |||
551 | static int fwspk_create_mixer(struct fwspk *fwspk) | ||
552 | { | ||
553 | static const struct snd_kcontrol_new controls[] = { | ||
554 | { | ||
555 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
556 | .name = "PCM Playback Switch", | ||
557 | .info = snd_ctl_boolean_mono_info, | ||
558 | .get = fwspk_mute_get, | ||
559 | .put = fwspk_mute_put, | ||
560 | }, | ||
561 | { | ||
562 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
563 | .name = "PCM Playback Volume", | ||
564 | .info = fwspk_volume_info, | ||
565 | .get = fwspk_volume_get, | ||
566 | .put = fwspk_volume_put, | ||
567 | }, | ||
568 | }; | ||
569 | unsigned int i, first_ch; | ||
570 | int err; | ||
571 | |||
572 | err = fwspk_volume_command(fwspk, &fwspk->volume_min, | ||
573 | 0, CTL_MIN, CTL_READ); | ||
574 | if (err < 0) | ||
575 | return err; | ||
576 | err = fwspk_volume_command(fwspk, &fwspk->volume_max, | ||
577 | 0, CTL_MAX, CTL_READ); | ||
578 | if (err < 0) | ||
579 | return err; | ||
580 | |||
581 | err = fwspk_mute_command(fwspk, &fwspk->mute, CTL_READ); | ||
582 | if (err < 0) | ||
583 | return err; | ||
584 | |||
585 | first_ch = fwspk->device_info->mixer_channels == 1 ? 0 : 1; | ||
586 | for (i = 0; i < fwspk->device_info->mixer_channels; ++i) { | ||
587 | err = fwspk_volume_command(fwspk, &fwspk->volume[i], | ||
588 | first_ch + i, CTL_CURRENT, CTL_READ); | ||
589 | if (err < 0) | ||
590 | return err; | ||
591 | } | ||
592 | |||
593 | for (i = 0; i < ARRAY_SIZE(controls); ++i) { | ||
594 | err = snd_ctl_add(fwspk->card, | ||
595 | snd_ctl_new1(&controls[i], fwspk)); | ||
596 | if (err < 0) | ||
597 | return err; | ||
598 | } | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | static u32 fwspk_read_firmware_version(struct fw_unit *unit) | ||
604 | { | ||
605 | __be32 data; | ||
606 | int err; | ||
607 | |||
608 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | ||
609 | OXFORD_FIRMWARE_ID_ADDRESS, &data, 4, 0); | ||
610 | return err >= 0 ? be32_to_cpu(data) : 0; | ||
611 | } | ||
612 | |||
613 | static void fwspk_card_free(struct snd_card *card) | ||
614 | { | ||
615 | struct fwspk *fwspk = card->private_data; | ||
616 | |||
617 | amdtp_stream_destroy(&fwspk->stream); | ||
618 | cmp_connection_destroy(&fwspk->connection); | ||
619 | fw_unit_put(fwspk->unit); | ||
620 | mutex_destroy(&fwspk->mutex); | ||
621 | } | ||
622 | |||
623 | static int fwspk_probe(struct fw_unit *unit, | ||
624 | const struct ieee1394_device_id *id) | ||
625 | { | ||
626 | struct fw_device *fw_dev = fw_parent_device(unit); | ||
627 | struct snd_card *card; | ||
628 | struct fwspk *fwspk; | ||
629 | u32 firmware; | ||
630 | int err; | ||
631 | |||
632 | err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, | ||
633 | sizeof(*fwspk), &card); | ||
634 | if (err < 0) | ||
635 | return err; | ||
636 | |||
637 | fwspk = card->private_data; | ||
638 | fwspk->card = card; | ||
639 | mutex_init(&fwspk->mutex); | ||
640 | fwspk->unit = fw_unit_get(unit); | ||
641 | fwspk->device_info = (const struct device_info *)id->driver_data; | ||
642 | |||
643 | err = cmp_connection_init(&fwspk->connection, unit, CMP_INPUT, 0); | ||
644 | if (err < 0) | ||
645 | goto err_unit; | ||
646 | |||
647 | err = amdtp_stream_init(&fwspk->stream, unit, AMDTP_OUT_STREAM, | ||
648 | CIP_NONBLOCKING); | ||
649 | if (err < 0) | ||
650 | goto err_connection; | ||
651 | |||
652 | card->private_free = fwspk_card_free; | ||
653 | |||
654 | strcpy(card->driver, fwspk->device_info->driver_name); | ||
655 | strcpy(card->shortname, fwspk->device_info->short_name); | ||
656 | firmware = fwspk_read_firmware_version(unit); | ||
657 | snprintf(card->longname, sizeof(card->longname), | ||
658 | "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d", | ||
659 | fwspk->device_info->long_name, | ||
660 | firmware >> 20, firmware & 0xffff, | ||
661 | fw_dev->config_rom[3], fw_dev->config_rom[4], | ||
662 | dev_name(&unit->device), 100 << fw_dev->max_speed); | ||
663 | strcpy(card->mixername, "OXFW970"); | ||
664 | |||
665 | err = fwspk_create_pcm(fwspk); | ||
666 | if (err < 0) | ||
667 | goto error; | ||
668 | |||
669 | err = fwspk_create_mixer(fwspk); | ||
670 | if (err < 0) | ||
671 | goto error; | ||
672 | |||
673 | err = snd_card_register(card); | ||
674 | if (err < 0) | ||
675 | goto error; | ||
676 | |||
677 | dev_set_drvdata(&unit->device, fwspk); | ||
678 | |||
679 | return 0; | ||
680 | |||
681 | err_connection: | ||
682 | cmp_connection_destroy(&fwspk->connection); | ||
683 | err_unit: | ||
684 | fw_unit_put(fwspk->unit); | ||
685 | mutex_destroy(&fwspk->mutex); | ||
686 | error: | ||
687 | snd_card_free(card); | ||
688 | return err; | ||
689 | } | ||
690 | |||
691 | static void fwspk_bus_reset(struct fw_unit *unit) | ||
692 | { | ||
693 | struct fwspk *fwspk = dev_get_drvdata(&unit->device); | ||
694 | |||
695 | fcp_bus_reset(fwspk->unit); | ||
696 | |||
697 | if (cmp_connection_update(&fwspk->connection) < 0) { | ||
698 | amdtp_stream_pcm_abort(&fwspk->stream); | ||
699 | mutex_lock(&fwspk->mutex); | ||
700 | fwspk_stop_stream(fwspk); | ||
701 | mutex_unlock(&fwspk->mutex); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | amdtp_stream_update(&fwspk->stream); | ||
706 | } | ||
707 | |||
708 | static void fwspk_remove(struct fw_unit *unit) | ||
709 | { | ||
710 | struct fwspk *fwspk = dev_get_drvdata(&unit->device); | ||
711 | |||
712 | amdtp_stream_pcm_abort(&fwspk->stream); | ||
713 | snd_card_disconnect(fwspk->card); | ||
714 | |||
715 | mutex_lock(&fwspk->mutex); | ||
716 | fwspk_stop_stream(fwspk); | ||
717 | mutex_unlock(&fwspk->mutex); | ||
718 | |||
719 | snd_card_free_when_closed(fwspk->card); | ||
720 | } | ||
721 | |||
722 | static const struct device_info griffin_firewave = { | ||
723 | .driver_name = "FireWave", | ||
724 | .short_name = "FireWave", | ||
725 | .long_name = "Griffin FireWave Surround", | ||
726 | .pcm_constraints = firewave_constraints, | ||
727 | .mixer_channels = 6, | ||
728 | .mute_fb_id = 0x01, | ||
729 | .volume_fb_id = 0x02, | ||
730 | }; | ||
731 | |||
732 | static const struct device_info lacie_speakers = { | ||
733 | .driver_name = "FWSpeakers", | ||
734 | .short_name = "FireWire Speakers", | ||
735 | .long_name = "LaCie FireWire Speakers", | ||
736 | .pcm_constraints = lacie_speakers_constraints, | ||
737 | .mixer_channels = 1, | ||
738 | .mute_fb_id = 0x01, | ||
739 | .volume_fb_id = 0x01, | ||
740 | }; | ||
741 | |||
742 | static const struct ieee1394_device_id fwspk_id_table[] = { | ||
743 | { | ||
744 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
745 | IEEE1394_MATCH_MODEL_ID | | ||
746 | IEEE1394_MATCH_SPECIFIER_ID | | ||
747 | IEEE1394_MATCH_VERSION, | ||
748 | .vendor_id = VENDOR_GRIFFIN, | ||
749 | .model_id = 0x00f970, | ||
750 | .specifier_id = SPECIFIER_1394TA, | ||
751 | .version = VERSION_AVC, | ||
752 | .driver_data = (kernel_ulong_t)&griffin_firewave, | ||
753 | }, | ||
754 | { | ||
755 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
756 | IEEE1394_MATCH_MODEL_ID | | ||
757 | IEEE1394_MATCH_SPECIFIER_ID | | ||
758 | IEEE1394_MATCH_VERSION, | ||
759 | .vendor_id = VENDOR_LACIE, | ||
760 | .model_id = 0x00f970, | ||
761 | .specifier_id = SPECIFIER_1394TA, | ||
762 | .version = VERSION_AVC, | ||
763 | .driver_data = (kernel_ulong_t)&lacie_speakers, | ||
764 | }, | ||
765 | { } | ||
766 | }; | ||
767 | MODULE_DEVICE_TABLE(ieee1394, fwspk_id_table); | ||
768 | |||
769 | static struct fw_driver fwspk_driver = { | ||
770 | .driver = { | ||
771 | .owner = THIS_MODULE, | ||
772 | .name = KBUILD_MODNAME, | ||
773 | .bus = &fw_bus_type, | ||
774 | }, | ||
775 | .probe = fwspk_probe, | ||
776 | .update = fwspk_bus_reset, | ||
777 | .remove = fwspk_remove, | ||
778 | .id_table = fwspk_id_table, | ||
779 | }; | ||
780 | |||
781 | static int __init alsa_fwspk_init(void) | ||
782 | { | ||
783 | return driver_register(&fwspk_driver.driver); | ||
784 | } | ||
785 | |||
786 | static void __exit alsa_fwspk_exit(void) | ||
787 | { | ||
788 | driver_unregister(&fwspk_driver.driver); | ||
789 | } | ||
790 | |||
791 | module_init(alsa_fwspk_init); | ||
792 | module_exit(alsa_fwspk_exit); | ||
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index f3735e64791c..67dbfde837ab 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -465,17 +465,10 @@ static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol, | |||
465 | static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, | 465 | static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, |
466 | struct snd_ctl_elem_info *uinfo) | 466 | struct snd_ctl_elem_info *uinfo) |
467 | { | 467 | { |
468 | static char *texts[4] = { | 468 | static const char * const texts[4] = { |
469 | "44.1kHz", "Off", "48kHz", "32kHz", | 469 | "44.1kHz", "Off", "48kHz", "32kHz", |
470 | }; | 470 | }; |
471 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 471 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
472 | uinfo->count = 1; | ||
473 | uinfo->value.enumerated.items = 4; | ||
474 | if (uinfo->value.enumerated.item >= 4) | ||
475 | uinfo->value.enumerated.item = 3; | ||
476 | strcpy(uinfo->value.enumerated.name, | ||
477 | texts[uinfo->value.enumerated.item]); | ||
478 | return 0; | ||
479 | } | 472 | } |
480 | 473 | ||
481 | static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, | 474 | static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, |
@@ -570,22 +563,13 @@ static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol, | |||
570 | { | 563 | { |
571 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | 564 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); |
572 | int mixer_ch = AK_GET_SHIFT(kcontrol->private_value); | 565 | int mixer_ch = AK_GET_SHIFT(kcontrol->private_value); |
573 | const char **input_names; | 566 | unsigned int num_names; |
574 | unsigned int num_names, idx; | ||
575 | 567 | ||
576 | num_names = ak4xxx_capture_num_inputs(ak, mixer_ch); | 568 | num_names = ak4xxx_capture_num_inputs(ak, mixer_ch); |
577 | if (!num_names) | 569 | if (!num_names) |
578 | return -EINVAL; | 570 | return -EINVAL; |
579 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 571 | return snd_ctl_enum_info(uinfo, 1, num_names, |
580 | uinfo->count = 1; | 572 | ak->adc_info[mixer_ch].input_names); |
581 | uinfo->value.enumerated.items = num_names; | ||
582 | idx = uinfo->value.enumerated.item; | ||
583 | if (idx >= num_names) | ||
584 | return -EINVAL; | ||
585 | input_names = ak->adc_info[mixer_ch].input_names; | ||
586 | strlcpy(uinfo->value.enumerated.name, input_names[idx], | ||
587 | sizeof(uinfo->value.enumerated.name)); | ||
588 | return 0; | ||
589 | } | 573 | } |
590 | 574 | ||
591 | static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol, | 575 | static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index f0fd98e695e3..01a07986f4a3 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
@@ -731,18 +731,12 @@ int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, | |||
731 | 731 | ||
732 | static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 732 | static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
733 | { | 733 | { |
734 | static char *texts[8] = { | 734 | static const char * const texts[8] = { |
735 | "Line", "Mix", "CD", "Synth", "Video", | 735 | "Line", "Mix", "CD", "Synth", "Video", |
736 | "Mic", "Phone", | 736 | "Mic", "Phone", |
737 | }; | 737 | }; |
738 | 738 | ||
739 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 739 | return snd_ctl_enum_info(uinfo, 2, 7, texts); |
740 | uinfo->count = 2; | ||
741 | uinfo->value.enumerated.items = 7; | ||
742 | if (uinfo->value.enumerated.item > 6) | ||
743 | uinfo->value.enumerated.item = 6; | ||
744 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
745 | return 0; | ||
746 | } | 740 | } |
747 | 741 | ||
748 | static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 742 | static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index b3b4f15e45ba..b5450143407b 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c | |||
@@ -614,8 +614,7 @@ static int snd_es1688_free(struct snd_es1688 *chip) | |||
614 | { | 614 | { |
615 | if (chip->hardware != ES1688_HW_UNDEF) | 615 | if (chip->hardware != ES1688_HW_UNDEF) |
616 | snd_es1688_init(chip, 0); | 616 | snd_es1688_init(chip, 0); |
617 | if (chip->res_port) | 617 | release_and_free_resource(chip->res_port); |
618 | release_and_free_resource(chip->res_port); | ||
619 | if (chip->irq >= 0) | 618 | if (chip->irq >= 0) |
620 | free_irq(chip->irq, (void *) chip); | 619 | free_irq(chip->irq, (void *) chip); |
621 | if (chip->dma8 >= 0) { | 620 | if (chip->dma8 >= 0) { |
@@ -762,18 +761,12 @@ int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, | |||
762 | 761 | ||
763 | static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 762 | static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
764 | { | 763 | { |
765 | static char *texts[9] = { | 764 | static const char * const texts[8] = { |
766 | "Mic", "Mic Master", "CD", "AOUT", | 765 | "Mic", "Mic Master", "CD", "AOUT", |
767 | "Mic1", "Mix", "Line", "Master" | 766 | "Mic1", "Mix", "Line", "Master" |
768 | }; | 767 | }; |
769 | 768 | ||
770 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 769 | return snd_ctl_enum_info(uinfo, 1, 8, texts); |
771 | uinfo->count = 1; | ||
772 | uinfo->value.enumerated.items = 8; | ||
773 | if (uinfo->value.enumerated.item > 7) | ||
774 | uinfo->value.enumerated.item = 7; | ||
775 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
776 | return 0; | ||
777 | } | 770 | } |
778 | 771 | ||
779 | static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 772 | static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 6faaac60161a..b481bb8c31bc 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -156,6 +156,7 @@ struct snd_es18xx { | |||
156 | #define ES18XX_I2S 0x0200 /* I2S mixer control */ | 156 | #define ES18XX_I2S 0x0200 /* I2S mixer control */ |
157 | #define ES18XX_MUTEREC 0x0400 /* Record source can be muted */ | 157 | #define ES18XX_MUTEREC 0x0400 /* Record source can be muted */ |
158 | #define ES18XX_CONTROL 0x0800 /* Has control ports */ | 158 | #define ES18XX_CONTROL 0x0800 /* Has control ports */ |
159 | #define ES18XX_GPO_2BIT 0x1000 /* GPO0,1 controlled by PM port */ | ||
159 | 160 | ||
160 | /* Power Management */ | 161 | /* Power Management */ |
161 | #define ES18XX_PM 0x07 | 162 | #define ES18XX_PM 0x07 |
@@ -964,44 +965,28 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream) | |||
964 | 965 | ||
965 | static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 966 | static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
966 | { | 967 | { |
967 | static char *texts5Source[5] = { | 968 | static const char * const texts5Source[5] = { |
968 | "Mic", "CD", "Line", "Master", "Mix" | 969 | "Mic", "CD", "Line", "Master", "Mix" |
969 | }; | 970 | }; |
970 | static char *texts8Source[8] = { | 971 | static const char * const texts8Source[8] = { |
971 | "Mic", "Mic Master", "CD", "AOUT", | 972 | "Mic", "Mic Master", "CD", "AOUT", |
972 | "Mic1", "Mix", "Line", "Master" | 973 | "Mic1", "Mix", "Line", "Master" |
973 | }; | 974 | }; |
974 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); | 975 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); |
975 | 976 | ||
976 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
977 | uinfo->count = 1; | ||
978 | switch (chip->version) { | 977 | switch (chip->version) { |
979 | case 0x1868: | 978 | case 0x1868: |
980 | case 0x1878: | 979 | case 0x1878: |
981 | uinfo->value.enumerated.items = 4; | 980 | return snd_ctl_enum_info(uinfo, 1, 4, texts5Source); |
982 | if (uinfo->value.enumerated.item > 3) | ||
983 | uinfo->value.enumerated.item = 3; | ||
984 | strcpy(uinfo->value.enumerated.name, | ||
985 | texts5Source[uinfo->value.enumerated.item]); | ||
986 | break; | ||
987 | case 0x1887: | 981 | case 0x1887: |
988 | case 0x1888: | 982 | case 0x1888: |
989 | uinfo->value.enumerated.items = 5; | 983 | return snd_ctl_enum_info(uinfo, 1, 5, texts5Source); |
990 | if (uinfo->value.enumerated.item > 4) | ||
991 | uinfo->value.enumerated.item = 4; | ||
992 | strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]); | ||
993 | break; | ||
994 | case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */ | 984 | case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */ |
995 | case 0x1879: | 985 | case 0x1879: |
996 | uinfo->value.enumerated.items = 8; | 986 | return snd_ctl_enum_info(uinfo, 1, 8, texts8Source); |
997 | if (uinfo->value.enumerated.item > 7) | ||
998 | uinfo->value.enumerated.item = 7; | ||
999 | strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]); | ||
1000 | break; | ||
1001 | default: | 987 | default: |
1002 | return -EINVAL; | 988 | return -EINVAL; |
1003 | } | 989 | } |
1004 | return 0; | ||
1005 | } | 990 | } |
1006 | 991 | ||
1007 | static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 992 | static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1136,11 +1121,14 @@ static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg) | |||
1136 | return snd_es18xx_read(chip, reg); | 1121 | return snd_es18xx_read(chip, reg); |
1137 | } | 1122 | } |
1138 | 1123 | ||
1139 | #define ES18XX_SINGLE(xname, xindex, reg, shift, mask, invert) \ | 1124 | #define ES18XX_SINGLE(xname, xindex, reg, shift, mask, flags) \ |
1140 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | 1125 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
1141 | .info = snd_es18xx_info_single, \ | 1126 | .info = snd_es18xx_info_single, \ |
1142 | .get = snd_es18xx_get_single, .put = snd_es18xx_put_single, \ | 1127 | .get = snd_es18xx_get_single, .put = snd_es18xx_put_single, \ |
1143 | .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } | 1128 | .private_value = reg | (shift << 8) | (mask << 16) | (flags << 24) } |
1129 | |||
1130 | #define ES18XX_FL_INVERT (1 << 0) | ||
1131 | #define ES18XX_FL_PMPORT (1 << 1) | ||
1144 | 1132 | ||
1145 | static int snd_es18xx_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1133 | static int snd_es18xx_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1146 | { | 1134 | { |
@@ -1159,10 +1147,14 @@ static int snd_es18xx_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1159 | int reg = kcontrol->private_value & 0xff; | 1147 | int reg = kcontrol->private_value & 0xff; |
1160 | int shift = (kcontrol->private_value >> 8) & 0xff; | 1148 | int shift = (kcontrol->private_value >> 8) & 0xff; |
1161 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1149 | int mask = (kcontrol->private_value >> 16) & 0xff; |
1162 | int invert = (kcontrol->private_value >> 24) & 0xff; | 1150 | int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; |
1151 | int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; | ||
1163 | int val; | 1152 | int val; |
1164 | 1153 | ||
1165 | val = snd_es18xx_reg_read(chip, reg); | 1154 | if (pm_port) |
1155 | val = inb(chip->port + ES18XX_PM); | ||
1156 | else | ||
1157 | val = snd_es18xx_reg_read(chip, reg); | ||
1166 | ucontrol->value.integer.value[0] = (val >> shift) & mask; | 1158 | ucontrol->value.integer.value[0] = (val >> shift) & mask; |
1167 | if (invert) | 1159 | if (invert) |
1168 | ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; | 1160 | ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; |
@@ -1175,7 +1167,8 @@ static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1175 | int reg = kcontrol->private_value & 0xff; | 1167 | int reg = kcontrol->private_value & 0xff; |
1176 | int shift = (kcontrol->private_value >> 8) & 0xff; | 1168 | int shift = (kcontrol->private_value >> 8) & 0xff; |
1177 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1169 | int mask = (kcontrol->private_value >> 16) & 0xff; |
1178 | int invert = (kcontrol->private_value >> 24) & 0xff; | 1170 | int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; |
1171 | int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; | ||
1179 | unsigned char val; | 1172 | unsigned char val; |
1180 | 1173 | ||
1181 | val = (ucontrol->value.integer.value[0] & mask); | 1174 | val = (ucontrol->value.integer.value[0] & mask); |
@@ -1183,6 +1176,15 @@ static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1183 | val = mask - val; | 1176 | val = mask - val; |
1184 | mask <<= shift; | 1177 | mask <<= shift; |
1185 | val <<= shift; | 1178 | val <<= shift; |
1179 | if (pm_port) { | ||
1180 | unsigned char cur = inb(chip->port + ES18XX_PM); | ||
1181 | |||
1182 | if ((cur & mask) == val) | ||
1183 | return 0; | ||
1184 | outb((cur & ~mask) | val, chip->port + ES18XX_PM); | ||
1185 | return 1; | ||
1186 | } | ||
1187 | |||
1186 | return snd_es18xx_reg_bits(chip, reg, mask, val) != val; | 1188 | return snd_es18xx_reg_bits(chip, reg, mask, val) != val; |
1187 | } | 1189 | } |
1188 | 1190 | ||
@@ -1304,7 +1306,7 @@ static struct snd_kcontrol_new snd_es18xx_opt_speaker = | |||
1304 | ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0); | 1306 | ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0); |
1305 | 1307 | ||
1306 | static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { | 1308 | static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { |
1307 | ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), | 1309 | ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, ES18XX_FL_INVERT), |
1308 | ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0), | 1310 | ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0), |
1309 | ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), | 1311 | ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), |
1310 | ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) | 1312 | ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) |
@@ -1363,6 +1365,11 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = { | |||
1363 | ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), | 1365 | ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), |
1364 | }; | 1366 | }; |
1365 | 1367 | ||
1368 | static struct snd_kcontrol_new snd_es18xx_opt_gpo_2bit[] = { | ||
1369 | ES18XX_SINGLE("GPO0 Switch", 0, ES18XX_PM, 0, 1, ES18XX_FL_PMPORT), | ||
1370 | ES18XX_SINGLE("GPO1 Switch", 0, ES18XX_PM, 1, 1, ES18XX_FL_PMPORT), | ||
1371 | }; | ||
1372 | |||
1366 | static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) | 1373 | static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) |
1367 | { | 1374 | { |
1368 | int data; | 1375 | int data; |
@@ -1629,10 +1636,10 @@ static int snd_es18xx_probe(struct snd_es18xx *chip, | |||
1629 | 1636 | ||
1630 | switch (chip->version) { | 1637 | switch (chip->version) { |
1631 | case 0x1868: | 1638 | case 0x1868: |
1632 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL; | 1639 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT; |
1633 | break; | 1640 | break; |
1634 | case 0x1869: | 1641 | case 0x1869: |
1635 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV; | 1642 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV | ES18XX_GPO_2BIT; |
1636 | break; | 1643 | break; |
1637 | case 0x1878: | 1644 | case 0x1878: |
1638 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; | 1645 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; |
@@ -1642,7 +1649,7 @@ static int snd_es18xx_probe(struct snd_es18xx *chip, | |||
1642 | break; | 1649 | break; |
1643 | case 0x1887: | 1650 | case 0x1887: |
1644 | case 0x1888: | 1651 | case 0x1888: |
1645 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; | 1652 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT; |
1646 | break; | 1653 | break; |
1647 | default: | 1654 | default: |
1648 | snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", | 1655 | snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", |
@@ -1944,6 +1951,15 @@ static int snd_es18xx_mixer(struct snd_card *card) | |||
1944 | return err; | 1951 | return err; |
1945 | } | 1952 | } |
1946 | } | 1953 | } |
1954 | if (chip->caps & ES18XX_GPO_2BIT) { | ||
1955 | for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_gpo_2bit); idx++) { | ||
1956 | err = snd_ctl_add(card, | ||
1957 | snd_ctl_new1(&snd_es18xx_opt_gpo_2bit[idx], | ||
1958 | chip)); | ||
1959 | if (err < 0) | ||
1960 | return err; | ||
1961 | } | ||
1962 | } | ||
1947 | return 0; | 1963 | return 0; |
1948 | } | 1964 | } |
1949 | 1965 | ||
diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c index 031dc69b7470..17e49a071af4 100644 --- a/sound/isa/msnd/msnd_pinnacle_mixer.c +++ b/sound/isa/msnd/msnd_pinnacle_mixer.c | |||
@@ -55,20 +55,13 @@ | |||
55 | static int snd_msndmix_info_mux(struct snd_kcontrol *kcontrol, | 55 | static int snd_msndmix_info_mux(struct snd_kcontrol *kcontrol, |
56 | struct snd_ctl_elem_info *uinfo) | 56 | struct snd_ctl_elem_info *uinfo) |
57 | { | 57 | { |
58 | static char *texts[3] = { | 58 | static const char * const texts[3] = { |
59 | "Analog", "MASS", "SPDIF", | 59 | "Analog", "MASS", "SPDIF", |
60 | }; | 60 | }; |
61 | struct snd_msnd *chip = snd_kcontrol_chip(kcontrol); | 61 | struct snd_msnd *chip = snd_kcontrol_chip(kcontrol); |
62 | unsigned items = test_bit(F_HAVEDIGITAL, &chip->flags) ? 3 : 2; | 62 | unsigned items = test_bit(F_HAVEDIGITAL, &chip->flags) ? 3 : 2; |
63 | 63 | ||
64 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 64 | return snd_ctl_enum_info(uinfo, 1, items, texts); |
65 | uinfo->count = 1; | ||
66 | uinfo->value.enumerated.items = items; | ||
67 | if (uinfo->value.enumerated.item >= items) | ||
68 | uinfo->value.enumerated.item = items - 1; | ||
69 | strcpy(uinfo->value.enumerated.name, | ||
70 | texts[uinfo->value.enumerated.item]); | ||
71 | return 0; | ||
72 | } | 65 | } |
73 | 66 | ||
74 | static int snd_msndmix_get_mux(struct snd_kcontrol *kcontrol, | 67 | static int snd_msndmix_get_mux(struct snd_kcontrol *kcontrol, |
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c index 4e3fcfb15ad4..95b39beb61c1 100644 --- a/sound/isa/sb/emu8000_synth.c +++ b/sound/isa/sb/emu8000_synth.c | |||
@@ -105,8 +105,7 @@ static int snd_emu8000_delete_device(struct snd_seq_device *dev) | |||
105 | snd_device_free(dev->card, hw->pcm); | 105 | snd_device_free(dev->card, hw->pcm); |
106 | if (hw->emu) | 106 | if (hw->emu) |
107 | snd_emux_free(hw->emu); | 107 | snd_emux_free(hw->emu); |
108 | if (hw->memhdr) | 108 | snd_util_memhdr_free(hw->memhdr); |
109 | snd_util_memhdr_free(hw->memhdr); | ||
110 | hw->emu = NULL; | 109 | hw->emu = NULL; |
111 | hw->memhdr = NULL; | 110 | hw->memhdr = NULL; |
112 | return 0; | 111 | return 0; |
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 0bbcd4714d28..72b10f4f3e70 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c | |||
@@ -702,17 +702,11 @@ static int snd_sb16_get_dma_mode(struct snd_sb *chip) | |||
702 | 702 | ||
703 | static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 703 | static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
704 | { | 704 | { |
705 | static char *texts[3] = { | 705 | static const char * const texts[3] = { |
706 | "Auto", "Playback", "Capture" | 706 | "Auto", "Playback", "Capture" |
707 | }; | 707 | }; |
708 | 708 | ||
709 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 709 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
710 | uinfo->count = 1; | ||
711 | uinfo->value.enumerated.items = 3; | ||
712 | if (uinfo->value.enumerated.item > 2) | ||
713 | uinfo->value.enumerated.item = 2; | ||
714 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
715 | return 0; | ||
716 | } | 710 | } |
717 | 711 | ||
718 | static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 712 | static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 3ef990602cdd..f22b4480828e 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c | |||
@@ -184,8 +184,7 @@ static int snd_sbdsp_probe(struct snd_sb * chip) | |||
184 | 184 | ||
185 | static int snd_sbdsp_free(struct snd_sb *chip) | 185 | static int snd_sbdsp_free(struct snd_sb *chip) |
186 | { | 186 | { |
187 | if (chip->res_port) | 187 | release_and_free_resource(chip->res_port); |
188 | release_and_free_resource(chip->res_port); | ||
189 | if (chip->irq >= 0) | 188 | if (chip->irq >= 0) |
190 | free_irq(chip->irq, (void *) chip); | 189 | free_irq(chip->irq, (void *) chip); |
191 | #ifdef CONFIG_ISA | 190 | #ifdef CONFIG_ISA |
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 1ff78ec9f0ac..e403334a19ad 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -182,17 +182,11 @@ static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
182 | 182 | ||
183 | static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 183 | static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
184 | { | 184 | { |
185 | static const char *texts[5] = { | 185 | static const char * const texts[5] = { |
186 | "CD", "Mic", "Line", "Synth", "Master" | 186 | "CD", "Mic", "Line", "Synth", "Master" |
187 | }; | 187 | }; |
188 | 188 | ||
189 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 189 | return snd_ctl_enum_info(uinfo, 1, 5, texts); |
190 | uinfo->count = 1; | ||
191 | uinfo->value.enumerated.items = 5; | ||
192 | if (uinfo->value.enumerated.item > 4) | ||
193 | uinfo->value.enumerated.item = 4; | ||
194 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
195 | return 0; | ||
196 | } | 190 | } |
197 | 191 | ||
198 | static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 192 | static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -275,18 +269,11 @@ static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
275 | static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol, | 269 | static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol, |
276 | struct snd_ctl_elem_info *uinfo) | 270 | struct snd_ctl_elem_info *uinfo) |
277 | { | 271 | { |
278 | static const char *texts[3] = { | 272 | static const char * const texts[3] = { |
279 | "L chan only", "R chan only", "L ch/2 + R ch/2" | 273 | "L chan only", "R chan only", "L ch/2 + R ch/2" |
280 | }; | 274 | }; |
281 | 275 | ||
282 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 276 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
283 | uinfo->count = 1; | ||
284 | uinfo->value.enumerated.items = 3; | ||
285 | if (uinfo->value.enumerated.item > 2) | ||
286 | uinfo->value.enumerated.item = 2; | ||
287 | strcpy(uinfo->value.enumerated.name, | ||
288 | texts[uinfo->value.enumerated.item]); | ||
289 | return 0; | ||
290 | } | 277 | } |
291 | 278 | ||
292 | static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol, | 279 | static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol, |
@@ -335,17 +322,11 @@ static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol, | |||
335 | 322 | ||
336 | static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 323 | static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
337 | { | 324 | { |
338 | static const char *texts[3] = { | 325 | static const char * const texts[3] = { |
339 | "Mic", "CD", "Line" | 326 | "Mic", "CD", "Line" |
340 | }; | 327 | }; |
341 | 328 | ||
342 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 329 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
343 | uinfo->count = 1; | ||
344 | uinfo->value.enumerated.items = 3; | ||
345 | if (uinfo->value.enumerated.item > 2) | ||
346 | uinfo->value.enumerated.item = 2; | ||
347 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
348 | return 0; | ||
349 | } | 330 | } |
350 | 331 | ||
351 | 332 | ||
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 360b08b03e1d..347bb1bda110 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -1993,25 +1993,20 @@ EXPORT_SYMBOL(snd_wss_timer); | |||
1993 | static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, | 1993 | static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, |
1994 | struct snd_ctl_elem_info *uinfo) | 1994 | struct snd_ctl_elem_info *uinfo) |
1995 | { | 1995 | { |
1996 | static char *texts[4] = { | 1996 | static const char * const texts[4] = { |
1997 | "Line", "Aux", "Mic", "Mix" | 1997 | "Line", "Aux", "Mic", "Mix" |
1998 | }; | 1998 | }; |
1999 | static char *opl3sa_texts[4] = { | 1999 | static const char * const opl3sa_texts[4] = { |
2000 | "Line", "CD", "Mic", "Mix" | 2000 | "Line", "CD", "Mic", "Mix" |
2001 | }; | 2001 | }; |
2002 | static char *gusmax_texts[4] = { | 2002 | static const char * const gusmax_texts[4] = { |
2003 | "Line", "Synth", "Mic", "Mix" | 2003 | "Line", "Synth", "Mic", "Mix" |
2004 | }; | 2004 | }; |
2005 | char **ptexts = texts; | 2005 | const char * const *ptexts = texts; |
2006 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | 2006 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); |
2007 | 2007 | ||
2008 | if (snd_BUG_ON(!chip->card)) | 2008 | if (snd_BUG_ON(!chip->card)) |
2009 | return -EINVAL; | 2009 | return -EINVAL; |
2010 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2011 | uinfo->count = 2; | ||
2012 | uinfo->value.enumerated.items = 4; | ||
2013 | if (uinfo->value.enumerated.item > 3) | ||
2014 | uinfo->value.enumerated.item = 3; | ||
2015 | if (!strcmp(chip->card->driver, "GUS MAX")) | 2010 | if (!strcmp(chip->card->driver, "GUS MAX")) |
2016 | ptexts = gusmax_texts; | 2011 | ptexts = gusmax_texts; |
2017 | switch (chip->hardware) { | 2012 | switch (chip->hardware) { |
@@ -2023,8 +2018,7 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, | |||
2023 | ptexts = opl3sa_texts; | 2018 | ptexts = opl3sa_texts; |
2024 | break; | 2019 | break; |
2025 | } | 2020 | } |
2026 | strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]); | 2021 | return snd_ctl_enum_info(uinfo, 2, 4, ptexts); |
2027 | return 0; | ||
2028 | } | 2022 | } |
2029 | 2023 | ||
2030 | static int snd_wss_get_mux(struct snd_kcontrol *kcontrol, | 2024 | static int snd_wss_get_mux(struct snd_kcontrol *kcontrol, |
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 04bb06c03ec8..33b08fcc27a9 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c | |||
@@ -201,17 +201,10 @@ static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol, | |||
201 | static int sgio2audio_source_info(struct snd_kcontrol *kcontrol, | 201 | static int sgio2audio_source_info(struct snd_kcontrol *kcontrol, |
202 | struct snd_ctl_elem_info *uinfo) | 202 | struct snd_ctl_elem_info *uinfo) |
203 | { | 203 | { |
204 | static const char *texts[3] = { | 204 | static const char * const texts[3] = { |
205 | "Cam Mic", "Mic", "Line" | 205 | "Cam Mic", "Mic", "Line" |
206 | }; | 206 | }; |
207 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 207 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
208 | uinfo->count = 1; | ||
209 | uinfo->value.enumerated.items = 3; | ||
210 | if (uinfo->value.enumerated.item >= 3) | ||
211 | uinfo->value.enumerated.item = 1; | ||
212 | strcpy(uinfo->value.enumerated.name, | ||
213 | texts[uinfo->value.enumerated.item]); | ||
214 | return 0; | ||
215 | } | 208 | } |
216 | 209 | ||
217 | static int sgio2audio_source_get(struct snd_kcontrol *kcontrol, | 210 | static int sgio2audio_source_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c index 279bc565ac7e..dae4d4344407 100644 --- a/sound/oss/uart401.c +++ b/sound/oss/uart401.c | |||
@@ -412,13 +412,10 @@ void unload_uart401(struct address_info *hw_config) | |||
412 | 412 | ||
413 | if (!devc->share_irq) | 413 | if (!devc->share_irq) |
414 | free_irq(devc->irq, devc); | 414 | free_irq(devc->irq, devc); |
415 | if (devc) | 415 | kfree(midi_devs[devc->my_dev]->converter); |
416 | { | 416 | kfree(midi_devs[devc->my_dev]); |
417 | kfree(midi_devs[devc->my_dev]->converter); | 417 | kfree(devc); |
418 | kfree(midi_devs[devc->my_dev]); | 418 | |
419 | kfree(devc); | ||
420 | devc = NULL; | ||
421 | } | ||
422 | /* This kills midi_devs[x] */ | 419 | /* This kills midi_devs[x] */ |
423 | sound_unload_mididev(hw_config->slots[4]); | 420 | sound_unload_mididev(hw_config->slots[4]); |
424 | } | 421 | } |
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 4b20be79c1dd..29604a239c44 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c | |||
@@ -776,15 +776,9 @@ static int | |||
776 | snd_harmony_captureroute_info(struct snd_kcontrol *kc, | 776 | snd_harmony_captureroute_info(struct snd_kcontrol *kc, |
777 | struct snd_ctl_elem_info *uinfo) | 777 | struct snd_ctl_elem_info *uinfo) |
778 | { | 778 | { |
779 | static char *texts[2] = { "Line", "Mic" }; | 779 | static const char * const texts[2] = { "Line", "Mic" }; |
780 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 780 | |
781 | uinfo->count = 1; | 781 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
782 | uinfo->value.enumerated.items = 2; | ||
783 | if (uinfo->value.enumerated.item > 1) | ||
784 | uinfo->value.enumerated.item = 1; | ||
785 | strcpy(uinfo->value.enumerated.name, | ||
786 | texts[uinfo->value.enumerated.item]); | ||
787 | return 0; | ||
788 | } | 782 | } |
789 | 783 | ||
790 | static int | 784 | static int |
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 14ad54b7928c..5ee2f17c287c 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -463,14 +463,8 @@ static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, | |||
463 | { | 463 | { |
464 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; | 464 | struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; |
465 | 465 | ||
466 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 466 | return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, |
467 | uinfo->count = e->shift_l == e->shift_r ? 1 : 2; | 467 | e->mask, e->texts); |
468 | uinfo->value.enumerated.items = e->mask; | ||
469 | |||
470 | if (uinfo->value.enumerated.item > e->mask - 1) | ||
471 | uinfo->value.enumerated.item = e->mask - 1; | ||
472 | strcpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]); | ||
473 | return 0; | ||
474 | } | 468 | } |
475 | 469 | ||
476 | static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, | 470 | static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 991762215417..ceaac1c41906 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -33,7 +33,8 @@ | |||
33 | static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, | 33 | static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, |
34 | const char *name); | 34 | const char *name); |
35 | static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, | 35 | static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, |
36 | const unsigned int *tlv, const char **slaves); | 36 | const unsigned int *tlv, |
37 | const char * const *slaves); | ||
37 | 38 | ||
38 | /* | 39 | /* |
39 | * Chip specific initialization | 40 | * Chip specific initialization |
@@ -81,22 +82,11 @@ static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsi | |||
81 | /* | 82 | /* |
82 | * shared line-in/mic controls | 83 | * shared line-in/mic controls |
83 | */ | 84 | */ |
84 | static int ac97_enum_text_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo, | ||
85 | const char **texts, unsigned int nums) | ||
86 | { | ||
87 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
88 | uinfo->count = 1; | ||
89 | uinfo->value.enumerated.items = nums; | ||
90 | if (uinfo->value.enumerated.item > nums - 1) | ||
91 | uinfo->value.enumerated.item = nums - 1; | ||
92 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 85 | static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
97 | { | 86 | { |
98 | static const char *texts[] = { "Shared", "Independent" }; | 87 | static const char * const texts[] = { "Shared", "Independent" }; |
99 | return ac97_enum_text_info(kcontrol, uinfo, texts, 2); | 88 | |
89 | return snd_ctl_enum_info(uinfo, 1, 2, texts); | ||
100 | } | 90 | } |
101 | 91 | ||
102 | static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 92 | static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -123,9 +113,9 @@ static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd | |||
123 | 113 | ||
124 | static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 114 | static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
125 | { | 115 | { |
126 | static const char *texts[] = { "2ch", "4ch", "6ch", "8ch" }; | 116 | static const char * const texts[] = { "2ch", "4ch", "6ch", "8ch" }; |
127 | return ac97_enum_text_info(kcontrol, uinfo, texts, | 117 | |
128 | kcontrol->private_value); | 118 | return snd_ctl_enum_info(uinfo, 1, kcontrol->private_value, texts); |
129 | } | 119 | } |
130 | 120 | ||
131 | static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 121 | static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -240,17 +230,11 @@ static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97) | |||
240 | static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol, | 230 | static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol, |
241 | struct snd_ctl_elem_info *uinfo) | 231 | struct snd_ctl_elem_info *uinfo) |
242 | { | 232 | { |
243 | static char *texts[3] = { | 233 | static const char * const texts[3] = { |
244 | "Standard", "Small", "Smaller" | 234 | "Standard", "Small", "Smaller" |
245 | }; | 235 | }; |
246 | 236 | ||
247 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 237 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
248 | uinfo->count = 1; | ||
249 | uinfo->value.enumerated.items = 3; | ||
250 | if (uinfo->value.enumerated.item > 2) | ||
251 | uinfo->value.enumerated.item = 2; | ||
252 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
253 | return 0; | ||
254 | } | 238 | } |
255 | 239 | ||
256 | static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol, | 240 | static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol, |
@@ -293,15 +277,9 @@ static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker = | |||
293 | static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol, | 277 | static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol, |
294 | struct snd_ctl_elem_info *uinfo) | 278 | struct snd_ctl_elem_info *uinfo) |
295 | { | 279 | { |
296 | static char *texts[2] = { "AC-Link", "A/D Converter" }; | 280 | static const char * const texts[2] = { "AC-Link", "A/D Converter" }; |
297 | 281 | ||
298 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 282 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
299 | uinfo->count = 1; | ||
300 | uinfo->value.enumerated.items = 2; | ||
301 | if (uinfo->value.enumerated.item > 1) | ||
302 | uinfo->value.enumerated.item = 1; | ||
303 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
304 | return 0; | ||
305 | } | 283 | } |
306 | 284 | ||
307 | static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol, | 285 | static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol, |
@@ -401,15 +379,9 @@ static int patch_yamaha_ymf743(struct snd_ac97 *ac97) | |||
401 | There is also a bit to mute S/PDIF output in a vendor-specific register. */ | 379 | There is also a bit to mute S/PDIF output in a vendor-specific register. */ |
402 | static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 380 | static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
403 | { | 381 | { |
404 | static char *texts[3] = { "Disabled", "Pin 43", "Pin 48" }; | 382 | static const char * const texts[3] = { "Disabled", "Pin 43", "Pin 48" }; |
405 | 383 | ||
406 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 384 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
407 | uinfo->count = 1; | ||
408 | uinfo->value.enumerated.items = 3; | ||
409 | if (uinfo->value.enumerated.item > 2) | ||
410 | uinfo->value.enumerated.item = 2; | ||
411 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
412 | return 0; | ||
413 | } | 385 | } |
414 | 386 | ||
415 | static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 387 | static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1103,16 +1075,11 @@ static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) | |||
1103 | 1075 | ||
1104 | static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1076 | static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1105 | { | 1077 | { |
1106 | static char *texts[5] = { "Input/Disabled", "Front Output", | 1078 | static const char * const texts[5] = { |
1079 | "Input/Disabled", "Front Output", | ||
1107 | "Rear Output", "Center/LFE Output", "Mixer Output" }; | 1080 | "Rear Output", "Center/LFE Output", "Mixer Output" }; |
1108 | 1081 | ||
1109 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1082 | return snd_ctl_enum_info(uinfo, 1, 5, texts); |
1110 | uinfo->count = 1; | ||
1111 | uinfo->value.enumerated.items = 5; | ||
1112 | if (uinfo->value.enumerated.item > 4) | ||
1113 | uinfo->value.enumerated.item = 4; | ||
1114 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1115 | return 0; | ||
1116 | } | 1083 | } |
1117 | 1084 | ||
1118 | static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1085 | static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1147,16 +1114,11 @@ static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, stru | |||
1147 | 1114 | ||
1148 | static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1115 | static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1149 | { | 1116 | { |
1150 | static char *texts[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack", | 1117 | static const char * const texts[7] = { |
1118 | "Mic2 Jack", "Mic1 Jack", "Line In Jack", | ||
1151 | "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" }; | 1119 | "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" }; |
1152 | 1120 | ||
1153 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1121 | return snd_ctl_enum_info(uinfo, 1, 7, texts); |
1154 | uinfo->count = 1; | ||
1155 | uinfo->value.enumerated.items = 7; | ||
1156 | if (uinfo->value.enumerated.item > 6) | ||
1157 | uinfo->value.enumerated.item = 6; | ||
1158 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1159 | return 0; | ||
1160 | } | 1122 | } |
1161 | 1123 | ||
1162 | static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1124 | static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1181,15 +1143,11 @@ static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struc | |||
1181 | 1143 | ||
1182 | static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1144 | static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1183 | { | 1145 | { |
1184 | static char *texts[3] = { "None", "Front Jack", "Rear Jack" }; | 1146 | static const char * const texts[3] = { |
1147 | "None", "Front Jack", "Rear Jack" | ||
1148 | }; | ||
1185 | 1149 | ||
1186 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1150 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
1187 | uinfo->count = 1; | ||
1188 | uinfo->value.enumerated.items = 3; | ||
1189 | if (uinfo->value.enumerated.item > 2) | ||
1190 | uinfo->value.enumerated.item = 2; | ||
1191 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1192 | return 0; | ||
1193 | } | 1151 | } |
1194 | 1152 | ||
1195 | static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1153 | static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1804,15 +1762,9 @@ static int patch_ad1886(struct snd_ac97 * ac97) | |||
1804 | 1762 | ||
1805 | static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1763 | static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1806 | { | 1764 | { |
1807 | static char *texts[2] = { "AC-Link", "A/D Converter" }; | 1765 | static const char * const texts[2] = { "AC-Link", "A/D Converter" }; |
1808 | 1766 | ||
1809 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1767 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
1810 | uinfo->count = 1; | ||
1811 | uinfo->value.enumerated.items = 2; | ||
1812 | if (uinfo->value.enumerated.item > 1) | ||
1813 | uinfo->value.enumerated.item = 1; | ||
1814 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1815 | return 0; | ||
1816 | } | 1768 | } |
1817 | 1769 | ||
1818 | static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1770 | static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1994,15 +1946,9 @@ static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd | |||
1994 | 1946 | ||
1995 | static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1947 | static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1996 | { | 1948 | { |
1997 | static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"}; | 1949 | static const char * const texts[3] = {"Off", "6 -> 4", "6 -> 2"}; |
1998 | 1950 | ||
1999 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1951 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2000 | uinfo->count = 1; | ||
2001 | uinfo->value.enumerated.items = 3; | ||
2002 | if (uinfo->value.enumerated.item > 2) | ||
2003 | uinfo->value.enumerated.item = 2; | ||
2004 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2005 | return 0; | ||
2006 | } | 1952 | } |
2007 | 1953 | ||
2008 | static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1954 | static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2153,16 +2099,11 @@ static int patch_ad1980(struct snd_ac97 * ac97) | |||
2153 | static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol, | 2099 | static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol, |
2154 | struct snd_ctl_elem_info *uinfo) | 2100 | struct snd_ctl_elem_info *uinfo) |
2155 | { | 2101 | { |
2156 | static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"}; | 2102 | static const char * const texts[4] = { |
2103 | "High-Z", "3.7 V", "2.25 V", "0 V" | ||
2104 | }; | ||
2157 | 2105 | ||
2158 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2106 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
2159 | uinfo->count = 1; | ||
2160 | uinfo->value.enumerated.items = 4; | ||
2161 | if (uinfo->value.enumerated.item > 3) | ||
2162 | uinfo->value.enumerated.item = 3; | ||
2163 | strcpy(uinfo->value.enumerated.name, | ||
2164 | texts[uinfo->value.enumerated.item]); | ||
2165 | return 0; | ||
2166 | } | 2107 | } |
2167 | 2108 | ||
2168 | static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol, | 2109 | static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol, |
@@ -2756,20 +2697,18 @@ static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = { | |||
2756 | 2697 | ||
2757 | static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2698 | static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2758 | { | 2699 | { |
2759 | static char *texts_655[3] = { "PCM", "Analog In", "IEC958 In" }; | 2700 | static const char * const texts_655[3] = { |
2760 | static char *texts_658[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" }; | 2701 | "PCM", "Analog In", "IEC958 In" |
2702 | }; | ||
2703 | static const char * const texts_658[4] = { | ||
2704 | "PCM", "Analog1 In", "Analog2 In", "IEC958 In" | ||
2705 | }; | ||
2761 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 2706 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
2762 | 2707 | ||
2763 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2708 | if (ac97->spec.dev_flags) |
2764 | uinfo->count = 1; | 2709 | return snd_ctl_enum_info(uinfo, 1, 4, texts_658); |
2765 | uinfo->value.enumerated.items = ac97->spec.dev_flags ? 4 : 3; | 2710 | else |
2766 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 2711 | return snd_ctl_enum_info(uinfo, 1, 3, texts_655); |
2767 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2768 | strcpy(uinfo->value.enumerated.name, | ||
2769 | ac97->spec.dev_flags ? | ||
2770 | texts_658[uinfo->value.enumerated.item] : | ||
2771 | texts_655[uinfo->value.enumerated.item]); | ||
2772 | return 0; | ||
2773 | } | 2712 | } |
2774 | 2713 | ||
2775 | static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2714 | static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -3055,15 +2994,9 @@ static int patch_cm9738(struct snd_ac97 * ac97) | |||
3055 | 2994 | ||
3056 | static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2995 | static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
3057 | { | 2996 | { |
3058 | static char *texts[] = { "Analog", "Digital" }; | 2997 | static const char * const texts[] = { "Analog", "Digital" }; |
3059 | 2998 | ||
3060 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2999 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
3061 | uinfo->count = 1; | ||
3062 | uinfo->value.enumerated.items = 2; | ||
3063 | if (uinfo->value.enumerated.item > 1) | ||
3064 | uinfo->value.enumerated.item = 1; | ||
3065 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
3066 | return 0; | ||
3067 | } | 3000 | } |
3068 | 3001 | ||
3069 | static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 3002 | static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -3235,15 +3168,9 @@ static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = { | |||
3235 | 3168 | ||
3236 | static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 3169 | static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
3237 | { | 3170 | { |
3238 | static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" }; | 3171 | static const char * const texts[] = { "AC-Link", "ADC", "SPDIF-In" }; |
3239 | 3172 | ||
3240 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3173 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
3241 | uinfo->count = 1; | ||
3242 | uinfo->value.enumerated.items = 3; | ||
3243 | if (uinfo->value.enumerated.item > 2) | ||
3244 | uinfo->value.enumerated.item = 2; | ||
3245 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
3246 | return 0; | ||
3247 | } | 3174 | } |
3248 | 3175 | ||
3249 | static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 3176 | static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -3270,7 +3197,9 @@ static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd | |||
3270 | ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0); | 3197 | ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0); |
3271 | } | 3198 | } |
3272 | 3199 | ||
3273 | static const char *cm9761_dac_clock[] = { "AC-Link", "SPDIF-In", "Both" }; | 3200 | static const char * const cm9761_dac_clock[] = { |
3201 | "AC-Link", "SPDIF-In", "Both" | ||
3202 | }; | ||
3274 | static const struct ac97_enum cm9761_dac_clock_enum = | 3203 | static const struct ac97_enum cm9761_dac_clock_enum = |
3275 | AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock); | 3204 | AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock); |
3276 | 3205 | ||
@@ -3384,7 +3313,9 @@ static int patch_cm9761(struct snd_ac97 *ac97) | |||
3384 | #define AC97_CM9780_MULTI_CHAN 0x66 | 3313 | #define AC97_CM9780_MULTI_CHAN 0x66 |
3385 | #define AC97_CM9780_SPDIF 0x6c | 3314 | #define AC97_CM9780_SPDIF 0x6c |
3386 | 3315 | ||
3387 | static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" }; | 3316 | static const char * const cm9780_ch_select[] = { |
3317 | "Front", "Side", "Center/LFE", "Rear" | ||
3318 | }; | ||
3388 | static const struct ac97_enum cm9780_ch_select_enum = | 3319 | static const struct ac97_enum cm9780_ch_select_enum = |
3389 | AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select); | 3320 | AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select); |
3390 | static const struct snd_kcontrol_new cm9780_controls[] = { | 3321 | static const struct snd_kcontrol_new cm9780_controls[] = { |
@@ -3430,7 +3361,7 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), | |||
3430 | AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), | 3361 | AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), |
3431 | }; | 3362 | }; |
3432 | 3363 | ||
3433 | static const char *slave_vols_vt1616[] = { | 3364 | static const char * const slave_vols_vt1616[] = { |
3434 | "Front Playback Volume", | 3365 | "Front Playback Volume", |
3435 | "Surround Playback Volume", | 3366 | "Surround Playback Volume", |
3436 | "Center Playback Volume", | 3367 | "Center Playback Volume", |
@@ -3438,7 +3369,7 @@ static const char *slave_vols_vt1616[] = { | |||
3438 | NULL | 3369 | NULL |
3439 | }; | 3370 | }; |
3440 | 3371 | ||
3441 | static const char *slave_sws_vt1616[] = { | 3372 | static const char * const slave_sws_vt1616[] = { |
3442 | "Front Playback Switch", | 3373 | "Front Playback Switch", |
3443 | "Surround Playback Switch", | 3374 | "Surround Playback Switch", |
3444 | "Center Playback Switch", | 3375 | "Center Playback Switch", |
@@ -3459,10 +3390,11 @@ static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, | |||
3459 | 3390 | ||
3460 | /* create a virtual master control and add slaves */ | 3391 | /* create a virtual master control and add slaves */ |
3461 | static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, | 3392 | static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, |
3462 | const unsigned int *tlv, const char **slaves) | 3393 | const unsigned int *tlv, |
3394 | const char * const *slaves) | ||
3463 | { | 3395 | { |
3464 | struct snd_kcontrol *kctl; | 3396 | struct snd_kcontrol *kctl; |
3465 | const char **s; | 3397 | const char * const *s; |
3466 | int err; | 3398 | int err; |
3467 | 3399 | ||
3468 | kctl = snd_ctl_make_virtual_master(name, tlv); | 3400 | kctl = snd_ctl_make_virtual_master(name, tlv); |
@@ -3552,11 +3484,12 @@ static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, | |||
3552 | * is SM51EN *AND* it's Bit14, not Bit15 so the table is very | 3484 | * is SM51EN *AND* it's Bit14, not Bit15 so the table is very |
3553 | * counter-intuitive */ | 3485 | * counter-intuitive */ |
3554 | 3486 | ||
3555 | static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3", | 3487 | static const char * const texts[] = {"LineIn Mic1", "LineIn Mic1 Mic3", |
3556 | "Surr LFE/C Mic3", "LineIn LFE/C Mic3", | 3488 | "Surr LFE/C Mic3", "LineIn LFE/C Mic3", |
3557 | "LineIn Mic2", "LineIn Mic2 Mic1", | 3489 | "LineIn Mic2", "LineIn Mic2 Mic1", |
3558 | "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; | 3490 | "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; |
3559 | return ac97_enum_text_info(kcontrol, uinfo, texts, 8); | 3491 | |
3492 | return snd_ctl_enum_info(uinfo, 1, 8, texts); | ||
3560 | } | 3493 | } |
3561 | 3494 | ||
3562 | static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, | 3495 | static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, |
@@ -3685,7 +3618,7 @@ static int patch_vt1617a(struct snd_ac97 * ac97) | |||
3685 | struct vt1618_uaj_item { | 3618 | struct vt1618_uaj_item { |
3686 | unsigned short mask; | 3619 | unsigned short mask; |
3687 | unsigned short shift; | 3620 | unsigned short shift; |
3688 | const char *items[4]; | 3621 | const char * const items[4]; |
3689 | }; | 3622 | }; |
3690 | 3623 | ||
3691 | /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */ | 3624 | /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */ |
@@ -3720,9 +3653,8 @@ static struct vt1618_uaj_item vt1618_uaj[3] = { | |||
3720 | static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol, | 3653 | static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol, |
3721 | struct snd_ctl_elem_info *uinfo) | 3654 | struct snd_ctl_elem_info *uinfo) |
3722 | { | 3655 | { |
3723 | return ac97_enum_text_info(kcontrol, uinfo, | 3656 | return snd_ctl_enum_info(uinfo, 1, 4, |
3724 | vt1618_uaj[kcontrol->private_value].items, | 3657 | vt1618_uaj[kcontrol->private_value].items); |
3725 | 4); | ||
3726 | } | 3658 | } |
3727 | 3659 | ||
3728 | /* All of the vt1618 Universal Audio Jack twiddlers are on | 3660 | /* All of the vt1618 Universal Audio Jack twiddlers are on |
@@ -3767,9 +3699,9 @@ static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol, | |||
3767 | static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol, | 3699 | static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol, |
3768 | struct snd_ctl_elem_info *uinfo) | 3700 | struct snd_ctl_elem_info *uinfo) |
3769 | { | 3701 | { |
3770 | static const char *txt_aux[] = {"Aux In", "Back Surr Out"}; | 3702 | static const char * const txt_aux[] = {"Aux In", "Back Surr Out"}; |
3771 | 3703 | ||
3772 | return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2); | 3704 | return snd_ctl_enum_info(uinfo, 1, 2, txt_aux); |
3773 | } | 3705 | } |
3774 | 3706 | ||
3775 | static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol, | 3707 | static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 47bf8dfe8276..d1ce151fe722 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
@@ -49,7 +49,7 @@ struct ac97_enum { | |||
49 | unsigned char shift_l; | 49 | unsigned char shift_l; |
50 | unsigned char shift_r; | 50 | unsigned char shift_r; |
51 | unsigned short mask; | 51 | unsigned short mask; |
52 | const char **texts; | 52 | const char * const *texts; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ | 55 | #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ |
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 5017176bfaa1..e9273fb2a505 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Asihpi soundcard | 2 | * Asihpi soundcard |
3 | * Copyright (c) by AudioScience Inc <alsa@audioscience.com> | 3 | * Copyright (c) by AudioScience Inc <support@audioscience.com> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of version 2 of the GNU General Public License as | 6 | * it under the terms of version 2 of the GNU General Public License as |
@@ -28,7 +28,6 @@ | |||
28 | #include "hpioctl.h" | 28 | #include "hpioctl.h" |
29 | #include "hpicmn.h" | 29 | #include "hpicmn.h" |
30 | 30 | ||
31 | |||
32 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
34 | #include <linux/jiffies.h> | 33 | #include <linux/jiffies.h> |
@@ -47,7 +46,7 @@ | |||
47 | 46 | ||
48 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
49 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); | 48 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); |
50 | MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx " | 49 | MODULE_DESCRIPTION("AudioScience ALSA ASI5xxx ASI6xxx ASI87xx ASI89xx " |
51 | HPI_VER_STRING); | 50 | HPI_VER_STRING); |
52 | 51 | ||
53 | #if defined CONFIG_SND_DEBUG_VERBOSE | 52 | #if defined CONFIG_SND_DEBUG_VERBOSE |
@@ -87,11 +86,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep, | |||
87 | #ifdef KERNEL_ALSA_BUILD | 86 | #ifdef KERNEL_ALSA_BUILD |
88 | static char *build_info = "Built using headers from kernel source"; | 87 | static char *build_info = "Built using headers from kernel source"; |
89 | module_param(build_info, charp, S_IRUGO); | 88 | module_param(build_info, charp, S_IRUGO); |
90 | MODULE_PARM_DESC(build_info, "built using headers from kernel source"); | 89 | MODULE_PARM_DESC(build_info, "Built using headers from kernel source"); |
91 | #else | 90 | #else |
92 | static char *build_info = "Built within ALSA source"; | 91 | static char *build_info = "Built within ALSA source"; |
93 | module_param(build_info, charp, S_IRUGO); | 92 | module_param(build_info, charp, S_IRUGO); |
94 | MODULE_PARM_DESC(build_info, "built within ALSA source"); | 93 | MODULE_PARM_DESC(build_info, "Built within ALSA source"); |
95 | #endif | 94 | #endif |
96 | 95 | ||
97 | /* set to 1 to dump every control from adapter to log */ | 96 | /* set to 1 to dump every control from adapter to log */ |
@@ -110,7 +109,7 @@ static int adapter_fs = DEFAULT_SAMPLERATE; | |||
110 | struct clk_source { | 109 | struct clk_source { |
111 | int source; | 110 | int source; |
112 | int index; | 111 | int index; |
113 | char *name; | 112 | const char *name; |
114 | }; | 113 | }; |
115 | 114 | ||
116 | struct clk_cache { | 115 | struct clk_cache { |
@@ -125,6 +124,16 @@ struct snd_card_asihpi { | |||
125 | struct pci_dev *pci; | 124 | struct pci_dev *pci; |
126 | struct hpi_adapter *hpi; | 125 | struct hpi_adapter *hpi; |
127 | 126 | ||
127 | /* In low latency mode there is only one stream, a pointer to its | ||
128 | * private data is stored here on trigger and cleared on stop. | ||
129 | * The interrupt handler uses it as a parameter when calling | ||
130 | * snd_card_asihpi_timer_function(). | ||
131 | */ | ||
132 | struct snd_card_asihpi_pcm *llmode_streampriv; | ||
133 | struct tasklet_struct t; | ||
134 | void (*pcm_start)(struct snd_pcm_substream *substream); | ||
135 | void (*pcm_stop)(struct snd_pcm_substream *substream); | ||
136 | |||
128 | u32 h_mixer; | 137 | u32 h_mixer; |
129 | struct clk_cache cc; | 138 | struct clk_cache cc; |
130 | 139 | ||
@@ -289,21 +298,17 @@ static void print_hwparams(struct snd_pcm_substream *substream, | |||
289 | { | 298 | { |
290 | char name[16]; | 299 | char name[16]; |
291 | snd_pcm_debug_name(substream, name, sizeof(name)); | 300 | snd_pcm_debug_name(substream, name, sizeof(name)); |
292 | snd_printd("%s HWPARAMS\n", name); | 301 | snd_printdd("%s HWPARAMS\n", name); |
293 | snd_printd(" samplerate %d Hz\n", params_rate(p)); | 302 | snd_printdd(" samplerate=%dHz channels=%d format=%d subformat=%d\n", |
294 | snd_printd(" channels %d\n", params_channels(p)); | 303 | params_rate(p), params_channels(p), |
295 | snd_printd(" format %d\n", params_format(p)); | 304 | params_format(p), params_subformat(p)); |
296 | snd_printd(" subformat %d\n", params_subformat(p)); | 305 | snd_printdd(" buffer=%dB period=%dB period_size=%dB periods=%d\n", |
297 | snd_printd(" buffer %d B\n", params_buffer_bytes(p)); | 306 | params_buffer_bytes(p), params_period_bytes(p), |
298 | snd_printd(" period %d B\n", params_period_bytes(p)); | 307 | params_period_size(p), params_periods(p)); |
299 | snd_printd(" access %d\n", params_access(p)); | 308 | snd_printdd(" buffer_size=%d access=%d data_rate=%dB/s\n", |
300 | snd_printd(" period_size %d\n", params_period_size(p)); | 309 | params_buffer_size(p), params_access(p), |
301 | snd_printd(" periods %d\n", params_periods(p)); | 310 | params_rate(p) * params_channels(p) * |
302 | snd_printd(" buffer_size %d\n", params_buffer_size(p)); | ||
303 | snd_printd(" %d B/s\n", params_rate(p) * | ||
304 | params_channels(p) * | ||
305 | snd_pcm_format_width(params_format(p)) / 8); | 311 | snd_pcm_format_width(params_format(p)) / 8); |
306 | |||
307 | } | 312 | } |
308 | 313 | ||
309 | static snd_pcm_format_t hpi_to_alsa_formats[] = { | 314 | static snd_pcm_format_t hpi_to_alsa_formats[] = { |
@@ -375,7 +380,7 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, | |||
375 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, | 380 | HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, |
376 | HPI_CONTROL_SAMPLECLOCK, &h_control); | 381 | HPI_CONTROL_SAMPLECLOCK, &h_control); |
377 | if (err) { | 382 | if (err) { |
378 | snd_printk(KERN_ERR | 383 | dev_err(&asihpi->pci->dev, |
379 | "No local sampleclock, err %d\n", err); | 384 | "No local sampleclock, err %d\n", err); |
380 | } | 385 | } |
381 | 386 | ||
@@ -481,7 +486,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
481 | params_buffer_bytes(params), runtime->dma_addr); | 486 | params_buffer_bytes(params), runtime->dma_addr); |
482 | if (err == 0) { | 487 | if (err == 0) { |
483 | snd_printdd( | 488 | snd_printdd( |
484 | "stream_host_buffer_attach succeeded %u %lu\n", | 489 | "stream_host_buffer_attach success %u %lu\n", |
485 | params_buffer_bytes(params), | 490 | params_buffer_bytes(params), |
486 | (unsigned long)runtime->dma_addr); | 491 | (unsigned long)runtime->dma_addr); |
487 | } else { | 492 | } else { |
@@ -491,12 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
491 | } | 496 | } |
492 | 497 | ||
493 | err = hpi_stream_get_info_ex(dpcm->h_stream, NULL, | 498 | err = hpi_stream_get_info_ex(dpcm->h_stream, NULL, |
494 | &dpcm->hpi_buffer_attached, | 499 | &dpcm->hpi_buffer_attached, NULL, NULL, NULL); |
495 | NULL, NULL, NULL); | ||
496 | |||
497 | snd_printdd("stream_host_buffer_attach status 0x%x\n", | ||
498 | dpcm->hpi_buffer_attached); | ||
499 | |||
500 | } | 500 | } |
501 | bytes_per_sec = params_rate(params) * params_channels(params); | 501 | bytes_per_sec = params_rate(params) * params_channels(params); |
502 | width = snd_pcm_format_width(params_format(params)); | 502 | width = snd_pcm_format_width(params_format(params)); |
@@ -538,7 +538,7 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * | |||
538 | int expiry; | 538 | int expiry; |
539 | 539 | ||
540 | expiry = HZ / 200; | 540 | expiry = HZ / 200; |
541 | /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */ | 541 | |
542 | expiry = max(expiry, 1); /* don't let it be zero! */ | 542 | expiry = max(expiry, 1); /* don't let it be zero! */ |
543 | dpcm->timer.expires = jiffies + expiry; | 543 | dpcm->timer.expires = jiffies + expiry; |
544 | dpcm->respawn_timer = 1; | 544 | dpcm->respawn_timer = 1; |
@@ -554,6 +554,48 @@ static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream) | |||
554 | del_timer(&dpcm->timer); | 554 | del_timer(&dpcm->timer); |
555 | } | 555 | } |
556 | 556 | ||
557 | static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream) | ||
558 | { | ||
559 | struct snd_card_asihpi_pcm *dpcm; | ||
560 | struct snd_card_asihpi *card; | ||
561 | |||
562 | BUG_ON(!substream); | ||
563 | |||
564 | dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; | ||
565 | card = snd_pcm_substream_chip(substream); | ||
566 | |||
567 | BUG_ON(in_interrupt()); | ||
568 | tasklet_disable(&card->t); | ||
569 | card->llmode_streampriv = dpcm; | ||
570 | tasklet_enable(&card->t); | ||
571 | |||
572 | hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, | ||
573 | HPI_ADAPTER_PROPERTY_IRQ_RATE, | ||
574 | card->update_interval_frames, 0)); | ||
575 | } | ||
576 | |||
577 | static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream) | ||
578 | { | ||
579 | struct snd_card_asihpi_pcm *dpcm; | ||
580 | struct snd_card_asihpi *card; | ||
581 | |||
582 | BUG_ON(!substream); | ||
583 | |||
584 | dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; | ||
585 | card = snd_pcm_substream_chip(substream); | ||
586 | |||
587 | hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, | ||
588 | HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); | ||
589 | |||
590 | if (in_interrupt()) | ||
591 | card->llmode_streampriv = NULL; | ||
592 | else { | ||
593 | tasklet_disable(&card->t); | ||
594 | card->llmode_streampriv = NULL; | ||
595 | tasklet_enable(&card->t); | ||
596 | } | ||
597 | } | ||
598 | |||
557 | static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | 599 | static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, |
558 | int cmd) | 600 | int cmd) |
559 | { | 601 | { |
@@ -564,10 +606,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
564 | char name[16]; | 606 | char name[16]; |
565 | 607 | ||
566 | snd_pcm_debug_name(substream, name, sizeof(name)); | 608 | snd_pcm_debug_name(substream, name, sizeof(name)); |
567 | snd_printdd("%s trigger\n", name); | ||
568 | 609 | ||
569 | switch (cmd) { | 610 | switch (cmd) { |
570 | case SNDRV_PCM_TRIGGER_START: | 611 | case SNDRV_PCM_TRIGGER_START: |
612 | snd_printdd("%s trigger start\n", name); | ||
571 | snd_pcm_group_for_each_entry(s, substream) { | 613 | snd_pcm_group_for_each_entry(s, substream) { |
572 | struct snd_pcm_runtime *runtime = s->runtime; | 614 | struct snd_pcm_runtime *runtime = s->runtime; |
573 | struct snd_card_asihpi_pcm *ds = runtime->private_data; | 615 | struct snd_card_asihpi_pcm *ds = runtime->private_data; |
@@ -588,7 +630,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
588 | * data?? | 630 | * data?? |
589 | */ | 631 | */ |
590 | unsigned int preload = ds->period_bytes * 1; | 632 | unsigned int preload = ds->period_bytes * 1; |
591 | snd_printddd("%d preload x%x\n", s->number, preload); | 633 | snd_printddd("%d preload %d\n", s->number, preload); |
592 | hpi_handle_error(hpi_outstream_write_buf( | 634 | hpi_handle_error(hpi_outstream_write_buf( |
593 | ds->h_stream, | 635 | ds->h_stream, |
594 | &runtime->dma_area[0], | 636 | &runtime->dma_area[0], |
@@ -611,16 +653,16 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
611 | } else | 653 | } else |
612 | break; | 654 | break; |
613 | } | 655 | } |
614 | snd_printdd("start\n"); | ||
615 | /* start the master stream */ | 656 | /* start the master stream */ |
616 | snd_card_asihpi_pcm_timer_start(substream); | 657 | card->pcm_start(substream); |
617 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || | 658 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || |
618 | !card->can_dma) | 659 | !card->can_dma) |
619 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); | 660 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); |
620 | break; | 661 | break; |
621 | 662 | ||
622 | case SNDRV_PCM_TRIGGER_STOP: | 663 | case SNDRV_PCM_TRIGGER_STOP: |
623 | snd_card_asihpi_pcm_timer_stop(substream); | 664 | snd_printdd("%s trigger stop\n", name); |
665 | card->pcm_stop(substream); | ||
624 | snd_pcm_group_for_each_entry(s, substream) { | 666 | snd_pcm_group_for_each_entry(s, substream) { |
625 | if (snd_pcm_substream_chip(s) != card) | 667 | if (snd_pcm_substream_chip(s) != card) |
626 | continue; | 668 | continue; |
@@ -638,7 +680,6 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
638 | } else | 680 | } else |
639 | break; | 681 | break; |
640 | } | 682 | } |
641 | snd_printdd("stop\n"); | ||
642 | 683 | ||
643 | /* _prepare and _hwparams reset the stream */ | 684 | /* _prepare and _hwparams reset the stream */ |
644 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); | 685 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
@@ -651,13 +692,13 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
651 | break; | 692 | break; |
652 | 693 | ||
653 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 694 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
654 | snd_printdd("pause release\n"); | 695 | snd_printdd("%s trigger pause release\n", name); |
696 | card->pcm_start(substream); | ||
655 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); | 697 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); |
656 | snd_card_asihpi_pcm_timer_start(substream); | ||
657 | break; | 698 | break; |
658 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 699 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
659 | snd_printdd("pause\n"); | 700 | snd_printdd("%s trigger pause push\n", name); |
660 | snd_card_asihpi_pcm_timer_stop(substream); | 701 | card->pcm_stop(substream); |
661 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); | 702 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
662 | break; | 703 | break; |
663 | default: | 704 | default: |
@@ -729,9 +770,8 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
729 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; | 770 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; |
730 | char name[16]; | 771 | char name[16]; |
731 | 772 | ||
732 | snd_pcm_debug_name(substream, name, sizeof(name)); | ||
733 | 773 | ||
734 | snd_printdd("%s snd_card_asihpi_timer_function\n", name); | 774 | snd_pcm_debug_name(substream, name, sizeof(name)); |
735 | 775 | ||
736 | /* find minimum newdata and buffer pos in group */ | 776 | /* find minimum newdata and buffer pos in group */ |
737 | snd_pcm_group_for_each_entry(s, substream) { | 777 | snd_pcm_group_for_each_entry(s, substream) { |
@@ -769,10 +809,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
769 | s->number); | 809 | s->number); |
770 | ds->drained_count++; | 810 | ds->drained_count++; |
771 | if (ds->drained_count > 20) { | 811 | if (ds->drained_count > 20) { |
772 | unsigned long flags; | 812 | snd_pcm_stop_xrun(s); |
773 | snd_pcm_stream_lock_irqsave(s, flags); | ||
774 | snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | ||
775 | snd_pcm_stream_unlock_irqrestore(s, flags); | ||
776 | continue; | 813 | continue; |
777 | } | 814 | } |
778 | } else { | 815 | } else { |
@@ -794,19 +831,21 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
794 | newdata); | 831 | newdata); |
795 | } | 832 | } |
796 | 833 | ||
797 | snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n", | 834 | snd_printddd( |
835 | "timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n", | ||
836 | name, s->number, state, | ||
837 | ds->pcm_buf_elapsed_dma_ofs, | ||
838 | ds->pcm_buf_host_rw_ofs, | ||
839 | pcm_buf_dma_ofs, | ||
840 | (int)bytes_avail, | ||
841 | |||
842 | (int)on_card_bytes, | ||
843 | buffer_size-bytes_avail, | ||
798 | (unsigned long)frames_to_bytes(runtime, | 844 | (unsigned long)frames_to_bytes(runtime, |
799 | runtime->status->hw_ptr), | 845 | runtime->status->hw_ptr), |
800 | (unsigned long)frames_to_bytes(runtime, | 846 | (unsigned long)frames_to_bytes(runtime, |
801 | runtime->control->appl_ptr)); | 847 | runtime->control->appl_ptr) |
802 | 848 | ); | |
803 | snd_printdd("%d S=%d, " | ||
804 | "rw=0x%04X, dma=0x%04X, left=0x%04X, " | ||
805 | "aux=0x%04X space=0x%04X\n", | ||
806 | s->number, state, | ||
807 | ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, | ||
808 | (int)bytes_avail, | ||
809 | (int)on_card_bytes, buffer_size-bytes_avail); | ||
810 | loops++; | 849 | loops++; |
811 | } | 850 | } |
812 | pcm_buf_dma_ofs = min_buf_pos; | 851 | pcm_buf_dma_ofs = min_buf_pos; |
@@ -824,16 +863,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
824 | 863 | ||
825 | next_jiffies = max(next_jiffies, 1U); | 864 | next_jiffies = max(next_jiffies, 1U); |
826 | dpcm->timer.expires = jiffies + next_jiffies; | 865 | dpcm->timer.expires = jiffies + next_jiffies; |
827 | snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n", | 866 | snd_printddd("timer2, jif=%d, buf_pos=%d, newdata=%d, xfer=%d\n", |
828 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); | 867 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); |
829 | 868 | ||
830 | snd_pcm_group_for_each_entry(s, substream) { | 869 | snd_pcm_group_for_each_entry(s, substream) { |
831 | struct snd_card_asihpi_pcm *ds = s->runtime->private_data; | 870 | struct snd_card_asihpi_pcm *ds = s->runtime->private_data; |
871 | runtime = s->runtime; | ||
832 | 872 | ||
833 | /* don't link Cap and Play */ | 873 | /* don't link Cap and Play */ |
834 | if (substream->stream != s->stream) | 874 | if (substream->stream != s->stream) |
835 | continue; | 875 | continue; |
836 | 876 | ||
877 | /* Store dma offset for use by pointer callback */ | ||
837 | ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; | 878 | ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; |
838 | 879 | ||
839 | if (xfercount && | 880 | if (xfercount && |
@@ -856,7 +897,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
856 | } | 897 | } |
857 | 898 | ||
858 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 899 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
859 | snd_printddd("P%d write1 0x%04X 0x%04X\n", | 900 | snd_printddd("write1, P=%d, xfer=%d, buf_ofs=%d\n", |
860 | s->number, xfer1, buf_ofs); | 901 | s->number, xfer1, buf_ofs); |
861 | hpi_handle_error( | 902 | hpi_handle_error( |
862 | hpi_outstream_write_buf( | 903 | hpi_outstream_write_buf( |
@@ -866,7 +907,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
866 | if (xfer2) { | 907 | if (xfer2) { |
867 | pd = s->runtime->dma_area; | 908 | pd = s->runtime->dma_area; |
868 | 909 | ||
869 | snd_printddd("P%d write2 0x%04X 0x%04X\n", | 910 | snd_printddd("write2, P=%d, xfer=%d, buf_ofs=%d\n", |
870 | s->number, | 911 | s->number, |
871 | xfercount - xfer1, buf_ofs); | 912 | xfercount - xfer1, buf_ofs); |
872 | hpi_handle_error( | 913 | hpi_handle_error( |
@@ -876,7 +917,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
876 | &ds->format)); | 917 | &ds->format)); |
877 | } | 918 | } |
878 | } else { | 919 | } else { |
879 | snd_printddd("C%d read1 0x%04x\n", | 920 | snd_printddd("read1, C=%d, xfer=%d\n", |
880 | s->number, xfer1); | 921 | s->number, xfer1); |
881 | hpi_handle_error( | 922 | hpi_handle_error( |
882 | hpi_instream_read_buf( | 923 | hpi_instream_read_buf( |
@@ -884,7 +925,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
884 | pd, xfer1)); | 925 | pd, xfer1)); |
885 | if (xfer2) { | 926 | if (xfer2) { |
886 | pd = s->runtime->dma_area; | 927 | pd = s->runtime->dma_area; |
887 | snd_printddd("C%d read2 0x%04x\n", | 928 | snd_printddd("read2, C=%d, xfer=%d\n", |
888 | s->number, xfer2); | 929 | s->number, xfer2); |
889 | hpi_handle_error( | 930 | hpi_handle_error( |
890 | hpi_instream_read_buf( | 931 | hpi_instream_read_buf( |
@@ -892,16 +933,38 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
892 | pd, xfer2)); | 933 | pd, xfer2)); |
893 | } | 934 | } |
894 | } | 935 | } |
936 | /* ? host_rw_ofs always ahead of elapsed_dma_ofs by preload size? */ | ||
895 | ds->pcm_buf_host_rw_ofs += xfercount; | 937 | ds->pcm_buf_host_rw_ofs += xfercount; |
896 | ds->pcm_buf_elapsed_dma_ofs += xfercount; | 938 | ds->pcm_buf_elapsed_dma_ofs += xfercount; |
897 | snd_pcm_period_elapsed(s); | 939 | snd_pcm_period_elapsed(s); |
898 | } | 940 | } |
899 | } | 941 | } |
900 | 942 | ||
901 | if (dpcm->respawn_timer) | 943 | if (!card->hpi->interrupt_mode && dpcm->respawn_timer) |
902 | add_timer(&dpcm->timer); | 944 | add_timer(&dpcm->timer); |
903 | } | 945 | } |
904 | 946 | ||
947 | static void snd_card_asihpi_int_task(unsigned long data) | ||
948 | { | ||
949 | struct hpi_adapter *a = (struct hpi_adapter *)data; | ||
950 | struct snd_card_asihpi *asihpi; | ||
951 | |||
952 | WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); | ||
953 | asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; | ||
954 | if (asihpi->llmode_streampriv) | ||
955 | snd_card_asihpi_timer_function( | ||
956 | (unsigned long)asihpi->llmode_streampriv); | ||
957 | } | ||
958 | |||
959 | static void snd_card_asihpi_isr(struct hpi_adapter *a) | ||
960 | { | ||
961 | struct snd_card_asihpi *asihpi; | ||
962 | |||
963 | WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); | ||
964 | asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; | ||
965 | tasklet_schedule(&asihpi->t); | ||
966 | } | ||
967 | |||
905 | /***************************** PLAYBACK OPS ****************/ | 968 | /***************************** PLAYBACK OPS ****************/ |
906 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, | 969 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, |
907 | unsigned int cmd, void *arg) | 970 | unsigned int cmd, void *arg) |
@@ -937,7 +1000,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) | |||
937 | snd_pcm_debug_name(substream, name, sizeof(name)); | 1000 | snd_pcm_debug_name(substream, name, sizeof(name)); |
938 | 1001 | ||
939 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); | 1002 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); |
940 | snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr); | 1003 | snd_printddd("%s, pointer=%ld\n", name, (unsigned long)ptr); |
941 | return ptr; | 1004 | return ptr; |
942 | } | 1005 | } |
943 | 1006 | ||
@@ -1009,13 +1072,22 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
1009 | runtime->private_free = snd_card_asihpi_runtime_free; | 1072 | runtime->private_free = snd_card_asihpi_runtime_free; |
1010 | 1073 | ||
1011 | memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback)); | 1074 | memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback)); |
1012 | snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; | 1075 | if (!card->hpi->interrupt_mode) { |
1013 | snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN; | 1076 | snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; |
1014 | /*?snd_card_asihpi_playback.period_bytes_min = | 1077 | snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN; |
1015 | card->out_max_chans * 4096; */ | 1078 | snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; |
1016 | snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; | 1079 | snd_card_asihpi_playback.periods_min = PERIODS_MIN; |
1017 | snd_card_asihpi_playback.periods_min = PERIODS_MIN; | 1080 | snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; |
1018 | snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; | 1081 | } else { |
1082 | size_t pbmin = card->update_interval_frames * | ||
1083 | card->out_max_chans; | ||
1084 | snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; | ||
1085 | snd_card_asihpi_playback.period_bytes_min = pbmin; | ||
1086 | snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; | ||
1087 | snd_card_asihpi_playback.periods_min = PERIODS_MIN; | ||
1088 | snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / pbmin; | ||
1089 | } | ||
1090 | |||
1019 | /* snd_card_asihpi_playback.fifo_size = 0; */ | 1091 | /* snd_card_asihpi_playback.fifo_size = 0; */ |
1020 | snd_card_asihpi_playback.channels_max = card->out_max_chans; | 1092 | snd_card_asihpi_playback.channels_max = card->out_max_chans; |
1021 | snd_card_asihpi_playback.channels_min = card->out_min_chans; | 1093 | snd_card_asihpi_playback.channels_min = card->out_min_chans; |
@@ -1050,7 +1122,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
1050 | card->update_interval_frames); | 1122 | card->update_interval_frames); |
1051 | 1123 | ||
1052 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1124 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1053 | card->update_interval_frames * 2, UINT_MAX); | 1125 | card->update_interval_frames, UINT_MAX); |
1054 | 1126 | ||
1055 | snd_printdd("playback open\n"); | 1127 | snd_printdd("playback open\n"); |
1056 | 1128 | ||
@@ -1085,9 +1157,10 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream) | |||
1085 | { | 1157 | { |
1086 | struct snd_pcm_runtime *runtime = substream->runtime; | 1158 | struct snd_pcm_runtime *runtime = substream->runtime; |
1087 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1159 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1160 | char name[16]; | ||
1161 | snd_pcm_debug_name(substream, name, sizeof(name)); | ||
1088 | 1162 | ||
1089 | snd_printddd("capture pointer %d=%d\n", | 1163 | snd_printddd("%s, pointer=%d\n", name, dpcm->pcm_buf_dma_ofs); |
1090 | substream->number, dpcm->pcm_buf_dma_ofs); | ||
1091 | /* NOTE Unlike playback can't use actual samples_played | 1164 | /* NOTE Unlike playback can't use actual samples_played |
1092 | for the capture position, because those samples aren't yet in | 1165 | for the capture position, because those samples aren't yet in |
1093 | the local buffer available for reading. | 1166 | the local buffer available for reading. |
@@ -1115,8 +1188,6 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) | |||
1115 | return 0; | 1188 | return 0; |
1116 | } | 1189 | } |
1117 | 1190 | ||
1118 | |||
1119 | |||
1120 | static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, | 1191 | static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, |
1121 | u32 h_stream) | 1192 | u32 h_stream) |
1122 | { | 1193 | { |
@@ -1183,11 +1254,21 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1183 | runtime->private_free = snd_card_asihpi_runtime_free; | 1254 | runtime->private_free = snd_card_asihpi_runtime_free; |
1184 | 1255 | ||
1185 | memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture)); | 1256 | memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture)); |
1186 | snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; | 1257 | if (!card->hpi->interrupt_mode) { |
1187 | snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN; | 1258 | snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; |
1188 | snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; | 1259 | snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN; |
1189 | snd_card_asihpi_capture.periods_min = PERIODS_MIN; | 1260 | snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; |
1190 | snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; | 1261 | snd_card_asihpi_capture.periods_min = PERIODS_MIN; |
1262 | snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; | ||
1263 | } else { | ||
1264 | size_t pbmin = card->update_interval_frames * | ||
1265 | card->out_max_chans; | ||
1266 | snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; | ||
1267 | snd_card_asihpi_capture.period_bytes_min = pbmin; | ||
1268 | snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; | ||
1269 | snd_card_asihpi_capture.periods_min = PERIODS_MIN; | ||
1270 | snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / pbmin; | ||
1271 | } | ||
1191 | /* snd_card_asihpi_capture.fifo_size = 0; */ | 1272 | /* snd_card_asihpi_capture.fifo_size = 0; */ |
1192 | snd_card_asihpi_capture.channels_max = card->in_max_chans; | 1273 | snd_card_asihpi_capture.channels_max = card->in_max_chans; |
1193 | snd_card_asihpi_capture.channels_min = card->in_min_chans; | 1274 | snd_card_asihpi_capture.channels_min = card->in_min_chans; |
@@ -1212,7 +1293,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1212 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1293 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1213 | card->update_interval_frames); | 1294 | card->update_interval_frames); |
1214 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1295 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1215 | card->update_interval_frames * 2, UINT_MAX); | 1296 | card->update_interval_frames, UINT_MAX); |
1216 | 1297 | ||
1217 | snd_pcm_set_sync(substream); | 1298 | snd_pcm_set_sync(substream); |
1218 | 1299 | ||
@@ -1296,8 +1377,9 @@ static const char * const asihpi_tuner_band_names[] = { | |||
1296 | "TV PAL I", | 1377 | "TV PAL I", |
1297 | "TV PAL DK", | 1378 | "TV PAL DK", |
1298 | "TV SECAM", | 1379 | "TV SECAM", |
1380 | "TV DAB", | ||
1299 | }; | 1381 | }; |
1300 | 1382 | /* Number of strings must match the enumerations for HPI_TUNER_BAND in hpi.h */ | |
1301 | compile_time_assert( | 1383 | compile_time_assert( |
1302 | (ARRAY_SIZE(asihpi_tuner_band_names) == | 1384 | (ARRAY_SIZE(asihpi_tuner_band_names) == |
1303 | (HPI_TUNER_BAND_LAST+1)), | 1385 | (HPI_TUNER_BAND_LAST+1)), |
@@ -1317,9 +1399,11 @@ static const char * const asihpi_src_names[] = { | |||
1317 | "Analog", | 1399 | "Analog", |
1318 | "Adapter", | 1400 | "Adapter", |
1319 | "RTP", | 1401 | "RTP", |
1320 | "Internal" | 1402 | "Internal", |
1403 | "AVB", | ||
1404 | "BLU-Link" | ||
1321 | }; | 1405 | }; |
1322 | 1406 | /* Number of strings must match the enumerations for HPI_SOURCENODES in hpi.h */ | |
1323 | compile_time_assert( | 1407 | compile_time_assert( |
1324 | (ARRAY_SIZE(asihpi_src_names) == | 1408 | (ARRAY_SIZE(asihpi_src_names) == |
1325 | (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), | 1409 | (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), |
@@ -1335,8 +1419,11 @@ static const char * const asihpi_dst_names[] = { | |||
1335 | "Net", | 1419 | "Net", |
1336 | "Analog", | 1420 | "Analog", |
1337 | "RTP", | 1421 | "RTP", |
1422 | "AVB", | ||
1423 | "Internal", | ||
1424 | "BLU-Link" | ||
1338 | }; | 1425 | }; |
1339 | 1426 | /* Number of strings must match the enumerations for HPI_DESTNODES in hpi.h */ | |
1340 | compile_time_assert( | 1427 | compile_time_assert( |
1341 | (ARRAY_SIZE(asihpi_dst_names) == | 1428 | (ARRAY_SIZE(asihpi_dst_names) == |
1342 | (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)), | 1429 | (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)), |
@@ -1351,7 +1438,7 @@ static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl, | |||
1351 | if (err < 0) | 1438 | if (err < 0) |
1352 | return err; | 1439 | return err; |
1353 | else if (mixer_dump) | 1440 | else if (mixer_dump) |
1354 | snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index); | 1441 | dev_info(&asihpi->pci->dev, "added %s(%d)\n", ctl->name, ctl->index); |
1355 | 1442 | ||
1356 | return 0; | 1443 | return 0; |
1357 | } | 1444 | } |
@@ -1625,18 +1712,7 @@ static const char * const asihpi_aesebu_format_names[] = { | |||
1625 | static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, | 1712 | static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, |
1626 | struct snd_ctl_elem_info *uinfo) | 1713 | struct snd_ctl_elem_info *uinfo) |
1627 | { | 1714 | { |
1628 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1715 | return snd_ctl_enum_info(uinfo, 1, 3, asihpi_aesebu_format_names); |
1629 | uinfo->count = 1; | ||
1630 | uinfo->value.enumerated.items = 3; | ||
1631 | |||
1632 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1633 | uinfo->value.enumerated.item = | ||
1634 | uinfo->value.enumerated.items - 1; | ||
1635 | |||
1636 | strcpy(uinfo->value.enumerated.name, | ||
1637 | asihpi_aesebu_format_names[uinfo->value.enumerated.item]); | ||
1638 | |||
1639 | return 0; | ||
1640 | } | 1716 | } |
1641 | 1717 | ||
1642 | static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, | 1718 | static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, |
@@ -1863,22 +1939,7 @@ static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol, | |||
1863 | if (num_bands < 0) | 1939 | if (num_bands < 0) |
1864 | return num_bands; | 1940 | return num_bands; |
1865 | 1941 | ||
1866 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1942 | return snd_ctl_enum_info(uinfo, 1, num_bands, asihpi_tuner_band_names); |
1867 | uinfo->count = 1; | ||
1868 | uinfo->value.enumerated.items = num_bands; | ||
1869 | |||
1870 | if (num_bands > 0) { | ||
1871 | if (uinfo->value.enumerated.item >= | ||
1872 | uinfo->value.enumerated.items) | ||
1873 | uinfo->value.enumerated.item = | ||
1874 | uinfo->value.enumerated.items - 1; | ||
1875 | |||
1876 | strcpy(uinfo->value.enumerated.name, | ||
1877 | asihpi_tuner_band_names[ | ||
1878 | tuner_bands[uinfo->value.enumerated.item]]); | ||
1879 | |||
1880 | } | ||
1881 | return 0; | ||
1882 | } | 1943 | } |
1883 | 1944 | ||
1884 | static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol, | 1945 | static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol, |
@@ -2253,7 +2314,7 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, | |||
2253 | u32 h_control = kcontrol->private_value; | 2314 | u32 h_control = kcontrol->private_value; |
2254 | u16 mode; | 2315 | u16 mode; |
2255 | int i; | 2316 | int i; |
2256 | u16 mode_map[6]; | 2317 | const char *mapped_names[6]; |
2257 | int valid_modes = 0; | 2318 | int valid_modes = 0; |
2258 | 2319 | ||
2259 | /* HPI channel mode values can be from 1 to 6 | 2320 | /* HPI channel mode values can be from 1 to 6 |
@@ -2262,24 +2323,14 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, | |||
2262 | for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) | 2323 | for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) |
2263 | if (!hpi_channel_mode_query_mode( | 2324 | if (!hpi_channel_mode_query_mode( |
2264 | h_control, i, &mode)) { | 2325 | h_control, i, &mode)) { |
2265 | mode_map[valid_modes] = mode; | 2326 | mapped_names[valid_modes] = mode_names[mode]; |
2266 | valid_modes++; | 2327 | valid_modes++; |
2267 | } | 2328 | } |
2268 | 2329 | ||
2269 | if (!valid_modes) | 2330 | if (!valid_modes) |
2270 | return -EINVAL; | 2331 | return -EINVAL; |
2271 | 2332 | ||
2272 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2333 | return snd_ctl_enum_info(uinfo, 1, valid_modes, mapped_names); |
2273 | uinfo->count = 1; | ||
2274 | uinfo->value.enumerated.items = valid_modes; | ||
2275 | |||
2276 | if (uinfo->value.enumerated.item >= valid_modes) | ||
2277 | uinfo->value.enumerated.item = valid_modes - 1; | ||
2278 | |||
2279 | strcpy(uinfo->value.enumerated.name, | ||
2280 | mode_names[mode_map[uinfo->value.enumerated.item]]); | ||
2281 | |||
2282 | return 0; | ||
2283 | } | 2334 | } |
2284 | 2335 | ||
2285 | static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol, | 2336 | static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol, |
@@ -2328,13 +2379,18 @@ static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi, | |||
2328 | /*------------------------------------------------------------ | 2379 | /*------------------------------------------------------------ |
2329 | Sampleclock source controls | 2380 | Sampleclock source controls |
2330 | ------------------------------------------------------------*/ | 2381 | ------------------------------------------------------------*/ |
2331 | static char *sampleclock_sources[MAX_CLOCKSOURCES] = { | 2382 | static const char const *sampleclock_sources[] = { |
2332 | "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header", | 2383 | "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header", |
2333 | "SMPTE", "Digital1", "Auto", "Network", "Invalid", | 2384 | "SMPTE", "Digital1", "Auto", "Network", "Invalid", |
2334 | "Prev Module", | 2385 | "Prev Module", "BLU-Link", |
2335 | "Digital2", "Digital3", "Digital4", "Digital5", | 2386 | "Digital2", "Digital3", "Digital4", "Digital5", |
2336 | "Digital6", "Digital7", "Digital8"}; | 2387 | "Digital6", "Digital7", "Digital8"}; |
2337 | 2388 | ||
2389 | /* Number of strings must match expected enumerated values */ | ||
2390 | compile_time_assert( | ||
2391 | (ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES), | ||
2392 | assert_sampleclock_sources_size); | ||
2393 | |||
2338 | static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, | 2394 | static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, |
2339 | struct snd_ctl_elem_info *uinfo) | 2395 | struct snd_ctl_elem_info *uinfo) |
2340 | { | 2396 | { |
@@ -2482,15 +2538,19 @@ static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol, | |||
2482 | static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, | 2538 | static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, |
2483 | struct hpi_control *hpi_ctl) | 2539 | struct hpi_control *hpi_ctl) |
2484 | { | 2540 | { |
2485 | struct snd_card *card = asihpi->card; | 2541 | struct snd_card *card; |
2486 | struct snd_kcontrol_new snd_control; | 2542 | struct snd_kcontrol_new snd_control; |
2487 | 2543 | ||
2488 | struct clk_cache *clkcache = &asihpi->cc; | 2544 | struct clk_cache *clkcache; |
2489 | u32 hSC = hpi_ctl->h_control; | 2545 | u32 hSC = hpi_ctl->h_control; |
2490 | int has_aes_in = 0; | 2546 | int has_aes_in = 0; |
2491 | int i, j; | 2547 | int i, j; |
2492 | u16 source; | 2548 | u16 source; |
2493 | 2549 | ||
2550 | if (snd_BUG_ON(!asihpi)) | ||
2551 | return -EINVAL; | ||
2552 | card = asihpi->card; | ||
2553 | clkcache = &asihpi->cc; | ||
2494 | snd_control.private_value = hpi_ctl->h_control; | 2554 | snd_control.private_value = hpi_ctl->h_control; |
2495 | 2555 | ||
2496 | clkcache->has_local = 0; | 2556 | clkcache->has_local = 0; |
@@ -2592,7 +2652,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2592 | if (err) { | 2652 | if (err) { |
2593 | if (err == HPI_ERROR_CONTROL_DISABLED) { | 2653 | if (err == HPI_ERROR_CONTROL_DISABLED) { |
2594 | if (mixer_dump) | 2654 | if (mixer_dump) |
2595 | snd_printk(KERN_INFO | 2655 | dev_info(&asihpi->pci->dev, |
2596 | "Disabled HPI Control(%d)\n", | 2656 | "Disabled HPI Control(%d)\n", |
2597 | idx); | 2657 | idx); |
2598 | continue; | 2658 | continue; |
@@ -2657,9 +2717,8 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2657 | case HPI_CONTROL_COMPANDER: | 2717 | case HPI_CONTROL_COMPANDER: |
2658 | default: | 2718 | default: |
2659 | if (mixer_dump) | 2719 | if (mixer_dump) |
2660 | snd_printk(KERN_INFO | 2720 | dev_info(&asihpi->pci->dev, |
2661 | "Untranslated HPI Control" | 2721 | "Untranslated HPI Control (%d) %d %d %d %d %d\n", |
2662 | "(%d) %d %d %d %d %d\n", | ||
2663 | idx, | 2722 | idx, |
2664 | hpi_ctl.control_type, | 2723 | hpi_ctl.control_type, |
2665 | hpi_ctl.src_node_type, | 2724 | hpi_ctl.src_node_type, |
@@ -2674,7 +2733,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2674 | if (HPI_ERROR_INVALID_OBJ_INDEX != err) | 2733 | if (HPI_ERROR_INVALID_OBJ_INDEX != err) |
2675 | hpi_handle_error(err); | 2734 | hpi_handle_error(err); |
2676 | 2735 | ||
2677 | snd_printk(KERN_INFO "%d mixer controls found\n", idx); | 2736 | dev_info(&asihpi->pci->dev, "%d mixer controls found\n", idx); |
2678 | 2737 | ||
2679 | return 0; | 2738 | return 0; |
2680 | } | 2739 | } |
@@ -2837,8 +2896,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2837 | &card); | 2896 | &card); |
2838 | if (err < 0) | 2897 | if (err < 0) |
2839 | return err; | 2898 | return err; |
2840 | snd_printk(KERN_WARNING | 2899 | dev_warn(&pci_dev->dev, "Adapter index %d->ALSA index %d\n", |
2841 | "**** WARNING **** Adapter index %d->ALSA index %d\n", | ||
2842 | adapter_index, card->number); | 2900 | adapter_index, card->number); |
2843 | } | 2901 | } |
2844 | 2902 | ||
@@ -2846,9 +2904,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2846 | asihpi->card = card; | 2904 | asihpi->card = card; |
2847 | asihpi->pci = pci_dev; | 2905 | asihpi->pci = pci_dev; |
2848 | asihpi->hpi = hpi; | 2906 | asihpi->hpi = hpi; |
2849 | 2907 | hpi->snd_card = card; | |
2850 | snd_printk(KERN_INFO "adapter ID=%4X index=%d\n", | ||
2851 | asihpi->hpi->adapter->type, adapter_index); | ||
2852 | 2908 | ||
2853 | err = hpi_adapter_get_property(adapter_index, | 2909 | err = hpi_adapter_get_property(adapter_index, |
2854 | HPI_ADAPTER_PROPERTY_CAPS1, | 2910 | HPI_ADAPTER_PROPERTY_CAPS1, |
@@ -2868,8 +2924,16 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2868 | if (err) | 2924 | if (err) |
2869 | asihpi->update_interval_frames = 512; | 2925 | asihpi->update_interval_frames = 512; |
2870 | 2926 | ||
2871 | if (!asihpi->can_dma) | 2927 | if (hpi->interrupt_mode) { |
2872 | asihpi->update_interval_frames *= 2; | 2928 | asihpi->pcm_start = snd_card_asihpi_pcm_int_start; |
2929 | asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop; | ||
2930 | tasklet_init(&asihpi->t, snd_card_asihpi_int_task, | ||
2931 | (unsigned long)hpi); | ||
2932 | hpi->interrupt_callback = snd_card_asihpi_isr; | ||
2933 | } else { | ||
2934 | asihpi->pcm_start = snd_card_asihpi_pcm_timer_start; | ||
2935 | asihpi->pcm_stop = snd_card_asihpi_pcm_timer_stop; | ||
2936 | } | ||
2873 | 2937 | ||
2874 | hpi_handle_error(hpi_instream_open(adapter_index, | 2938 | hpi_handle_error(hpi_instream_open(adapter_index, |
2875 | 0, &h_stream)); | 2939 | 0, &h_stream)); |
@@ -2879,6 +2943,9 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2879 | 2943 | ||
2880 | hpi_handle_error(hpi_instream_close(h_stream)); | 2944 | hpi_handle_error(hpi_instream_close(h_stream)); |
2881 | 2945 | ||
2946 | if (!asihpi->can_dma) | ||
2947 | asihpi->update_interval_frames *= 2; | ||
2948 | |||
2882 | err = hpi_adapter_get_property(adapter_index, | 2949 | err = hpi_adapter_get_property(adapter_index, |
2883 | HPI_ADAPTER_PROPERTY_CURCHANNELS, | 2950 | HPI_ADAPTER_PROPERTY_CURCHANNELS, |
2884 | &asihpi->in_max_chans, &asihpi->out_max_chans); | 2951 | &asihpi->in_max_chans, &asihpi->out_max_chans); |
@@ -2896,20 +2963,21 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2896 | asihpi->in_min_chans = 1; | 2963 | asihpi->in_min_chans = 1; |
2897 | } | 2964 | } |
2898 | 2965 | ||
2899 | snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n", | 2966 | dev_info(&pci_dev->dev, "Has dma:%d, grouping:%d, mrx:%d, uif:%d\n", |
2900 | asihpi->can_dma, | 2967 | asihpi->can_dma, |
2901 | asihpi->support_grouping, | 2968 | asihpi->support_grouping, |
2902 | asihpi->support_mrx | 2969 | asihpi->support_mrx, |
2970 | asihpi->update_interval_frames | ||
2903 | ); | 2971 | ); |
2904 | 2972 | ||
2905 | err = snd_card_asihpi_pcm_new(asihpi, 0); | 2973 | err = snd_card_asihpi_pcm_new(asihpi, 0); |
2906 | if (err < 0) { | 2974 | if (err < 0) { |
2907 | snd_printk(KERN_ERR "pcm_new failed\n"); | 2975 | dev_err(&pci_dev->dev, "pcm_new failed\n"); |
2908 | goto __nodev; | 2976 | goto __nodev; |
2909 | } | 2977 | } |
2910 | err = snd_card_asihpi_mixer_new(asihpi); | 2978 | err = snd_card_asihpi_mixer_new(asihpi); |
2911 | if (err < 0) { | 2979 | if (err < 0) { |
2912 | snd_printk(KERN_ERR "mixer_new failed\n"); | 2980 | dev_err(&pci_dev->dev, "mixer_new failed\n"); |
2913 | goto __nodev; | 2981 | goto __nodev; |
2914 | } | 2982 | } |
2915 | 2983 | ||
@@ -2936,13 +3004,12 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2936 | err = snd_card_register(card); | 3004 | err = snd_card_register(card); |
2937 | 3005 | ||
2938 | if (!err) { | 3006 | if (!err) { |
2939 | hpi->snd_card = card; | ||
2940 | dev++; | 3007 | dev++; |
2941 | return 0; | 3008 | return 0; |
2942 | } | 3009 | } |
2943 | __nodev: | 3010 | __nodev: |
2944 | snd_card_free(card); | 3011 | snd_card_free(card); |
2945 | snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err); | 3012 | dev_err(&pci_dev->dev, "snd_asihpi_probe error %d\n", err); |
2946 | return err; | 3013 | return err; |
2947 | 3014 | ||
2948 | } | 3015 | } |
@@ -2950,6 +3017,16 @@ __nodev: | |||
2950 | static void snd_asihpi_remove(struct pci_dev *pci_dev) | 3017 | static void snd_asihpi_remove(struct pci_dev *pci_dev) |
2951 | { | 3018 | { |
2952 | struct hpi_adapter *hpi = pci_get_drvdata(pci_dev); | 3019 | struct hpi_adapter *hpi = pci_get_drvdata(pci_dev); |
3020 | struct snd_card_asihpi *asihpi = hpi->snd_card->private_data; | ||
3021 | |||
3022 | /* Stop interrupts */ | ||
3023 | if (hpi->interrupt_mode) { | ||
3024 | hpi->interrupt_callback = NULL; | ||
3025 | hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index, | ||
3026 | HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); | ||
3027 | tasklet_kill(&asihpi->t); | ||
3028 | } | ||
3029 | |||
2953 | snd_card_free(hpi->snd_card); | 3030 | snd_card_free(hpi->snd_card); |
2954 | hpi->snd_card = NULL; | 3031 | hpi->snd_card = NULL; |
2955 | asihpi_adapter_remove(pci_dev); | 3032 | asihpi_adapter_remove(pci_dev); |
@@ -2971,10 +3048,6 @@ static struct pci_driver driver = { | |||
2971 | .id_table = asihpi_pci_tbl, | 3048 | .id_table = asihpi_pci_tbl, |
2972 | .probe = snd_asihpi_probe, | 3049 | .probe = snd_asihpi_probe, |
2973 | .remove = snd_asihpi_remove, | 3050 | .remove = snd_asihpi_remove, |
2974 | #ifdef CONFIG_PM_SLEEP | ||
2975 | /* .suspend = snd_asihpi_suspend, | ||
2976 | .resume = snd_asihpi_resume, */ | ||
2977 | #endif | ||
2978 | }; | 3051 | }; |
2979 | 3052 | ||
2980 | static int __init snd_asihpi_init(void) | 3053 | static int __init snd_asihpi_init(void) |
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 20887241a3ae..4466bd2c5272 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h | |||
@@ -196,8 +196,10 @@ enum HPI_SOURCENODES { | |||
196 | packets of RTP audio samples from other devices. */ | 196 | packets of RTP audio samples from other devices. */ |
197 | HPI_SOURCENODE_RTP_DESTINATION = 112, | 197 | HPI_SOURCENODE_RTP_DESTINATION = 112, |
198 | HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */ | 198 | HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */ |
199 | HPI_SOURCENODE_AVB = 114, /**< AVB input stream */ | ||
200 | HPI_SOURCENODE_BLULINK = 115, /**< BLU-link input channel */ | ||
199 | /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ | 201 | /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ |
200 | HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */ | 202 | HPI_SOURCENODE_LAST_INDEX = 115 /**< largest ID */ |
201 | /* AX6 max sourcenode types = 15 */ | 203 | /* AX6 max sourcenode types = 15 */ |
202 | }; | 204 | }; |
203 | 205 | ||
@@ -224,8 +226,11 @@ enum HPI_DESTNODES { | |||
224 | /** RTP stream output node - This node is a source for | 226 | /** RTP stream output node - This node is a source for |
225 | packets of RTP audio samples that are sent to other devices. */ | 227 | packets of RTP audio samples that are sent to other devices. */ |
226 | HPI_DESTNODE_RTP_SOURCE = 208, | 228 | HPI_DESTNODE_RTP_SOURCE = 208, |
229 | HPI_DESTNODE_AVB = 209, /**< AVB output stream */ | ||
230 | HPI_DESTNODE_INTERNAL = 210, /**< node internal to the device. */ | ||
231 | HPI_DESTNODE_BLULINK = 211, /**< BLU-link output channel. */ | ||
227 | /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ | 232 | /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ |
228 | HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */ | 233 | HPI_DESTNODE_LAST_INDEX = 211 /**< largest ID */ |
229 | /* AX6 max destnode types = 15 */ | 234 | /* AX6 max destnode types = 15 */ |
230 | }; | 235 | }; |
231 | 236 | ||
@@ -752,7 +757,8 @@ enum HPI_TUNER_BAND { | |||
752 | HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/ | 757 | HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/ |
753 | HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/ | 758 | HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/ |
754 | HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/ | 759 | HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/ |
755 | HPI_TUNER_BAND_LAST = 9 /**< the index of the last tuner band. */ | 760 | HPI_TUNER_BAND_DAB = 10, |
761 | HPI_TUNER_BAND_LAST = 10 /**< the index of the last tuner band. */ | ||
756 | }; | 762 | }; |
757 | 763 | ||
758 | /** Tuner mode attributes | 764 | /** Tuner mode attributes |
@@ -842,8 +848,10 @@ enum HPI_SAMPLECLOCK_SOURCES { | |||
842 | HPI_SAMPLECLOCK_SOURCE_NETWORK = 8, | 848 | HPI_SAMPLECLOCK_SOURCE_NETWORK = 8, |
843 | /** From previous adjacent module (ASI2416 only)*/ | 849 | /** From previous adjacent module (ASI2416 only)*/ |
844 | HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10, | 850 | HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10, |
851 | /** Blu link sample clock*/ | ||
852 | HPI_SAMPLECLOCK_SOURCE_BLULINK = 11, | ||
845 | /*! Update this if you add a new clock source.*/ | 853 | /*! Update this if you add a new clock source.*/ |
846 | HPI_SAMPLECLOCK_SOURCE_LAST = 10 | 854 | HPI_SAMPLECLOCK_SOURCE_LAST = 11 |
847 | }; | 855 | }; |
848 | 856 | ||
849 | /** Equalizer filter types. Used by HPI_ParametricEq_SetBand() | 857 | /** Equalizer filter types. Used by HPI_ParametricEq_SetBand() |
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 4f2873880b16..8d5abfa4e24b 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | 2 | ||
3 | AudioScience HPI driver | 3 | AudioScience HPI driver |
4 | Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> | 4 | Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of version 2 of the GNU General Public License as | 7 | it under the terms of version 2 of the GNU General Public License as |
@@ -163,6 +163,9 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
163 | 163 | ||
164 | static void delete_adapter_obj(struct hpi_adapter_obj *pao); | 164 | static void delete_adapter_obj(struct hpi_adapter_obj *pao); |
165 | 165 | ||
166 | static int adapter_irq_query_and_clear(struct hpi_adapter_obj *pao, | ||
167 | u32 message); | ||
168 | |||
166 | static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, | 169 | static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, |
167 | struct hpi_message *phm, struct hpi_response *phr); | 170 | struct hpi_message *phm, struct hpi_response *phr); |
168 | 171 | ||
@@ -283,7 +286,6 @@ static void adapter_message(struct hpi_adapter_obj *pao, | |||
283 | case HPI_ADAPTER_DELETE: | 286 | case HPI_ADAPTER_DELETE: |
284 | adapter_delete(pao, phm, phr); | 287 | adapter_delete(pao, phm, phr); |
285 | break; | 288 | break; |
286 | |||
287 | default: | 289 | default: |
288 | hw_message(pao, phm, phr); | 290 | hw_message(pao, phm, phr); |
289 | break; | 291 | break; |
@@ -673,6 +675,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
673 | 675 | ||
674 | HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); | 676 | HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); |
675 | 677 | ||
678 | pao->irq_query_and_clear = adapter_irq_query_and_clear; | ||
679 | pao->instream_host_buffer_status = | ||
680 | phw->p_interface_buffer->instream_host_buffer_status; | ||
681 | pao->outstream_host_buffer_status = | ||
682 | phw->p_interface_buffer->outstream_host_buffer_status; | ||
683 | |||
676 | return hpi_add_adapter(pao); | 684 | return hpi_add_adapter(pao); |
677 | } | 685 | } |
678 | 686 | ||
@@ -713,6 +721,21 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao) | |||
713 | 721 | ||
714 | /*****************************************************************************/ | 722 | /*****************************************************************************/ |
715 | /* Adapter functions */ | 723 | /* Adapter functions */ |
724 | static int adapter_irq_query_and_clear(struct hpi_adapter_obj *pao, | ||
725 | u32 message) | ||
726 | { | ||
727 | struct hpi_hw_obj *phw = pao->priv; | ||
728 | u32 hsr = 0; | ||
729 | |||
730 | hsr = ioread32(phw->prHSR); | ||
731 | if (hsr & C6205_HSR_INTSRC) { | ||
732 | /* reset the interrupt from the DSP */ | ||
733 | iowrite32(C6205_HSR_INTSRC, phw->prHSR); | ||
734 | return HPI_IRQ_MIXER; | ||
735 | } | ||
736 | |||
737 | return HPI_IRQ_NONE; | ||
738 | } | ||
716 | 739 | ||
717 | /*****************************************************************************/ | 740 | /*****************************************************************************/ |
718 | /* OutStream Host buffer functions */ | 741 | /* OutStream Host buffer functions */ |
@@ -1331,17 +1354,21 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1331 | if (boot_code_id[1] != 0) { | 1354 | if (boot_code_id[1] != 0) { |
1332 | /* DSP 1 is a C6713 */ | 1355 | /* DSP 1 is a C6713 */ |
1333 | /* CLKX0 <- '1' release the C6205 bootmode pulldowns */ | 1356 | /* CLKX0 <- '1' release the C6205 bootmode pulldowns */ |
1334 | boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202); | 1357 | boot_loader_write_mem32(pao, 0, 0x018C0024, 0x00002202); |
1335 | hpios_delay_micro_seconds(100); | 1358 | hpios_delay_micro_seconds(100); |
1336 | /* Reset the 6713 #1 - revB */ | 1359 | /* Reset the 6713 #1 - revB */ |
1337 | boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0); | 1360 | boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0); |
1338 | 1361 | /* value of bit 3 is unknown after DSP reset, other bits shoudl be 0 */ | |
1339 | /* dummy read every 4 words for 6205 advisory 1.4.4 */ | 1362 | if (0 != (boot_loader_read_mem32(pao, 0, |
1340 | boot_loader_read_mem32(pao, 0, 0); | 1363 | (C6205_BAR0_TIMER1_CTL)) & ~8)) |
1341 | 1364 | return HPI6205_ERROR_6205_REG; | |
1342 | hpios_delay_micro_seconds(100); | 1365 | hpios_delay_micro_seconds(100); |
1366 | |||
1343 | /* Release C6713 from reset - revB */ | 1367 | /* Release C6713 from reset - revB */ |
1344 | boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4); | 1368 | boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4); |
1369 | if (4 != (boot_loader_read_mem32(pao, 0, | ||
1370 | (C6205_BAR0_TIMER1_CTL)) & ~8)) | ||
1371 | return HPI6205_ERROR_6205_REG; | ||
1345 | hpios_delay_micro_seconds(100); | 1372 | hpios_delay_micro_seconds(100); |
1346 | } | 1373 | } |
1347 | 1374 | ||
@@ -2089,7 +2116,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, | |||
2089 | return 0; | 2116 | return 0; |
2090 | } | 2117 | } |
2091 | 2118 | ||
2092 | /* Assume buffer of type struct bus_master_interface | 2119 | /* Assume buffer of type struct bus_master_interface_62 |
2093 | is allocated "noncacheable" */ | 2120 | is allocated "noncacheable" */ |
2094 | 2121 | ||
2095 | if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { | 2122 | if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { |
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index bc86cb726d79..48380ce2c81b 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h | |||
@@ -554,17 +554,21 @@ struct hpi_pci { | |||
554 | struct pci_dev *pci_dev; | 554 | struct pci_dev *pci_dev; |
555 | }; | 555 | }; |
556 | 556 | ||
557 | /** Adapter specification resource */ | ||
558 | struct hpi_adapter_specification { | ||
559 | u32 type; | ||
560 | u8 modules[4]; | ||
561 | }; | ||
562 | |||
557 | struct hpi_resource { | 563 | struct hpi_resource { |
558 | union { | 564 | union { |
559 | const struct hpi_pci *pci; | 565 | const struct hpi_pci *pci; |
560 | const char *net_if; | 566 | const char *net_if; |
567 | struct hpi_adapter_specification adapter_spec; | ||
568 | const void *sw_if; | ||
561 | } r; | 569 | } r; |
562 | #ifndef HPI64BIT /* keep structure size constant */ | ||
563 | u32 pad_to64; | ||
564 | #endif | ||
565 | u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */ | 570 | u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */ |
566 | u16 padding; | 571 | u16 padding; |
567 | |||
568 | }; | 572 | }; |
569 | 573 | ||
570 | /** Format info used inside struct hpi_message | 574 | /** Format info used inside struct hpi_message |
@@ -582,7 +586,7 @@ struct hpi_msg_format { | |||
582 | struct hpi_msg_data { | 586 | struct hpi_msg_data { |
583 | struct hpi_msg_format format; | 587 | struct hpi_msg_format format; |
584 | u8 *pb_data; | 588 | u8 *pb_data; |
585 | #ifndef HPI64BIT | 589 | #ifndef CONFIG_64BIT |
586 | u32 padding; | 590 | u32 padding; |
587 | #endif | 591 | #endif |
588 | u32 data_size; | 592 | u32 data_size; |
@@ -595,7 +599,7 @@ struct hpi_data_legacy32 { | |||
595 | u32 data_size; | 599 | u32 data_size; |
596 | }; | 600 | }; |
597 | 601 | ||
598 | #ifdef HPI64BIT | 602 | #ifdef CONFIG_64BIT |
599 | /* Compatibility version of struct hpi_data*/ | 603 | /* Compatibility version of struct hpi_data*/ |
600 | struct hpi_data_compat32 { | 604 | struct hpi_data_compat32 { |
601 | struct hpi_msg_format format; | 605 | struct hpi_msg_format format; |
@@ -682,8 +686,8 @@ union hpi_adapterx_msg { | |||
682 | u16 value; | 686 | u16 value; |
683 | } test_assert; | 687 | } test_assert; |
684 | struct { | 688 | struct { |
685 | u32 yes; | 689 | u32 message; |
686 | } irq_query; | 690 | } irq; |
687 | u32 pad[3]; | 691 | u32 pad[3]; |
688 | }; | 692 | }; |
689 | 693 | ||
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 7ed5c26c3737..c7751243dc42 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | 2 | ||
3 | AudioScience HPI driver | 3 | AudioScience HPI driver |
4 | Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> | 4 | Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of version 2 of the GNU General Public License as | 7 | it under the terms of version 2 of the GNU General Public License as |
@@ -206,6 +206,14 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) | |||
206 | struct hpi_control_cache_info *info = | 206 | struct hpi_control_cache_info *info = |
207 | (struct hpi_control_cache_info *) | 207 | (struct hpi_control_cache_info *) |
208 | &p_master_cache[byte_count]; | 208 | &p_master_cache[byte_count]; |
209 | u16 control_index = info->control_index; | ||
210 | |||
211 | if (control_index >= pC->control_count) { | ||
212 | HPI_DEBUG_LOG(INFO, | ||
213 | "adap %d control index %d out of range, cache not ready?\n", | ||
214 | pC->adap_idx, control_index); | ||
215 | return 0; | ||
216 | } | ||
209 | 217 | ||
210 | if (!info->size_in32bit_words) { | 218 | if (!info->size_in32bit_words) { |
211 | if (!i) { | 219 | if (!i) { |
@@ -225,10 +233,10 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) | |||
225 | } | 233 | } |
226 | 234 | ||
227 | if (info->control_type) { | 235 | if (info->control_type) { |
228 | pC->p_info[info->control_index] = info; | 236 | pC->p_info[control_index] = info; |
229 | cached++; | 237 | cached++; |
230 | } else { /* dummy cache entry */ | 238 | } else { /* dummy cache entry */ |
231 | pC->p_info[info->control_index] = NULL; | 239 | pC->p_info[control_index] = NULL; |
232 | } | 240 | } |
233 | 241 | ||
234 | byte_count += info->size_in32bit_words * 4; | 242 | byte_count += info->size_in32bit_words * 4; |
@@ -309,35 +317,18 @@ static const struct pad_ofs_size pad_desc[] = { | |||
309 | /** CheckControlCache checks the cache and fills the struct hpi_response | 317 | /** CheckControlCache checks the cache and fills the struct hpi_response |
310 | * accordingly. It returns one if a cache hit occurred, zero otherwise. | 318 | * accordingly. It returns one if a cache hit occurred, zero otherwise. |
311 | */ | 319 | */ |
312 | short hpi_check_control_cache(struct hpi_control_cache *p_cache, | 320 | short hpi_check_control_cache_single(struct hpi_control_cache_single *pC, |
313 | struct hpi_message *phm, struct hpi_response *phr) | 321 | struct hpi_message *phm, struct hpi_response *phr) |
314 | { | 322 | { |
315 | short found = 1; | ||
316 | struct hpi_control_cache_info *pI; | ||
317 | struct hpi_control_cache_single *pC; | ||
318 | size_t response_size; | 323 | size_t response_size; |
319 | if (!find_control(phm->obj_index, p_cache, &pI)) { | 324 | short found = 1; |
320 | HPI_DEBUG_LOG(VERBOSE, | ||
321 | "HPICMN find_control() failed for adap %d\n", | ||
322 | phm->adapter_index); | ||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | phr->error = 0; | ||
327 | phr->specific_error = 0; | ||
328 | phr->version = 0; | ||
329 | 325 | ||
330 | /* set the default response size */ | 326 | /* set the default response size */ |
331 | response_size = | 327 | response_size = |
332 | sizeof(struct hpi_response_header) + | 328 | sizeof(struct hpi_response_header) + |
333 | sizeof(struct hpi_control_res); | 329 | sizeof(struct hpi_control_res); |
334 | 330 | ||
335 | /* pC is the default cached control strucure. May be cast to | 331 | switch (pC->u.i.control_type) { |
336 | something else in the following switch statement. | ||
337 | */ | ||
338 | pC = (struct hpi_control_cache_single *)pI; | ||
339 | |||
340 | switch (pI->control_type) { | ||
341 | 332 | ||
342 | case HPI_CONTROL_METER: | 333 | case HPI_CONTROL_METER: |
343 | if (phm->u.c.attribute == HPI_METER_PEAK) { | 334 | if (phm->u.c.attribute == HPI_METER_PEAK) { |
@@ -467,7 +458,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
467 | break; | 458 | break; |
468 | case HPI_CONTROL_PAD:{ | 459 | case HPI_CONTROL_PAD:{ |
469 | struct hpi_control_cache_pad *p_pad; | 460 | struct hpi_control_cache_pad *p_pad; |
470 | p_pad = (struct hpi_control_cache_pad *)pI; | 461 | p_pad = (struct hpi_control_cache_pad *)pC; |
471 | 462 | ||
472 | if (!(p_pad->field_valid_flags & (1 << | 463 | if (!(p_pad->field_valid_flags & (1 << |
473 | HPI_CTL_ATTR_INDEX(phm->u.c. | 464 | HPI_CTL_ATTR_INDEX(phm->u.c. |
@@ -531,7 +522,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
531 | 522 | ||
532 | HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n", | 523 | HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n", |
533 | found ? "Cached" : "Uncached", phm->adapter_index, | 524 | found ? "Cached" : "Uncached", phm->adapter_index, |
534 | pI->control_index, pI->control_type, phm->u.c.attribute); | 525 | pC->u.i.control_index, pC->u.i.control_type, |
526 | phm->u.c.attribute); | ||
535 | 527 | ||
536 | if (found) { | 528 | if (found) { |
537 | phr->size = (u16)response_size; | 529 | phr->size = (u16)response_size; |
@@ -543,34 +535,36 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
543 | return found; | 535 | return found; |
544 | } | 536 | } |
545 | 537 | ||
546 | /** Updates the cache with Set values. | 538 | short hpi_check_control_cache(struct hpi_control_cache *p_cache, |
547 | |||
548 | Only update if no error. | ||
549 | Volume and Level return the limited values in the response, so use these | ||
550 | Multiplexer does so use sent values | ||
551 | */ | ||
552 | void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, | ||
553 | struct hpi_message *phm, struct hpi_response *phr) | 539 | struct hpi_message *phm, struct hpi_response *phr) |
554 | { | 540 | { |
555 | struct hpi_control_cache_single *pC; | ||
556 | struct hpi_control_cache_info *pI; | 541 | struct hpi_control_cache_info *pI; |
557 | 542 | ||
558 | if (phr->error) | ||
559 | return; | ||
560 | |||
561 | if (!find_control(phm->obj_index, p_cache, &pI)) { | 543 | if (!find_control(phm->obj_index, p_cache, &pI)) { |
562 | HPI_DEBUG_LOG(VERBOSE, | 544 | HPI_DEBUG_LOG(VERBOSE, |
563 | "HPICMN find_control() failed for adap %d\n", | 545 | "HPICMN find_control() failed for adap %d\n", |
564 | phm->adapter_index); | 546 | phm->adapter_index); |
565 | return; | 547 | return 0; |
566 | } | 548 | } |
567 | 549 | ||
568 | /* pC is the default cached control strucure. | 550 | phr->error = 0; |
569 | May be cast to something else in the following switch statement. | 551 | phr->specific_error = 0; |
570 | */ | 552 | phr->version = 0; |
571 | pC = (struct hpi_control_cache_single *)pI; | 553 | |
554 | return hpi_check_control_cache_single((struct hpi_control_cache_single | ||
555 | *)pI, phm, phr); | ||
556 | } | ||
557 | |||
558 | /** Updates the cache with Set values. | ||
572 | 559 | ||
573 | switch (pI->control_type) { | 560 | Only update if no error. |
561 | Volume and Level return the limited values in the response, so use these | ||
562 | Multiplexer does so use sent values | ||
563 | */ | ||
564 | void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single | ||
565 | *pC, struct hpi_message *phm, struct hpi_response *phr) | ||
566 | { | ||
567 | switch (pC->u.i.control_type) { | ||
574 | case HPI_CONTROL_VOLUME: | 568 | case HPI_CONTROL_VOLUME: |
575 | if (phm->u.c.attribute == HPI_VOLUME_GAIN) { | 569 | if (phm->u.c.attribute == HPI_VOLUME_GAIN) { |
576 | pC->u.vol.an_log[0] = phr->u.c.an_log_value[0]; | 570 | pC->u.vol.an_log[0] = phr->u.c.an_log_value[0]; |
@@ -625,6 +619,30 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, | |||
625 | } | 619 | } |
626 | } | 620 | } |
627 | 621 | ||
622 | void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, | ||
623 | struct hpi_message *phm, struct hpi_response *phr) | ||
624 | { | ||
625 | struct hpi_control_cache_single *pC; | ||
626 | struct hpi_control_cache_info *pI; | ||
627 | |||
628 | if (phr->error) | ||
629 | return; | ||
630 | |||
631 | if (!find_control(phm->obj_index, p_cache, &pI)) { | ||
632 | HPI_DEBUG_LOG(VERBOSE, | ||
633 | "HPICMN find_control() failed for adap %d\n", | ||
634 | phm->adapter_index); | ||
635 | return; | ||
636 | } | ||
637 | |||
638 | /* pC is the default cached control strucure. | ||
639 | May be cast to something else in the following switch statement. | ||
640 | */ | ||
641 | pC = (struct hpi_control_cache_single *)pI; | ||
642 | |||
643 | hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr); | ||
644 | } | ||
645 | |||
628 | /** Allocate control cache. | 646 | /** Allocate control cache. |
629 | 647 | ||
630 | \return Cache pointer, or NULL if allocation fails. | 648 | \return Cache pointer, or NULL if allocation fails. |
@@ -637,12 +655,13 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, | |||
637 | if (!p_cache) | 655 | if (!p_cache) |
638 | return NULL; | 656 | return NULL; |
639 | 657 | ||
640 | p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info), | 658 | p_cache->p_info = |
641 | GFP_KERNEL); | 659 | kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL); |
642 | if (!p_cache->p_info) { | 660 | if (!p_cache->p_info) { |
643 | kfree(p_cache); | 661 | kfree(p_cache); |
644 | return NULL; | 662 | return NULL; |
645 | } | 663 | } |
664 | |||
646 | p_cache->cache_size_in_bytes = size_in_bytes; | 665 | p_cache->cache_size_in_bytes = size_in_bytes; |
647 | p_cache->control_count = control_count; | 666 | p_cache->control_count = control_count; |
648 | p_cache->p_cache = p_dsp_control_buffer; | 667 | p_cache->p_cache = p_dsp_control_buffer; |
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h index e44121283047..46629c2d101b 100644 --- a/sound/pci/asihpi/hpicmn.h +++ b/sound/pci/asihpi/hpicmn.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | 2 | ||
3 | AudioScience HPI driver | 3 | AudioScience HPI driver |
4 | Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> | 4 | Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of version 2 of the GNU General Public License as | 7 | it under the terms of version 2 of the GNU General Public License as |
@@ -21,7 +21,11 @@ | |||
21 | struct hpi_adapter_obj; | 21 | struct hpi_adapter_obj; |
22 | 22 | ||
23 | /* a function that takes an adapter obj and returns an int */ | 23 | /* a function that takes an adapter obj and returns an int */ |
24 | typedef int adapter_int_func(struct hpi_adapter_obj *pao); | 24 | typedef int adapter_int_func(struct hpi_adapter_obj *pao, u32 message); |
25 | |||
26 | #define HPI_IRQ_NONE (0) | ||
27 | #define HPI_IRQ_MESSAGE (1) | ||
28 | #define HPI_IRQ_MIXER (2) | ||
25 | 29 | ||
26 | struct hpi_adapter_obj { | 30 | struct hpi_adapter_obj { |
27 | struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */ | 31 | struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */ |
@@ -33,6 +37,9 @@ struct hpi_adapter_obj { | |||
33 | u16 dsp_crashed; | 37 | u16 dsp_crashed; |
34 | u16 has_control_cache; | 38 | u16 has_control_cache; |
35 | void *priv; | 39 | void *priv; |
40 | adapter_int_func *irq_query_and_clear; | ||
41 | struct hpi_hostbuffer_status *instream_host_buffer_status; | ||
42 | struct hpi_hostbuffer_status *outstream_host_buffer_status; | ||
36 | }; | 43 | }; |
37 | 44 | ||
38 | struct hpi_control_cache { | 45 | struct hpi_control_cache { |
@@ -55,13 +62,21 @@ void hpi_delete_adapter(struct hpi_adapter_obj *pao); | |||
55 | 62 | ||
56 | short hpi_check_control_cache(struct hpi_control_cache *pC, | 63 | short hpi_check_control_cache(struct hpi_control_cache *pC, |
57 | struct hpi_message *phm, struct hpi_response *phr); | 64 | struct hpi_message *phm, struct hpi_response *phr); |
65 | |||
66 | short hpi_check_control_cache_single(struct hpi_control_cache_single *pC, | ||
67 | struct hpi_message *phm, struct hpi_response *phr); | ||
68 | |||
58 | struct hpi_control_cache *hpi_alloc_control_cache(const u32 | 69 | struct hpi_control_cache *hpi_alloc_control_cache(const u32 |
59 | number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer); | 70 | number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer); |
71 | |||
60 | void hpi_free_control_cache(struct hpi_control_cache *p_cache); | 72 | void hpi_free_control_cache(struct hpi_control_cache *p_cache); |
61 | 73 | ||
62 | void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC, | 74 | void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC, |
63 | struct hpi_message *phm, struct hpi_response *phr); | 75 | struct hpi_message *phm, struct hpi_response *phr); |
64 | 76 | ||
77 | void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single | ||
78 | *pC, struct hpi_message *phm, struct hpi_response *phr); | ||
79 | |||
65 | u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); | 80 | u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); |
66 | 81 | ||
67 | hpi_handler_func HPI_COMMON; | 82 | hpi_handler_func HPI_COMMON; |
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c index 032d563e3708..7eb617175fde 100644 --- a/sound/pci/asihpi/hpimsginit.c +++ b/sound/pci/asihpi/hpimsginit.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | 2 | ||
3 | AudioScience HPI driver | 3 | AudioScience HPI driver |
4 | Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> | 4 | Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of version 2 of the GNU General Public License as | 7 | it under the terms of version 2 of the GNU General Public License as |
@@ -37,11 +37,15 @@ static u16 gwSSX2_bypass; | |||
37 | static void hpi_init_message(struct hpi_message *phm, u16 object, | 37 | static void hpi_init_message(struct hpi_message *phm, u16 object, |
38 | u16 function) | 38 | u16 function) |
39 | { | 39 | { |
40 | memset(phm, 0, sizeof(*phm)); | 40 | u16 size; |
41 | |||
41 | if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) | 42 | if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) |
42 | phm->size = msg_size[object]; | 43 | size = msg_size[object]; |
43 | else | 44 | else |
44 | phm->size = sizeof(*phm); | 45 | size = sizeof(*phm); |
46 | |||
47 | memset(phm, 0, size); | ||
48 | phm->size = size; | ||
45 | 49 | ||
46 | if (gwSSX2_bypass) | 50 | if (gwSSX2_bypass) |
47 | phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; | 51 | phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; |
@@ -60,12 +64,16 @@ static void hpi_init_message(struct hpi_message *phm, u16 object, | |||
60 | void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, | 64 | void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, |
61 | u16 error) | 65 | u16 error) |
62 | { | 66 | { |
63 | memset(phr, 0, sizeof(*phr)); | 67 | u16 size; |
64 | phr->type = HPI_TYPE_RESPONSE; | 68 | |
65 | if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) | 69 | if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) |
66 | phr->size = res_size[object]; | 70 | size = res_size[object]; |
67 | else | 71 | else |
68 | phr->size = sizeof(*phr); | 72 | size = sizeof(*phr); |
73 | |||
74 | memset(phr, 0, sizeof(*phr)); | ||
75 | phr->size = size; | ||
76 | phr->type = HPI_TYPE_RESPONSE; | ||
69 | phr->object = object; | 77 | phr->object = object; |
70 | phr->function = function; | 78 | phr->function = function; |
71 | phr->error = error; | 79 | phr->error = error; |
@@ -86,7 +94,7 @@ void hpi_init_message_response(struct hpi_message *phm, | |||
86 | static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, | 94 | static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, |
87 | u16 object, u16 function) | 95 | u16 object, u16 function) |
88 | { | 96 | { |
89 | memset(phm, 0, sizeof(*phm)); | 97 | memset(phm, 0, size); |
90 | if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { | 98 | if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { |
91 | phm->size = size; | 99 | phm->size = size; |
92 | phm->type = HPI_TYPE_REQUEST; | 100 | phm->type = HPI_TYPE_REQUEST; |
@@ -100,7 +108,9 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, | |||
100 | void hpi_init_responseV1(struct hpi_response_header *phr, u16 size, | 108 | void hpi_init_responseV1(struct hpi_response_header *phr, u16 size, |
101 | u16 object, u16 function) | 109 | u16 object, u16 function) |
102 | { | 110 | { |
103 | memset(phr, 0, sizeof(*phr)); | 111 | (void)object; |
112 | (void)function; | ||
113 | memset(phr, 0, size); | ||
104 | phr->size = size; | 114 | phr->size = size; |
105 | phr->version = 1; | 115 | phr->version = 1; |
106 | phr->type = HPI_TYPE_RESPONSE; | 116 | phr->type = HPI_TYPE_RESPONSE; |
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index d4790ddc225c..736f45337fc7 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | 2 | ||
3 | AudioScience HPI driver | 3 | AudioScience HPI driver |
4 | Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> | 4 | Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of version 2 of the GNU General Public License as | 7 | it under the terms of version 2 of the GNU General Public License as |
@@ -35,6 +35,7 @@ static struct pci_device_id asihpi_pci_tbl[] = { | |||
35 | static struct hpios_spinlock msgx_lock; | 35 | static struct hpios_spinlock msgx_lock; |
36 | 36 | ||
37 | static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS]; | 37 | static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS]; |
38 | static int logging_enabled = 1; | ||
38 | 39 | ||
39 | static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci | 40 | static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci |
40 | *pci_info) | 41 | *pci_info) |
@@ -312,7 +313,9 @@ static void instream_message(struct hpi_message *phm, | |||
312 | void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, | 313 | void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, |
313 | void *h_owner) | 314 | void *h_owner) |
314 | { | 315 | { |
315 | HPI_DEBUG_MESSAGE(DEBUG, phm); | 316 | |
317 | if (logging_enabled) | ||
318 | HPI_DEBUG_MESSAGE(DEBUG, phm); | ||
316 | 319 | ||
317 | if (phm->type != HPI_TYPE_REQUEST) { | 320 | if (phm->type != HPI_TYPE_REQUEST) { |
318 | hpi_init_response(phr, phm->object, phm->function, | 321 | hpi_init_response(phr, phm->object, phm->function, |
@@ -352,8 +355,14 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, | |||
352 | hw_entry_point(phm, phr); | 355 | hw_entry_point(phm, phr); |
353 | break; | 356 | break; |
354 | } | 357 | } |
355 | HPI_DEBUG_RESPONSE(phr); | ||
356 | 358 | ||
359 | if (logging_enabled) | ||
360 | HPI_DEBUG_RESPONSE(phr); | ||
361 | |||
362 | if (phr->error >= HPI_ERROR_DSP_COMMUNICATION) { | ||
363 | hpi_debug_level_set(HPI_DEBUG_LEVEL_ERROR); | ||
364 | logging_enabled = 0; | ||
365 | } | ||
357 | } | 366 | } |
358 | 367 | ||
359 | static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) | 368 | static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) |
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 7f0272032fbb..6aa677e60555 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | |||
3 | AudioScience HPI driver | 2 | AudioScience HPI driver |
4 | Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> | 3 | Common Linux HPI ioctl and module probe/remove functions |
4 | |||
5 | Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> | ||
5 | 6 | ||
6 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of version 2 of the GNU General Public License as | 8 | it under the terms of version 2 of the GNU General Public License as |
@@ -12,11 +13,6 @@ | |||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 14 | GNU General Public License for more details. |
14 | 15 | ||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Common Linux HPI ioctl and module probe/remove functions | ||
20 | *******************************************************************************/ | 16 | *******************************************************************************/ |
21 | #define SOURCEFILE_NAME "hpioctl.c" | 17 | #define SOURCEFILE_NAME "hpioctl.c" |
22 | 18 | ||
@@ -29,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions | |||
29 | #include "hpicmn.h" | 25 | #include "hpicmn.h" |
30 | 26 | ||
31 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/interrupt.h> | ||
32 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
33 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
34 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -307,10 +304,38 @@ out: | |||
307 | return err; | 304 | return err; |
308 | } | 305 | } |
309 | 306 | ||
307 | static int asihpi_irq_count; | ||
308 | |||
309 | static irqreturn_t asihpi_isr(int irq, void *dev_id) | ||
310 | { | ||
311 | struct hpi_adapter *a = dev_id; | ||
312 | int handled; | ||
313 | |||
314 | if (!a->adapter->irq_query_and_clear) { | ||
315 | pr_err("asihpi_isr ASI%04X:%d no handler\n", a->adapter->type, | ||
316 | a->adapter->index); | ||
317 | return IRQ_NONE; | ||
318 | } | ||
319 | |||
320 | handled = a->adapter->irq_query_and_clear(a->adapter, 0); | ||
321 | |||
322 | if (!handled) | ||
323 | return IRQ_NONE; | ||
324 | |||
325 | asihpi_irq_count++; | ||
326 | /* printk(KERN_INFO "asihpi_isr %d ASI%04X:%d irq handled\n", | ||
327 | asihpi_irq_count, a->adapter->type, a->adapter->index); */ | ||
328 | |||
329 | if (a->interrupt_callback) | ||
330 | a->interrupt_callback(a); | ||
331 | |||
332 | return IRQ_HANDLED; | ||
333 | } | ||
334 | |||
310 | int asihpi_adapter_probe(struct pci_dev *pci_dev, | 335 | int asihpi_adapter_probe(struct pci_dev *pci_dev, |
311 | const struct pci_device_id *pci_id) | 336 | const struct pci_device_id *pci_id) |
312 | { | 337 | { |
313 | int idx, nm; | 338 | int idx, nm, low_latency_mode = 0, irq_supported = 0; |
314 | int adapter_index; | 339 | int adapter_index; |
315 | unsigned int memlen; | 340 | unsigned int memlen; |
316 | struct hpi_message hm; | 341 | struct hpi_message hm; |
@@ -388,8 +413,38 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev, | |||
388 | hm.adapter_index = adapter.adapter->index; | 413 | hm.adapter_index = adapter.adapter->index; |
389 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | 414 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); |
390 | 415 | ||
391 | if (hr.error) | 416 | if (hr.error) { |
417 | HPI_DEBUG_LOG(ERROR, "HPI_ADAPTER_OPEN failed, aborting\n"); | ||
392 | goto err; | 418 | goto err; |
419 | } | ||
420 | |||
421 | /* Check if current mode == Low Latency mode */ | ||
422 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
423 | HPI_ADAPTER_GET_MODE); | ||
424 | hm.adapter_index = adapter.adapter->index; | ||
425 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | ||
426 | |||
427 | if (!hr.error | ||
428 | && hr.u.ax.mode.adapter_mode == HPI_ADAPTER_MODE_LOW_LATENCY) | ||
429 | low_latency_mode = 1; | ||
430 | else | ||
431 | dev_info(&pci_dev->dev, | ||
432 | "Adapter at index %d is not in low latency mode\n", | ||
433 | adapter.adapter->index); | ||
434 | |||
435 | /* Check if IRQs are supported */ | ||
436 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
437 | HPI_ADAPTER_GET_PROPERTY); | ||
438 | hm.adapter_index = adapter.adapter->index; | ||
439 | hm.u.ax.property_set.property = HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ; | ||
440 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | ||
441 | if (hr.error || !hr.u.ax.property_get.parameter1) { | ||
442 | dev_info(&pci_dev->dev, | ||
443 | "IRQs not supported by adapter at index %d\n", | ||
444 | adapter.adapter->index); | ||
445 | } else { | ||
446 | irq_supported = 1; | ||
447 | } | ||
393 | 448 | ||
394 | /* WARNING can't init mutex in 'adapter' | 449 | /* WARNING can't init mutex in 'adapter' |
395 | * and then copy it to adapters[] ?!?! | 450 | * and then copy it to adapters[] ?!?! |
@@ -398,6 +453,44 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev, | |||
398 | mutex_init(&adapters[adapter_index].mutex); | 453 | mutex_init(&adapters[adapter_index].mutex); |
399 | pci_set_drvdata(pci_dev, &adapters[adapter_index]); | 454 | pci_set_drvdata(pci_dev, &adapters[adapter_index]); |
400 | 455 | ||
456 | if (low_latency_mode && irq_supported) { | ||
457 | if (!adapter.adapter->irq_query_and_clear) { | ||
458 | dev_err(&pci_dev->dev, | ||
459 | "no IRQ handler for adapter %d, aborting\n", | ||
460 | adapter.adapter->index); | ||
461 | goto err; | ||
462 | } | ||
463 | |||
464 | /* Disable IRQ generation on DSP side by setting the rate to 0 */ | ||
465 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
466 | HPI_ADAPTER_SET_PROPERTY); | ||
467 | hm.adapter_index = adapter.adapter->index; | ||
468 | hm.u.ax.property_set.property = HPI_ADAPTER_PROPERTY_IRQ_RATE; | ||
469 | hm.u.ax.property_set.parameter1 = 0; | ||
470 | hm.u.ax.property_set.parameter2 = 0; | ||
471 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | ||
472 | if (hr.error) { | ||
473 | HPI_DEBUG_LOG(ERROR, | ||
474 | "HPI_ADAPTER_GET_MODE failed, aborting\n"); | ||
475 | goto err; | ||
476 | } | ||
477 | |||
478 | /* Note: request_irq calls asihpi_isr here */ | ||
479 | if (request_irq(pci_dev->irq, asihpi_isr, IRQF_SHARED, | ||
480 | "asihpi", &adapters[adapter_index])) { | ||
481 | dev_err(&pci_dev->dev, "request_irq(%d) failed\n", | ||
482 | pci_dev->irq); | ||
483 | goto err; | ||
484 | } | ||
485 | |||
486 | adapters[adapter_index].interrupt_mode = 1; | ||
487 | |||
488 | dev_info(&pci_dev->dev, "using irq %d\n", pci_dev->irq); | ||
489 | adapters[adapter_index].irq = pci_dev->irq; | ||
490 | } else { | ||
491 | dev_info(&pci_dev->dev, "using polled mode\n"); | ||
492 | } | ||
493 | |||
401 | dev_info(&pci_dev->dev, "probe succeeded for ASI%04X HPI index %d\n", | 494 | dev_info(&pci_dev->dev, "probe succeeded for ASI%04X HPI index %d\n", |
402 | adapter.adapter->type, adapter_index); | 495 | adapter.adapter->type, adapter_index); |
403 | 496 | ||
@@ -431,6 +524,15 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev) | |||
431 | pa = pci_get_drvdata(pci_dev); | 524 | pa = pci_get_drvdata(pci_dev); |
432 | pci = pa->adapter->pci; | 525 | pci = pa->adapter->pci; |
433 | 526 | ||
527 | /* Disable IRQ generation on DSP side */ | ||
528 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
529 | HPI_ADAPTER_SET_PROPERTY); | ||
530 | hm.adapter_index = pa->adapter->index; | ||
531 | hm.u.ax.property_set.property = HPI_ADAPTER_PROPERTY_IRQ_RATE; | ||
532 | hm.u.ax.property_set.parameter1 = 0; | ||
533 | hm.u.ax.property_set.parameter2 = 0; | ||
534 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | ||
535 | |||
434 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | 536 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, |
435 | HPI_ADAPTER_DELETE); | 537 | HPI_ADAPTER_DELETE); |
436 | hm.adapter_index = pa->adapter->index; | 538 | hm.adapter_index = pa->adapter->index; |
@@ -442,8 +544,10 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev) | |||
442 | iounmap(pci.ap_mem_base[idx]); | 544 | iounmap(pci.ap_mem_base[idx]); |
443 | } | 545 | } |
444 | 546 | ||
445 | if (pa->p_buffer) | 547 | if (pa->irq) |
446 | vfree(pa->p_buffer); | 548 | free_irq(pa->irq, pa); |
549 | |||
550 | vfree(pa->p_buffer); | ||
447 | 551 | ||
448 | if (1) | 552 | if (1) |
449 | dev_info(&pci_dev->dev, | 553 | dev_info(&pci_dev->dev, |
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index d3fbd0d76c37..4e383601b9cf 100644 --- a/sound/pci/asihpi/hpios.h +++ b/sound/pci/asihpi/hpios.h | |||
@@ -41,10 +41,6 @@ HPI Operating System Specific macros for Linux Kernel driver | |||
41 | 41 | ||
42 | #define HPI_NO_OS_FILE_OPS | 42 | #define HPI_NO_OS_FILE_OPS |
43 | 43 | ||
44 | #ifdef CONFIG_64BIT | ||
45 | #define HPI64BIT | ||
46 | #endif | ||
47 | |||
48 | /** Details of a memory area allocated with pci_alloc_consistent | 44 | /** Details of a memory area allocated with pci_alloc_consistent |
49 | Need all info for parameters to pci_free_consistent | 45 | Need all info for parameters to pci_free_consistent |
50 | */ | 46 | */ |
@@ -155,6 +151,10 @@ struct hpi_adapter { | |||
155 | struct hpi_adapter_obj *adapter; | 151 | struct hpi_adapter_obj *adapter; |
156 | struct snd_card *snd_card; | 152 | struct snd_card *snd_card; |
157 | 153 | ||
154 | int irq; | ||
155 | int interrupt_mode; | ||
156 | void (*interrupt_callback) (struct hpi_adapter *); | ||
157 | |||
158 | /* mutex prevents contention for one card | 158 | /* mutex prevents contention for one card |
159 | between multiple user programs (via ioctl) */ | 159 | between multiple user programs (via ioctl) */ |
160 | struct mutex mutex; | 160 | struct mutex mutex; |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 7895c5d300c7..9c1c4452a8ee 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -688,9 +688,7 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma) | |||
688 | if (! dma->substream || ! dma->running) | 688 | if (! dma->substream || ! dma->running) |
689 | return; | 689 | return; |
690 | dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); | 690 | dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); |
691 | snd_pcm_stream_lock(dma->substream); | 691 | snd_pcm_stop_xrun(dma->substream); |
692 | snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); | ||
693 | snd_pcm_stream_unlock(dma->substream); | ||
694 | } | 692 | } |
695 | 693 | ||
696 | /* | 694 | /* |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 3c3241309a30..b2f63e0727de 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -638,9 +638,7 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip, | |||
638 | if (! dma->substream || ! dma->running) | 638 | if (! dma->substream || ! dma->running) |
639 | return; | 639 | return; |
640 | dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); | 640 | dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); |
641 | snd_pcm_stream_lock(dma->substream); | 641 | snd_pcm_stop_xrun(dma->substream); |
642 | snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); | ||
643 | snd_pcm_stream_unlock(dma->substream); | ||
644 | } | 642 | } |
645 | 643 | ||
646 | /* | 644 | /* |
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 21ce31f636bc..996369134ea8 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c | |||
@@ -48,11 +48,10 @@ static void vortex_fix_latency(struct pci_dev *vortex) | |||
48 | { | 48 | { |
49 | int rc; | 49 | int rc; |
50 | if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) { | 50 | if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) { |
51 | pr_info( CARD_NAME | 51 | dev_info(&vortex->dev, "vortex latency is 0xff\n"); |
52 | ": vortex latency is 0xff\n"); | ||
53 | } else { | 52 | } else { |
54 | pr_warn( CARD_NAME | 53 | dev_warn(&vortex->dev, |
55 | ": could not set vortex latency: pci error 0x%x\n", rc); | 54 | "could not set vortex latency: pci error 0x%x\n", rc); |
56 | } | 55 | } |
57 | } | 56 | } |
58 | 57 | ||
@@ -70,11 +69,10 @@ static void vortex_fix_agp_bridge(struct pci_dev *via) | |||
70 | if (!(rc = pci_read_config_byte(via, 0x42, &value)) | 69 | if (!(rc = pci_read_config_byte(via, 0x42, &value)) |
71 | && ((value & 0x10) | 70 | && ((value & 0x10) |
72 | || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) { | 71 | || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) { |
73 | pr_info( CARD_NAME | 72 | dev_info(&via->dev, "bridge config is 0x%x\n", value | 0x10); |
74 | ": bridge config is 0x%x\n", value | 0x10); | ||
75 | } else { | 73 | } else { |
76 | pr_warn( CARD_NAME | 74 | dev_warn(&via->dev, |
77 | ": could not set vortex latency: pci error 0x%x\n", rc); | 75 | "could not set vortex latency: pci error 0x%x\n", rc); |
78 | } | 76 | } |
79 | } | 77 | } |
80 | 78 | ||
@@ -97,7 +95,8 @@ static void snd_vortex_workaround(struct pci_dev *vortex, int fix) | |||
97 | PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL); | 95 | PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL); |
98 | } | 96 | } |
99 | if (via) { | 97 | if (via) { |
100 | pr_info( CARD_NAME ": Activating latency workaround...\n"); | 98 | dev_info(&vortex->dev, |
99 | "Activating latency workaround...\n"); | ||
101 | vortex_fix_latency(vortex); | 100 | vortex_fix_latency(vortex); |
102 | vortex_fix_agp_bridge(via); | 101 | vortex_fix_agp_bridge(via); |
103 | } | 102 | } |
@@ -153,7 +152,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) | |||
153 | return err; | 152 | return err; |
154 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || | 153 | if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || |
155 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { | 154 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { |
156 | pr_err( "error to set DMA mask\n"); | 155 | dev_err(card->dev, "error to set DMA mask\n"); |
157 | pci_disable_device(pci); | 156 | pci_disable_device(pci); |
158 | return -ENXIO; | 157 | return -ENXIO; |
159 | } | 158 | } |
@@ -182,7 +181,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) | |||
182 | 181 | ||
183 | chip->mmio = pci_ioremap_bar(pci, 0); | 182 | chip->mmio = pci_ioremap_bar(pci, 0); |
184 | if (!chip->mmio) { | 183 | if (!chip->mmio) { |
185 | pr_err( "MMIO area remap failed.\n"); | 184 | dev_err(card->dev, "MMIO area remap failed.\n"); |
186 | err = -ENOMEM; | 185 | err = -ENOMEM; |
187 | goto ioremap_out; | 186 | goto ioremap_out; |
188 | } | 187 | } |
@@ -191,14 +190,14 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) | |||
191 | * This must be done before we do request_irq otherwise we can get spurious | 190 | * This must be done before we do request_irq otherwise we can get spurious |
192 | * interrupts that we do not handle properly and make a mess of things */ | 191 | * interrupts that we do not handle properly and make a mess of things */ |
193 | if ((err = vortex_core_init(chip)) != 0) { | 192 | if ((err = vortex_core_init(chip)) != 0) { |
194 | pr_err( "hw core init failed\n"); | 193 | dev_err(card->dev, "hw core init failed\n"); |
195 | goto core_out; | 194 | goto core_out; |
196 | } | 195 | } |
197 | 196 | ||
198 | if ((err = request_irq(pci->irq, vortex_interrupt, | 197 | if ((err = request_irq(pci->irq, vortex_interrupt, |
199 | IRQF_SHARED, KBUILD_MODNAME, | 198 | IRQF_SHARED, KBUILD_MODNAME, |
200 | chip)) != 0) { | 199 | chip)) != 0) { |
201 | pr_err( "cannot grab irq\n"); | 200 | dev_err(card->dev, "cannot grab irq\n"); |
202 | goto irq_out; | 201 | goto irq_out; |
203 | } | 202 | } |
204 | chip->irq = pci->irq; | 203 | chip->irq = pci->irq; |
@@ -315,7 +314,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
315 | if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, | 314 | if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, |
316 | sizeof(snd_vortex_synth_arg_t), &wave) < 0 | 315 | sizeof(snd_vortex_synth_arg_t), &wave) < 0 |
317 | || wave == NULL) { | 316 | || wave == NULL) { |
318 | snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n"); | 317 | dev_err(card->dev, "Can't initialize Aureal wavetable synth\n"); |
319 | } else { | 318 | } else { |
320 | snd_vortex_synth_arg_t *arg; | 319 | snd_vortex_synth_arg_t *arg; |
321 | 320 | ||
@@ -342,11 +341,11 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
342 | chip->rev = pci->revision; | 341 | chip->rev = pci->revision; |
343 | #ifdef CHIP_AU8830 | 342 | #ifdef CHIP_AU8830 |
344 | if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { | 343 | if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { |
345 | pr_alert( | 344 | dev_alert(card->dev, |
346 | "vortex: The revision (%x) of your card has not been seen before.\n", | 345 | "The revision (%x) of your card has not been seen before.\n", |
347 | chip->rev); | 346 | chip->rev); |
348 | pr_alert( | 347 | dev_alert(card->dev, |
349 | "vortex: Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n"); | 348 | "Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n"); |
350 | snd_card_free(card); | 349 | snd_card_free(card); |
351 | err = -ENODEV; | 350 | err = -ENODEV; |
352 | return err; | 351 | return err; |
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index 466a5c8e8354..3a8fefefea77 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h | |||
@@ -243,7 +243,7 @@ static int vortex_core_init(vortex_t * card); | |||
243 | static int vortex_core_shutdown(vortex_t * card); | 243 | static int vortex_core_shutdown(vortex_t * card); |
244 | static void vortex_enable_int(vortex_t * card); | 244 | static void vortex_enable_int(vortex_t * card); |
245 | static irqreturn_t vortex_interrupt(int irq, void *dev_id); | 245 | static irqreturn_t vortex_interrupt(int irq, void *dev_id); |
246 | static int vortex_alsafmt_aspfmt(int alsafmt); | 246 | static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v); |
247 | 247 | ||
248 | /* Connection stuff. */ | 248 | /* Connection stuff. */ |
249 | static void vortex_connect_default(vortex_t * vortex, int en); | 249 | static void vortex_connect_default(vortex_t * vortex, int en); |
@@ -278,7 +278,7 @@ static void vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix, | |||
278 | static void vortex_Vort3D_enable(vortex_t * v); | 278 | static void vortex_Vort3D_enable(vortex_t * v); |
279 | static void vortex_Vort3D_disable(vortex_t * v); | 279 | static void vortex_Vort3D_disable(vortex_t * v); |
280 | static void vortex_Vort3D_connect(vortex_t * vortex, int en); | 280 | static void vortex_Vort3D_connect(vortex_t * vortex, int en); |
281 | static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en); | 281 | static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v); |
282 | #endif | 282 | #endif |
283 | 283 | ||
284 | /* Driver stuff. */ | 284 | /* Driver stuff. */ |
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c index 30f760e3d2c0..ab0f87312911 100644 --- a/sound/pci/au88x0/au88x0_a3d.c +++ b/sound/pci/au88x0/au88x0_a3d.c | |||
@@ -484,12 +484,13 @@ static void a3dsrc_ZeroState(a3dsrc_t * a) | |||
484 | } | 484 | } |
485 | 485 | ||
486 | /* Reset entire A3D engine */ | 486 | /* Reset entire A3D engine */ |
487 | static void a3dsrc_ZeroStateA3D(a3dsrc_t * a) | 487 | static void a3dsrc_ZeroStateA3D(a3dsrc_t *a, vortex_t *v) |
488 | { | 488 | { |
489 | int i, var, var2; | 489 | int i, var, var2; |
490 | 490 | ||
491 | if ((a->vortex) == NULL) { | 491 | if ((a->vortex) == NULL) { |
492 | pr_err( "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n"); | 492 | dev_err(v->card->dev, |
493 | "ZeroStateA3D: ERROR: a->vortex is NULL\n"); | ||
493 | return; | 494 | return; |
494 | } | 495 | } |
495 | 496 | ||
@@ -601,7 +602,7 @@ static void vortex_Vort3D_enable(vortex_t *v) | |||
601 | Vort3DRend_Initialize(v, XT_HEADPHONE); | 602 | Vort3DRend_Initialize(v, XT_HEADPHONE); |
602 | for (i = 0; i < NR_A3D; i++) { | 603 | for (i = 0; i < NR_A3D; i++) { |
603 | vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2); | 604 | vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2); |
604 | a3dsrc_ZeroStateA3D(&(v->a3d[0])); | 605 | a3dsrc_ZeroStateA3D(&v->a3d[0], v); |
605 | } | 606 | } |
606 | /* Register ALSA controls */ | 607 | /* Register ALSA controls */ |
607 | vortex_a3d_register_controls(v); | 608 | vortex_a3d_register_controls(v); |
@@ -628,15 +629,15 @@ static void vortex_Vort3D_connect(vortex_t * v, int en) | |||
628 | v->mixxtlk[0] = | 629 | v->mixxtlk[0] = |
629 | vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); | 630 | vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); |
630 | if (v->mixxtlk[0] < 0) { | 631 | if (v->mixxtlk[0] < 0) { |
631 | pr_warn | 632 | dev_warn(v->card->dev, |
632 | ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n"); | 633 | "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); |
633 | return; | 634 | return; |
634 | } | 635 | } |
635 | v->mixxtlk[1] = | 636 | v->mixxtlk[1] = |
636 | vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); | 637 | vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); |
637 | if (v->mixxtlk[1] < 0) { | 638 | if (v->mixxtlk[1] < 0) { |
638 | pr_warn | 639 | dev_warn(v->card->dev, |
639 | ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n"); | 640 | "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); |
640 | return; | 641 | return; |
641 | } | 642 | } |
642 | #endif | 643 | #endif |
@@ -676,11 +677,11 @@ static void vortex_Vort3D_connect(vortex_t * v, int en) | |||
676 | } | 677 | } |
677 | 678 | ||
678 | /* Initialize one single A3D source. */ | 679 | /* Initialize one single A3D source. */ |
679 | static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en) | 680 | static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v) |
680 | { | 681 | { |
681 | if (a->vortex == NULL) { | 682 | if (a->vortex == NULL) { |
682 | pr_warn | 683 | dev_warn(v->card->dev, |
683 | ("vortex: Vort3D_InitializeSource: A3D source not initialized\n"); | 684 | "Vort3D_InitializeSource: A3D source not initialized\n"); |
684 | return; | 685 | return; |
685 | } | 686 | } |
686 | if (en) { | 687 | if (en) { |
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 72e81286b70e..4667c3232b7f 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c | |||
@@ -285,8 +285,8 @@ vortex_mixer_addWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) | |||
285 | temp = hwread(vortex->mmio, prev); | 285 | temp = hwread(vortex->mmio, prev); |
286 | //printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp); | 286 | //printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp); |
287 | if ((++lifeboat) > 0xf) { | 287 | if ((++lifeboat) > 0xf) { |
288 | pr_err( | 288 | dev_err(vortex->card->dev, |
289 | "vortex_mixer_addWTD: lifeboat overflow\n"); | 289 | "vortex_mixer_addWTD: lifeboat overflow\n"); |
290 | return 0; | 290 | return 0; |
291 | } | 291 | } |
292 | } | 292 | } |
@@ -303,7 +303,7 @@ vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) | |||
303 | 303 | ||
304 | eax = hwread(vortex->mmio, VORTEX_MIXER_SR); | 304 | eax = hwread(vortex->mmio, VORTEX_MIXER_SR); |
305 | if (((1 << ch) & eax) == 0) { | 305 | if (((1 << ch) & eax) == 0) { |
306 | pr_err( "mix ALARM %x\n", eax); | 306 | dev_err(vortex->card->dev, "mix ALARM %x\n", eax); |
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
309 | ebp = VORTEX_MIXER_CHNBASE + (ch << 2); | 309 | ebp = VORTEX_MIXER_CHNBASE + (ch << 2); |
@@ -324,8 +324,8 @@ vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) | |||
324 | //printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); | 324 | //printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); |
325 | while ((edx & 0xf) != mix) { | 325 | while ((edx & 0xf) != mix) { |
326 | if ((esi) > 0xf) { | 326 | if ((esi) > 0xf) { |
327 | pr_err( | 327 | dev_err(vortex->card->dev, |
328 | "vortex: mixdelWTD: error lifeboat overflow\n"); | 328 | "mixdelWTD: error lifeboat overflow\n"); |
329 | return 0; | 329 | return 0; |
330 | } | 330 | } |
331 | esp14 = ebx; | 331 | esp14 = ebx; |
@@ -492,7 +492,7 @@ vortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio) | |||
492 | hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio); | 492 | hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio); |
493 | temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2)); | 493 | temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2)); |
494 | if ((++lifeboat) > 0x9) { | 494 | if ((++lifeboat) > 0x9) { |
495 | pr_err( "Vortex: Src cvr fail\n"); | 495 | dev_err(vortex->card->dev, "Src cvr fail\n"); |
496 | break; | 496 | break; |
497 | } | 497 | } |
498 | } | 498 | } |
@@ -684,8 +684,8 @@ vortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch) | |||
684 | temp = hwread(vortex->mmio, prev); | 684 | temp = hwread(vortex->mmio, prev); |
685 | //printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp); | 685 | //printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp); |
686 | if ((++lifeboat) > 0xf) { | 686 | if ((++lifeboat) > 0xf) { |
687 | pr_err( | 687 | dev_err(vortex->card->dev, |
688 | "vortex_src_addWTD: lifeboat overflow\n"); | 688 | "vortex_src_addWTD: lifeboat overflow\n"); |
689 | return 0; | 689 | return 0; |
690 | } | 690 | } |
691 | } | 691 | } |
@@ -703,7 +703,7 @@ vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch) | |||
703 | 703 | ||
704 | eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR); | 704 | eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR); |
705 | if (((1 << ch) & eax) == 0) { | 705 | if (((1 << ch) & eax) == 0) { |
706 | pr_err( "src alarm\n"); | 706 | dev_err(vortex->card->dev, "src alarm\n"); |
707 | return 0; | 707 | return 0; |
708 | } | 708 | } |
709 | ebp = VORTEX_SRC_CHNBASE + (ch << 2); | 709 | ebp = VORTEX_SRC_CHNBASE + (ch << 2); |
@@ -724,8 +724,8 @@ vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch) | |||
724 | //printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); | 724 | //printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); |
725 | while ((edx & 0xf) != src) { | 725 | while ((edx & 0xf) != src) { |
726 | if ((esi) > 0xf) { | 726 | if ((esi) > 0xf) { |
727 | pr_warn | 727 | dev_warn(vortex->card->dev, |
728 | ("vortex: srcdelWTD: error, lifeboat overflow\n"); | 728 | "srcdelWTD: error, lifeboat overflow\n"); |
729 | return 0; | 729 | return 0; |
730 | } | 730 | } |
731 | esp14 = ebx; | 731 | esp14 = ebx; |
@@ -819,8 +819,8 @@ vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int stereo, int priority, | |||
819 | do { | 819 | do { |
820 | temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)); | 820 | temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)); |
821 | if (lifeboat++ > 0xbb8) { | 821 | if (lifeboat++ > 0xbb8) { |
822 | pr_err( | 822 | dev_err(vortex->card->dev, |
823 | "Vortex: vortex_fifo_setadbctrl fail\n"); | 823 | "vortex_fifo_setadbctrl fail\n"); |
824 | break; | 824 | break; |
825 | } | 825 | } |
826 | } | 826 | } |
@@ -915,7 +915,8 @@ vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority, | |||
915 | do { | 915 | do { |
916 | temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)); | 916 | temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)); |
917 | if (lifeboat++ > 0xbb8) { | 917 | if (lifeboat++ > 0xbb8) { |
918 | pr_err( "Vortex: vortex_fifo_setwtctrl fail\n"); | 918 | dev_err(vortex->card->dev, |
919 | "vortex_fifo_setwtctrl fail\n"); | ||
919 | break; | 920 | break; |
920 | } | 921 | } |
921 | } | 922 | } |
@@ -1042,7 +1043,7 @@ static void vortex_fifo_init(vortex_t * vortex) | |||
1042 | for (x = NR_ADB - 1; x >= 0; x--) { | 1043 | for (x = NR_ADB - 1; x >= 0; x--) { |
1043 | hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1)); | 1044 | hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1)); |
1044 | if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1)) | 1045 | if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1)) |
1045 | pr_err( "bad adb fifo reset!"); | 1046 | dev_err(vortex->card->dev, "bad adb fifo reset!"); |
1046 | vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE); | 1047 | vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE); |
1047 | addr -= 4; | 1048 | addr -= 4; |
1048 | } | 1049 | } |
@@ -1053,9 +1054,9 @@ static void vortex_fifo_init(vortex_t * vortex) | |||
1053 | for (x = NR_WT - 1; x >= 0; x--) { | 1054 | for (x = NR_WT - 1; x >= 0; x--) { |
1054 | hwwrite(vortex->mmio, addr, FIFO_U0); | 1055 | hwwrite(vortex->mmio, addr, FIFO_U0); |
1055 | if (hwread(vortex->mmio, addr) != FIFO_U0) | 1056 | if (hwread(vortex->mmio, addr) != FIFO_U0) |
1056 | pr_err( | 1057 | dev_err(vortex->card->dev, |
1057 | "bad wt fifo reset (0x%08x, 0x%08x)!\n", | 1058 | "bad wt fifo reset (0x%08x, 0x%08x)!\n", |
1058 | addr, hwread(vortex->mmio, addr)); | 1059 | addr, hwread(vortex->mmio, addr)); |
1059 | vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE); | 1060 | vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE); |
1060 | addr -= 4; | 1061 | addr -= 4; |
1061 | } | 1062 | } |
@@ -1213,8 +1214,9 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma) | |||
1213 | if (dma->period_virt >= dma->nr_periods) | 1214 | if (dma->period_virt >= dma->nr_periods) |
1214 | dma->period_virt -= dma->nr_periods; | 1215 | dma->period_virt -= dma->nr_periods; |
1215 | if (delta != 1) | 1216 | if (delta != 1) |
1216 | pr_info( "vortex: %d virt=%d, real=%d, delta=%d\n", | 1217 | dev_info(vortex->card->dev, |
1217 | adbdma, dma->period_virt, dma->period_real, delta); | 1218 | "%d virt=%d, real=%d, delta=%d\n", |
1219 | adbdma, dma->period_virt, dma->period_real, delta); | ||
1218 | 1220 | ||
1219 | return delta; | 1221 | return delta; |
1220 | } | 1222 | } |
@@ -1482,8 +1484,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma) | |||
1482 | dma->period_real = page; | 1484 | dma->period_real = page; |
1483 | 1485 | ||
1484 | if (delta != 1) | 1486 | if (delta != 1) |
1485 | pr_warn( "vortex: wt virt = %d, delta = %d\n", | 1487 | dev_warn(vortex->card->dev, "wt virt = %d, delta = %d\n", |
1486 | dma->period_virt, delta); | 1488 | dma->period_virt, delta); |
1487 | 1489 | ||
1488 | return delta; | 1490 | return delta; |
1489 | } | 1491 | } |
@@ -1667,9 +1669,9 @@ vortex_adb_addroutes(vortex_t * vortex, unsigned char channel, | |||
1667 | hwread(vortex->mmio, | 1669 | hwread(vortex->mmio, |
1668 | VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK; | 1670 | VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK; |
1669 | if ((lifeboat++) > ADB_MASK) { | 1671 | if ((lifeboat++) > ADB_MASK) { |
1670 | pr_err( | 1672 | dev_err(vortex->card->dev, |
1671 | "vortex_adb_addroutes: unending route! 0x%x\n", | 1673 | "vortex_adb_addroutes: unending route! 0x%x\n", |
1672 | *route); | 1674 | *route); |
1673 | return; | 1675 | return; |
1674 | } | 1676 | } |
1675 | } | 1677 | } |
@@ -1703,9 +1705,9 @@ vortex_adb_delroutes(vortex_t * vortex, unsigned char channel, | |||
1703 | hwread(vortex->mmio, | 1705 | hwread(vortex->mmio, |
1704 | VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK; | 1706 | VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK; |
1705 | if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) { | 1707 | if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) { |
1706 | pr_err( | 1708 | dev_err(vortex->card->dev, |
1707 | "vortex_adb_delroutes: route not found! 0x%x\n", | 1709 | "vortex_adb_delroutes: route not found! 0x%x\n", |
1708 | route0); | 1710 | route0); |
1709 | return; | 1711 | return; |
1710 | } | 1712 | } |
1711 | } | 1713 | } |
@@ -2045,7 +2047,9 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) | |||
2045 | } | 2047 | } |
2046 | } | 2048 | } |
2047 | } | 2049 | } |
2048 | pr_err( "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype); | 2050 | dev_err(vortex->card->dev, |
2051 | "FATAL: ResManager: resource type %d exhausted.\n", | ||
2052 | restype); | ||
2049 | return -ENOMEM; | 2053 | return -ENOMEM; |
2050 | } | 2054 | } |
2051 | 2055 | ||
@@ -2173,11 +2177,13 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir, | |||
2173 | memset(stream->resources, 0, | 2177 | memset(stream->resources, 0, |
2174 | sizeof(unsigned char) * | 2178 | sizeof(unsigned char) * |
2175 | VORTEX_RESOURCE_LAST); | 2179 | VORTEX_RESOURCE_LAST); |
2176 | pr_err( "vortex: out of A3D sources. Sorry\n"); | 2180 | dev_err(vortex->card->dev, |
2181 | "out of A3D sources. Sorry\n"); | ||
2177 | return -EBUSY; | 2182 | return -EBUSY; |
2178 | } | 2183 | } |
2179 | /* (De)Initialize A3D hardware source. */ | 2184 | /* (De)Initialize A3D hardware source. */ |
2180 | vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en); | 2185 | vortex_Vort3D_InitializeSource(&vortex->a3d[a3d], en, |
2186 | vortex); | ||
2181 | } | 2187 | } |
2182 | /* Make SPDIF out exclusive to "spdif" device when in use. */ | 2188 | /* Make SPDIF out exclusive to "spdif" device when in use. */ |
2183 | if ((stream->type == VORTEX_PCM_SPDIF) && (en)) { | 2189 | if ((stream->type == VORTEX_PCM_SPDIF) && (en)) { |
@@ -2421,7 +2427,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) | |||
2421 | hwread(vortex->mmio, VORTEX_IRQ_SOURCE); | 2427 | hwread(vortex->mmio, VORTEX_IRQ_SOURCE); |
2422 | // Is at least one IRQ flag set? | 2428 | // Is at least one IRQ flag set? |
2423 | if (source == 0) { | 2429 | if (source == 0) { |
2424 | pr_err( "vortex: missing irq source\n"); | 2430 | dev_err(vortex->card->dev, "missing irq source\n"); |
2425 | return IRQ_NONE; | 2431 | return IRQ_NONE; |
2426 | } | 2432 | } |
2427 | 2433 | ||
@@ -2429,19 +2435,19 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) | |||
2429 | // Attend every interrupt source. | 2435 | // Attend every interrupt source. |
2430 | if (unlikely(source & IRQ_ERR_MASK)) { | 2436 | if (unlikely(source & IRQ_ERR_MASK)) { |
2431 | if (source & IRQ_FATAL) { | 2437 | if (source & IRQ_FATAL) { |
2432 | pr_err( "vortex: IRQ fatal error\n"); | 2438 | dev_err(vortex->card->dev, "IRQ fatal error\n"); |
2433 | } | 2439 | } |
2434 | if (source & IRQ_PARITY) { | 2440 | if (source & IRQ_PARITY) { |
2435 | pr_err( "vortex: IRQ parity error\n"); | 2441 | dev_err(vortex->card->dev, "IRQ parity error\n"); |
2436 | } | 2442 | } |
2437 | if (source & IRQ_REG) { | 2443 | if (source & IRQ_REG) { |
2438 | pr_err( "vortex: IRQ reg error\n"); | 2444 | dev_err(vortex->card->dev, "IRQ reg error\n"); |
2439 | } | 2445 | } |
2440 | if (source & IRQ_FIFO) { | 2446 | if (source & IRQ_FIFO) { |
2441 | pr_err( "vortex: IRQ fifo error\n"); | 2447 | dev_err(vortex->card->dev, "IRQ fifo error\n"); |
2442 | } | 2448 | } |
2443 | if (source & IRQ_DMA) { | 2449 | if (source & IRQ_DMA) { |
2444 | pr_err( "vortex: IRQ dma error\n"); | 2450 | dev_err(vortex->card->dev, "IRQ dma error\n"); |
2445 | } | 2451 | } |
2446 | handled = 1; | 2452 | handled = 1; |
2447 | } | 2453 | } |
@@ -2489,7 +2495,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) | |||
2489 | } | 2495 | } |
2490 | 2496 | ||
2491 | if (!handled) { | 2497 | if (!handled) { |
2492 | pr_err( "vortex: unknown irq source %x\n", source); | 2498 | dev_err(vortex->card->dev, "unknown irq source %x\n", source); |
2493 | } | 2499 | } |
2494 | return IRQ_RETVAL(handled); | 2500 | return IRQ_RETVAL(handled); |
2495 | } | 2501 | } |
@@ -2546,7 +2552,7 @@ vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short | |||
2546 | while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { | 2552 | while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { |
2547 | udelay(100); | 2553 | udelay(100); |
2548 | if (lifeboat++ > POLL_COUNT) { | 2554 | if (lifeboat++ > POLL_COUNT) { |
2549 | pr_err( "vortex: ac97 codec stuck busy\n"); | 2555 | dev_err(card->card->dev, "ac97 codec stuck busy\n"); |
2550 | return; | 2556 | return; |
2551 | } | 2557 | } |
2552 | } | 2558 | } |
@@ -2572,7 +2578,7 @@ static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short | |||
2572 | while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { | 2578 | while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { |
2573 | udelay(100); | 2579 | udelay(100); |
2574 | if (lifeboat++ > POLL_COUNT) { | 2580 | if (lifeboat++ > POLL_COUNT) { |
2575 | pr_err( "vortex: ac97 codec stuck busy\n"); | 2581 | dev_err(card->card->dev, "ac97 codec stuck busy\n"); |
2576 | return 0xffff; | 2582 | return 0xffff; |
2577 | } | 2583 | } |
2578 | } | 2584 | } |
@@ -2586,7 +2592,8 @@ static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short | |||
2586 | udelay(100); | 2592 | udelay(100); |
2587 | data = hwread(card->mmio, VORTEX_CODEC_IO); | 2593 | data = hwread(card->mmio, VORTEX_CODEC_IO); |
2588 | if (lifeboat++ > POLL_COUNT) { | 2594 | if (lifeboat++ > POLL_COUNT) { |
2589 | pr_err( "vortex: ac97 address never arrived\n"); | 2595 | dev_err(card->card->dev, |
2596 | "ac97 address never arrived\n"); | ||
2590 | return 0xffff; | 2597 | return 0xffff; |
2591 | } | 2598 | } |
2592 | } while ((data & VORTEX_CODEC_ADDMASK) != | 2599 | } while ((data & VORTEX_CODEC_ADDMASK) != |
@@ -2683,7 +2690,7 @@ static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode) | |||
2683 | static int vortex_core_init(vortex_t *vortex) | 2690 | static int vortex_core_init(vortex_t *vortex) |
2684 | { | 2691 | { |
2685 | 2692 | ||
2686 | pr_info( "Vortex: init.... "); | 2693 | dev_info(vortex->card->dev, "init started\n"); |
2687 | /* Hardware Init. */ | 2694 | /* Hardware Init. */ |
2688 | hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff); | 2695 | hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff); |
2689 | msleep(5); | 2696 | msleep(5); |
@@ -2728,7 +2735,7 @@ static int vortex_core_init(vortex_t *vortex) | |||
2728 | //vortex_enable_timer_int(vortex); | 2735 | //vortex_enable_timer_int(vortex); |
2729 | //vortex_disable_timer_int(vortex); | 2736 | //vortex_disable_timer_int(vortex); |
2730 | 2737 | ||
2731 | pr_info( "done.\n"); | 2738 | dev_info(vortex->card->dev, "init.... done.\n"); |
2732 | spin_lock_init(&vortex->lock); | 2739 | spin_lock_init(&vortex->lock); |
2733 | 2740 | ||
2734 | return 0; | 2741 | return 0; |
@@ -2737,7 +2744,7 @@ static int vortex_core_init(vortex_t *vortex) | |||
2737 | static int vortex_core_shutdown(vortex_t * vortex) | 2744 | static int vortex_core_shutdown(vortex_t * vortex) |
2738 | { | 2745 | { |
2739 | 2746 | ||
2740 | pr_info( "Vortex: shutdown..."); | 2747 | dev_info(vortex->card->dev, "shutdown started\n"); |
2741 | #ifndef CHIP_AU8820 | 2748 | #ifndef CHIP_AU8820 |
2742 | vortex_eq_free(vortex); | 2749 | vortex_eq_free(vortex); |
2743 | vortex_Vort3D_disable(vortex); | 2750 | vortex_Vort3D_disable(vortex); |
@@ -2759,13 +2766,13 @@ static int vortex_core_shutdown(vortex_t * vortex) | |||
2759 | msleep(5); | 2766 | msleep(5); |
2760 | hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff); | 2767 | hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff); |
2761 | 2768 | ||
2762 | pr_info( "done.\n"); | 2769 | dev_info(vortex->card->dev, "shutdown.... done.\n"); |
2763 | return 0; | 2770 | return 0; |
2764 | } | 2771 | } |
2765 | 2772 | ||
2766 | /* Alsa support. */ | 2773 | /* Alsa support. */ |
2767 | 2774 | ||
2768 | static int vortex_alsafmt_aspfmt(int alsafmt) | 2775 | static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v) |
2769 | { | 2776 | { |
2770 | int fmt; | 2777 | int fmt; |
2771 | 2778 | ||
@@ -2793,7 +2800,8 @@ static int vortex_alsafmt_aspfmt(int alsafmt) | |||
2793 | break; | 2800 | break; |
2794 | default: | 2801 | default: |
2795 | fmt = 0x8; | 2802 | fmt = 0x8; |
2796 | pr_err( "vortex: format unsupported %d\n", alsafmt); | 2803 | dev_err(v->card->dev, |
2804 | "format unsupported %d\n", alsafmt); | ||
2797 | break; | 2805 | break; |
2798 | } | 2806 | } |
2799 | return fmt; | 2807 | return fmt; |
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c index 9404ba73eaf6..9585c5c63b96 100644 --- a/sound/pci/au88x0/au88x0_eq.c +++ b/sound/pci/au88x0/au88x0_eq.c | |||
@@ -845,7 +845,8 @@ snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u | |||
845 | 845 | ||
846 | vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); | 846 | vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); |
847 | if (count != 20) { | 847 | if (count != 20) { |
848 | pr_err( "vortex: peak count error 20 != %d \n", count); | 848 | dev_err(vortex->card->dev, |
849 | "peak count error 20 != %d\n", count); | ||
849 | return -1; | 850 | return -1; |
850 | } | 851 | } |
851 | for (i = 0; i < 20; i++) | 852 | for (i = 0; i < 20; i++) |
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c index 72daf6cf8169..151815b857a0 100644 --- a/sound/pci/au88x0/au88x0_game.c +++ b/sound/pci/au88x0/au88x0_game.c | |||
@@ -98,7 +98,8 @@ static int vortex_gameport_register(vortex_t *vortex) | |||
98 | 98 | ||
99 | vortex->gameport = gp = gameport_allocate_port(); | 99 | vortex->gameport = gp = gameport_allocate_port(); |
100 | if (!gp) { | 100 | if (!gp) { |
101 | pr_err( "vortex: cannot allocate memory for gameport\n"); | 101 | dev_err(vortex->card->dev, |
102 | "cannot allocate memory for gameport\n"); | ||
102 | return -ENOMEM; | 103 | return -ENOMEM; |
103 | } | 104 | } |
104 | 105 | ||
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index 328c1943c0c3..1025e55ca854 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c | |||
@@ -73,7 +73,7 @@ static int snd_vortex_midi(vortex_t *vortex) | |||
73 | /* Check if anything is OK. */ | 73 | /* Check if anything is OK. */ |
74 | temp = hwread(vortex->mmio, VORTEX_MIDI_DATA); | 74 | temp = hwread(vortex->mmio, VORTEX_MIDI_DATA); |
75 | if (temp != MPU401_ACK /*0xfe */ ) { | 75 | if (temp != MPU401_ACK /*0xfe */ ) { |
76 | pr_err( "midi port doesn't acknowledge!\n"); | 76 | dev_err(vortex->card->dev, "midi port doesn't acknowledge!\n"); |
77 | return -ENODEV; | 77 | return -ENODEV; |
78 | } | 78 | } |
79 | /* Enable MPU401 interrupts. */ | 79 | /* Enable MPU401 interrupts. */ |
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 5adc6b92ffab..a6d6d8d0867a 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c | |||
@@ -227,7 +227,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, | |||
227 | err = | 227 | err = |
228 | snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 228 | snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
229 | if (err < 0) { | 229 | if (err < 0) { |
230 | pr_err( "Vortex: pcm page alloc failed!\n"); | 230 | dev_err(chip->card->dev, "Vortex: pcm page alloc failed!\n"); |
231 | return err; | 231 | return err; |
232 | } | 232 | } |
233 | /* | 233 | /* |
@@ -332,7 +332,7 @@ static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream) | |||
332 | dir = 1; | 332 | dir = 1; |
333 | else | 333 | else |
334 | dir = 0; | 334 | dir = 0; |
335 | fmt = vortex_alsafmt_aspfmt(runtime->format); | 335 | fmt = vortex_alsafmt_aspfmt(runtime->format, chip); |
336 | spin_lock_irq(&chip->lock); | 336 | spin_lock_irq(&chip->lock); |
337 | if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { | 337 | if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { |
338 | vortex_adbdma_setmode(chip, dma, 1, dir, fmt, | 338 | vortex_adbdma_setmode(chip, dma, 1, dir, fmt, |
@@ -371,7 +371,7 @@ static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
371 | } | 371 | } |
372 | #ifndef CHIP_AU8810 | 372 | #ifndef CHIP_AU8810 |
373 | else { | 373 | else { |
374 | pr_info( "vortex: wt start %d\n", dma); | 374 | dev_info(chip->card->dev, "wt start %d\n", dma); |
375 | vortex_wtdma_startfifo(chip, dma); | 375 | vortex_wtdma_startfifo(chip, dma); |
376 | } | 376 | } |
377 | #endif | 377 | #endif |
@@ -384,7 +384,7 @@ static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
384 | vortex_adbdma_stopfifo(chip, dma); | 384 | vortex_adbdma_stopfifo(chip, dma); |
385 | #ifndef CHIP_AU8810 | 385 | #ifndef CHIP_AU8810 |
386 | else { | 386 | else { |
387 | pr_info( "vortex: wt stop %d\n", dma); | 387 | dev_info(chip->card->dev, "wt stop %d\n", dma); |
388 | vortex_wtdma_stopfifo(chip, dma); | 388 | vortex_wtdma_stopfifo(chip, dma); |
389 | } | 389 | } |
390 | #endif | 390 | #endif |
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index f094bac24291..78e12f4796f3 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c | |||
@@ -90,7 +90,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) | |||
90 | hwwrite(vortex->mmio, WT_PARM(wt, 2), 0); | 90 | hwwrite(vortex->mmio, WT_PARM(wt, 2), 0); |
91 | 91 | ||
92 | temp = hwread(vortex->mmio, WT_PARM(wt, 3)); | 92 | temp = hwread(vortex->mmio, WT_PARM(wt, 3)); |
93 | pr_debug( "vortex: WT PARM3: %x\n", temp); | 93 | dev_dbg(vortex->card->dev, "WT PARM3: %x\n", temp); |
94 | //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp); | 94 | //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp); |
95 | 95 | ||
96 | hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0); | 96 | hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0); |
@@ -98,7 +98,8 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) | |||
98 | hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0); | 98 | hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0); |
99 | hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0); | 99 | hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0); |
100 | 100 | ||
101 | pr_debug( "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt))); | 101 | dev_dbg(vortex->card->dev, "WT GMODE: %x\n", |
102 | hwread(vortex->mmio, WT_GMODE(wt))); | ||
102 | 103 | ||
103 | hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff); | 104 | hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff); |
104 | hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810); | 105 | hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810); |
@@ -106,7 +107,8 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) | |||
106 | voice->parm0 = voice->parm1 = 0xcfb23e2f; | 107 | voice->parm0 = voice->parm1 = 0xcfb23e2f; |
107 | hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); | 108 | hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); |
108 | hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); | 109 | hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); |
109 | pr_debug( "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt))); | 110 | dev_dbg(vortex->card->dev, "WT GMODE 2 : %x\n", |
111 | hwread(vortex->mmio, WT_GMODE(wt))); | ||
110 | return 0; | 112 | return 0; |
111 | } | 113 | } |
112 | 114 | ||
@@ -196,14 +198,15 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, | |||
196 | 198 | ||
197 | if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) { | 199 | if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) { |
198 | if (wt >= (NR_WT / NR_WT_PB)) { | 200 | if (wt >= (NR_WT / NR_WT_PB)) { |
199 | pr_warn | 201 | dev_warn(vortex->card->dev, |
200 | ("vortex: WT SetReg: bank out of range. reg=0x%x, wt=%d\n", | 202 | "WT SetReg: bank out of range. reg=0x%x, wt=%d\n", |
201 | reg, wt); | 203 | reg, wt); |
202 | return 0; | 204 | return 0; |
203 | } | 205 | } |
204 | } else { | 206 | } else { |
205 | if (wt >= NR_WT) { | 207 | if (wt >= NR_WT) { |
206 | pr_err( "vortex: WT SetReg: voice out of range\n"); | 208 | dev_err(vortex->card->dev, |
209 | "WT SetReg: voice out of range\n"); | ||
207 | return 0; | 210 | return 0; |
208 | } | 211 | } |
209 | } | 212 | } |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 3878cf5de9a4..e1cf01949fda 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -725,19 +725,10 @@ static int snd_aw2_new_pcm(struct aw2 *chip) | |||
725 | static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol, | 725 | static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol, |
726 | struct snd_ctl_elem_info *uinfo) | 726 | struct snd_ctl_elem_info *uinfo) |
727 | { | 727 | { |
728 | static char *texts[2] = { | 728 | static const char * const texts[2] = { |
729 | "Analog", "Digital" | 729 | "Analog", "Digital" |
730 | }; | 730 | }; |
731 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 731 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
732 | uinfo->count = 1; | ||
733 | uinfo->value.enumerated.items = 2; | ||
734 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) { | ||
735 | uinfo->value.enumerated.item = | ||
736 | uinfo->value.enumerated.items - 1; | ||
737 | } | ||
738 | strcpy(uinfo->value.enumerated.name, | ||
739 | texts[uinfo->value.enumerated.item]); | ||
740 | return 0; | ||
741 | } | 732 | } |
742 | 733 | ||
743 | static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol, | 734 | static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 5a69e26cb2fb..fdbb9c05c77b 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -1034,11 +1034,6 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol, | |||
1034 | const char * const *p = NULL; | 1034 | const char * const *p = NULL; |
1035 | 1035 | ||
1036 | snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); | 1036 | snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); |
1037 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1038 | uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1; | ||
1039 | uinfo->value.enumerated.items = reg.enum_c; | ||
1040 | if (uinfo->value.enumerated.item > reg.enum_c - 1U) | ||
1041 | uinfo->value.enumerated.item = reg.enum_c - 1U; | ||
1042 | if (reg.reg == IDX_MIXER_ADVCTL2) { | 1037 | if (reg.reg == IDX_MIXER_ADVCTL2) { |
1043 | switch(reg.lchan_shift) { | 1038 | switch(reg.lchan_shift) { |
1044 | case 8: /* modem out sel */ | 1039 | case 8: /* modem out sel */ |
@@ -1051,12 +1046,12 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol, | |||
1051 | p = texts4; | 1046 | p = texts4; |
1052 | break; | 1047 | break; |
1053 | } | 1048 | } |
1054 | } else | 1049 | } else if (reg.reg == IDX_MIXER_REC_SELECT) |
1055 | if (reg.reg == IDX_MIXER_REC_SELECT) | ||
1056 | p = texts3; | 1050 | p = texts3; |
1057 | 1051 | ||
1058 | strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]); | 1052 | return snd_ctl_enum_info(uinfo, |
1059 | return 0; | 1053 | (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1, |
1054 | reg.enum_c, p); | ||
1060 | } | 1055 | } |
1061 | 1056 | ||
1062 | static int | 1057 | static int |
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 27de0de90018..68c0eb0a2807 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
@@ -185,17 +185,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol, | |||
185 | static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol, | 185 | static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol, |
186 | struct snd_ctl_elem_info *uinfo) | 186 | struct snd_ctl_elem_info *uinfo) |
187 | { | 187 | { |
188 | static char *texts[6] = { | 188 | static const char * const texts[6] = { |
189 | "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out" | 189 | "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out" |
190 | }; | 190 | }; |
191 | 191 | ||
192 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 192 | return snd_ctl_enum_info(uinfo, 1, 6, texts); |
193 | uinfo->count = 1; | ||
194 | uinfo->value.enumerated.items = 6; | ||
195 | if (uinfo->value.enumerated.item > 5) | ||
196 | uinfo->value.enumerated.item = 5; | ||
197 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
198 | return 0; | ||
199 | } | 193 | } |
200 | 194 | ||
201 | static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol, | 195 | static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol, |
@@ -228,17 +222,11 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol, | |||
228 | static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol, | 222 | static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol, |
229 | struct snd_ctl_elem_info *uinfo) | 223 | struct snd_ctl_elem_info *uinfo) |
230 | { | 224 | { |
231 | static char *texts[6] = { | 225 | static const char * const texts[4] = { |
232 | "Phone", "Mic", "Line in", "Aux" | 226 | "Phone", "Mic", "Line in", "Aux" |
233 | }; | 227 | }; |
234 | 228 | ||
235 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 229 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
236 | uinfo->count = 1; | ||
237 | uinfo->value.enumerated.items = 4; | ||
238 | if (uinfo->value.enumerated.item > 3) | ||
239 | uinfo->value.enumerated.item = 3; | ||
240 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
241 | return 0; | ||
242 | } | 230 | } |
243 | 231 | ||
244 | static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol, | 232 | static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol, |
@@ -273,29 +261,17 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, | |||
273 | static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol, | 261 | static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol, |
274 | struct snd_ctl_elem_info *uinfo) | 262 | struct snd_ctl_elem_info *uinfo) |
275 | { | 263 | { |
276 | static char *texts[2] = { "Side out", "Line in" }; | 264 | static const char * const texts[2] = { "Side out", "Line in" }; |
277 | 265 | ||
278 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 266 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
279 | uinfo->count = 1; | ||
280 | uinfo->value.enumerated.items = 2; | ||
281 | if (uinfo->value.enumerated.item > 1) | ||
282 | uinfo->value.enumerated.item = 1; | ||
283 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
284 | return 0; | ||
285 | } | 267 | } |
286 | 268 | ||
287 | static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol, | 269 | static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol, |
288 | struct snd_ctl_elem_info *uinfo) | 270 | struct snd_ctl_elem_info *uinfo) |
289 | { | 271 | { |
290 | static char *texts[2] = { "Line in", "Mic in" }; | 272 | static const char * const texts[2] = { "Line in", "Mic in" }; |
291 | 273 | ||
292 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 274 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
293 | uinfo->count = 1; | ||
294 | uinfo->value.enumerated.items = 2; | ||
295 | if (uinfo->value.enumerated.item > 1) | ||
296 | uinfo->value.enumerated.item = 1; | ||
297 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
298 | return 0; | ||
299 | } | 275 | } |
300 | 276 | ||
301 | static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol, | 277 | static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 454659074390..977a59855fa6 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
@@ -438,7 +438,9 @@ atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
438 | position = src->ops->get_ca(src); | 438 | position = src->ops->get_ca(src); |
439 | 439 | ||
440 | if (position < apcm->vm_block->addr) { | 440 | if (position < apcm->vm_block->addr) { |
441 | snd_printdd("ctxfi: bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", position, apcm->vm_block->addr, apcm->vm_block->size); | 441 | dev_dbg(atc->card->dev, |
442 | "bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", | ||
443 | position, apcm->vm_block->addr, apcm->vm_block->size); | ||
442 | position = apcm->vm_block->addr; | 444 | position = apcm->vm_block->addr; |
443 | } | 445 | } |
444 | 446 | ||
@@ -1145,7 +1147,6 @@ static int atc_release_resources(struct ct_atc *atc) | |||
1145 | int i; | 1147 | int i; |
1146 | struct daio_mgr *daio_mgr = NULL; | 1148 | struct daio_mgr *daio_mgr = NULL; |
1147 | struct dao *dao = NULL; | 1149 | struct dao *dao = NULL; |
1148 | struct dai *dai = NULL; | ||
1149 | struct daio *daio = NULL; | 1150 | struct daio *daio = NULL; |
1150 | struct sum_mgr *sum_mgr = NULL; | 1151 | struct sum_mgr *sum_mgr = NULL; |
1151 | struct src_mgr *src_mgr = NULL; | 1152 | struct src_mgr *src_mgr = NULL; |
@@ -1172,9 +1173,6 @@ static int atc_release_resources(struct ct_atc *atc) | |||
1172 | dao = container_of(daio, struct dao, daio); | 1173 | dao = container_of(daio, struct dao, daio); |
1173 | dao->ops->clear_left_input(dao); | 1174 | dao->ops->clear_left_input(dao); |
1174 | dao->ops->clear_right_input(dao); | 1175 | dao->ops->clear_right_input(dao); |
1175 | } else { | ||
1176 | dai = container_of(daio, struct dai, daio); | ||
1177 | /* some thing to do for dai ... */ | ||
1178 | } | 1176 | } |
1179 | daio_mgr->put_daio(daio_mgr, daio); | 1177 | daio_mgr->put_daio(daio_mgr, daio); |
1180 | } | 1178 | } |
@@ -1299,7 +1297,7 @@ static int atc_identify_card(struct ct_atc *atc, unsigned int ssid) | |||
1299 | atc->model = CT20K2_UNKNOWN; | 1297 | atc->model = CT20K2_UNKNOWN; |
1300 | } | 1298 | } |
1301 | atc->model_name = ct_subsys_name[atc->model]; | 1299 | atc->model_name = ct_subsys_name[atc->model]; |
1302 | snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", | 1300 | dev_info(atc->card->dev, "chip %s model %s (%04x:%04x) is found\n", |
1303 | atc->chip_name, atc->model_name, | 1301 | atc->chip_name, atc->model_name, |
1304 | vendor_id, device_id); | 1302 | vendor_id, device_id); |
1305 | return 0; | 1303 | return 0; |
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index c1c3f8816fff..9b87dd28de83 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c | |||
@@ -528,8 +528,6 @@ static int get_daio_rsc(struct daio_mgr *mgr, | |||
528 | struct daio **rdaio) | 528 | struct daio **rdaio) |
529 | { | 529 | { |
530 | int err; | 530 | int err; |
531 | struct dai *dai = NULL; | ||
532 | struct dao *dao = NULL; | ||
533 | unsigned long flags; | 531 | unsigned long flags; |
534 | 532 | ||
535 | *rdaio = NULL; | 533 | *rdaio = NULL; |
@@ -544,27 +542,30 @@ static int get_daio_rsc(struct daio_mgr *mgr, | |||
544 | return err; | 542 | return err; |
545 | } | 543 | } |
546 | 544 | ||
545 | err = -ENOMEM; | ||
547 | /* Allocate mem for daio resource */ | 546 | /* Allocate mem for daio resource */ |
548 | if (desc->type <= DAIO_OUT_MAX) { | 547 | if (desc->type <= DAIO_OUT_MAX) { |
549 | dao = kzalloc(sizeof(*dao), GFP_KERNEL); | 548 | struct dao *dao = kzalloc(sizeof(*dao), GFP_KERNEL); |
550 | if (!dao) { | 549 | if (!dao) |
551 | err = -ENOMEM; | ||
552 | goto error; | 550 | goto error; |
553 | } | 551 | |
554 | err = dao_rsc_init(dao, desc, mgr); | 552 | err = dao_rsc_init(dao, desc, mgr); |
555 | if (err) | 553 | if (err) { |
554 | kfree(dao); | ||
556 | goto error; | 555 | goto error; |
556 | } | ||
557 | 557 | ||
558 | *rdaio = &dao->daio; | 558 | *rdaio = &dao->daio; |
559 | } else { | 559 | } else { |
560 | dai = kzalloc(sizeof(*dai), GFP_KERNEL); | 560 | struct dai *dai = kzalloc(sizeof(*dai), GFP_KERNEL); |
561 | if (!dai) { | 561 | if (!dai) |
562 | err = -ENOMEM; | ||
563 | goto error; | 562 | goto error; |
564 | } | 563 | |
565 | err = dai_rsc_init(dai, desc, mgr); | 564 | err = dai_rsc_init(dai, desc, mgr); |
566 | if (err) | 565 | if (err) { |
566 | kfree(dai); | ||
567 | goto error; | 567 | goto error; |
568 | } | ||
568 | 569 | ||
569 | *rdaio = &dai->daio; | 570 | *rdaio = &dai->daio; |
570 | } | 571 | } |
@@ -575,11 +576,6 @@ static int get_daio_rsc(struct daio_mgr *mgr, | |||
575 | return 0; | 576 | return 0; |
576 | 577 | ||
577 | error: | 578 | error: |
578 | if (dao) | ||
579 | kfree(dao); | ||
580 | else if (dai) | ||
581 | kfree(dai); | ||
582 | |||
583 | spin_lock_irqsave(&mgr->mgr_lock, flags); | 579 | spin_lock_irqsave(&mgr->mgr_lock, flags); |
584 | daio_mgr_put_rsc(&mgr->mgr, desc->type); | 580 | daio_mgr_put_rsc(&mgr->mgr, desc->type); |
585 | spin_unlock_irqrestore(&mgr->mgr_lock, flags); | 581 | spin_unlock_irqrestore(&mgr->mgr_lock, flags); |
diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c index 03fb909085af..a5d460453d7b 100644 --- a/sound/pci/ctxfi/cttimer.c +++ b/sound/pci/ctxfi/cttimer.c | |||
@@ -421,12 +421,12 @@ struct ct_timer *ct_timer_new(struct ct_atc *atc) | |||
421 | atimer->atc = atc; | 421 | atimer->atc = atc; |
422 | hw = atc->hw; | 422 | hw = atc->hw; |
423 | if (!use_system_timer && hw->set_timer_irq) { | 423 | if (!use_system_timer && hw->set_timer_irq) { |
424 | snd_printd(KERN_INFO "ctxfi: Use xfi-native timer\n"); | 424 | dev_info(atc->card->dev, "Use xfi-native timer\n"); |
425 | atimer->ops = &ct_xfitimer_ops; | 425 | atimer->ops = &ct_xfitimer_ops; |
426 | hw->irq_callback_data = atimer; | 426 | hw->irq_callback_data = atimer; |
427 | hw->irq_callback = ct_timer_interrupt; | 427 | hw->irq_callback = ct_timer_interrupt; |
428 | } else { | 428 | } else { |
429 | snd_printd(KERN_INFO "ctxfi: Use system timer\n"); | 429 | dev_info(atc->card->dev, "Use system timer\n"); |
430 | atimer->ops = &ct_systimer_ops; | 430 | atimer->ops = &ct_systimer_ops; |
431 | } | 431 | } |
432 | return atimer; | 432 | return atimer; |
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c index 20c7cbc89bb3..febee5bda877 100644 --- a/sound/pci/echoaudio/darla20_dsp.c +++ b/sound/pci/echoaudio/darla20_dsp.c | |||
@@ -33,12 +33,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
33 | { | 33 | { |
34 | int err; | 34 | int err; |
35 | 35 | ||
36 | DE_INIT(("init_hw() - Darla20\n")); | ||
37 | if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20)) | 36 | if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20)) |
38 | return -ENODEV; | 37 | return -ENODEV; |
39 | 38 | ||
40 | if ((err = init_dsp_comm_page(chip))) { | 39 | if ((err = init_dsp_comm_page(chip))) { |
41 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 40 | dev_err(chip->card->dev, |
41 | "init_hw: could not initialize DSP comm page\n"); | ||
42 | return err; | 42 | return err; |
43 | } | 43 | } |
44 | 44 | ||
@@ -57,7 +57,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
57 | return err; | 57 | return err; |
58 | chip->bad_board = FALSE; | 58 | chip->bad_board = FALSE; |
59 | 59 | ||
60 | DE_INIT(("init_hw done\n")); | ||
61 | return err; | 60 | return err; |
62 | } | 61 | } |
63 | 62 | ||
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c index 6da6663e9176..7b4f6fd51b09 100644 --- a/sound/pci/echoaudio/darla24_dsp.c +++ b/sound/pci/echoaudio/darla24_dsp.c | |||
@@ -33,12 +33,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
33 | { | 33 | { |
34 | int err; | 34 | int err; |
35 | 35 | ||
36 | DE_INIT(("init_hw() - Darla24\n")); | ||
37 | if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24)) | 36 | if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24)) |
38 | return -ENODEV; | 37 | return -ENODEV; |
39 | 38 | ||
40 | if ((err = init_dsp_comm_page(chip))) { | 39 | if ((err = init_dsp_comm_page(chip))) { |
41 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 40 | dev_err(chip->card->dev, |
41 | "init_hw: could not initialize DSP comm page\n"); | ||
42 | return err; | 42 | return err; |
43 | } | 43 | } |
44 | 44 | ||
@@ -56,7 +56,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
56 | return err; | 56 | return err; |
57 | chip->bad_board = FALSE; | 57 | chip->bad_board = FALSE; |
58 | 58 | ||
59 | DE_INIT(("init_hw done\n")); | ||
60 | return err; | 59 | return err; |
61 | } | 60 | } |
62 | 61 | ||
@@ -128,15 +127,17 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
128 | clock = GD24_8000; | 127 | clock = GD24_8000; |
129 | break; | 128 | break; |
130 | default: | 129 | default: |
131 | DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", | 130 | dev_err(chip->card->dev, |
132 | rate)); | 131 | "set_sample_rate: Error, invalid sample rate %d\n", |
132 | rate); | ||
133 | return -EINVAL; | 133 | return -EINVAL; |
134 | } | 134 | } |
135 | 135 | ||
136 | if (wait_handshake(chip)) | 136 | if (wait_handshake(chip)) |
137 | return -EIO; | 137 | return -EIO; |
138 | 138 | ||
139 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | 139 | dev_dbg(chip->card->dev, |
140 | "set_sample_rate: %d clock %d\n", rate, clock); | ||
140 | chip->sample_rate = rate; | 141 | chip->sample_rate = rate; |
141 | 142 | ||
142 | /* Override the sample rate if this card is set to Echo sync. */ | 143 | /* Override the sample rate if this card is set to Echo sync. */ |
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c index 3cdc2ee2d1dd..ae11ce11b1c2 100644 --- a/sound/pci/echoaudio/echo3g_dsp.c +++ b/sound/pci/echoaudio/echo3g_dsp.c | |||
@@ -46,12 +46,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
46 | int err; | 46 | int err; |
47 | 47 | ||
48 | local_irq_enable(); | 48 | local_irq_enable(); |
49 | DE_INIT(("init_hw() - Echo3G\n")); | ||
50 | if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G)) | 49 | if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G)) |
51 | return -ENODEV; | 50 | return -ENODEV; |
52 | 51 | ||
53 | if ((err = init_dsp_comm_page(chip))) { | 52 | if ((err = init_dsp_comm_page(chip))) { |
54 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 53 | dev_err(chip->card->dev, |
54 | "init_hw - could not initialize DSP comm page\n"); | ||
55 | return err; | 55 | return err; |
56 | } | 56 | } |
57 | 57 | ||
@@ -98,7 +98,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
98 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | 98 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | |
99 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | 99 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; |
100 | 100 | ||
101 | DE_INIT(("init_hw done\n")); | ||
102 | return err; | 101 | return err; |
103 | } | 102 | } |
104 | 103 | ||
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 631aaa4046ad..21228adaa70c 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -48,13 +48,16 @@ static int get_firmware(const struct firmware **fw_entry, | |||
48 | 48 | ||
49 | #ifdef CONFIG_PM_SLEEP | 49 | #ifdef CONFIG_PM_SLEEP |
50 | if (chip->fw_cache[fw_index]) { | 50 | if (chip->fw_cache[fw_index]) { |
51 | DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); | 51 | dev_dbg(chip->card->dev, |
52 | "firmware requested: %s is cached\n", | ||
53 | card_fw[fw_index].data); | ||
52 | *fw_entry = chip->fw_cache[fw_index]; | 54 | *fw_entry = chip->fw_cache[fw_index]; |
53 | return 0; | 55 | return 0; |
54 | } | 56 | } |
55 | #endif | 57 | #endif |
56 | 58 | ||
57 | DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); | 59 | dev_dbg(chip->card->dev, |
60 | "firmware requested: %s\n", card_fw[fw_index].data); | ||
58 | snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); | 61 | snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); |
59 | err = request_firmware(fw_entry, name, pci_device(chip)); | 62 | err = request_firmware(fw_entry, name, pci_device(chip)); |
60 | if (err < 0) | 63 | if (err < 0) |
@@ -69,13 +72,13 @@ static int get_firmware(const struct firmware **fw_entry, | |||
69 | 72 | ||
70 | 73 | ||
71 | 74 | ||
72 | static void free_firmware(const struct firmware *fw_entry) | 75 | static void free_firmware(const struct firmware *fw_entry, |
76 | struct echoaudio *chip) | ||
73 | { | 77 | { |
74 | #ifdef CONFIG_PM_SLEEP | 78 | #ifdef CONFIG_PM_SLEEP |
75 | DE_ACT(("firmware not released (kept in cache)\n")); | 79 | dev_dbg(chip->card->dev, "firmware not released (kept in cache)\n"); |
76 | #else | 80 | #else |
77 | release_firmware(fw_entry); | 81 | release_firmware(fw_entry); |
78 | DE_ACT(("firmware released\n")); | ||
79 | #endif | 82 | #endif |
80 | } | 83 | } |
81 | 84 | ||
@@ -89,10 +92,9 @@ static void free_firmware_cache(struct echoaudio *chip) | |||
89 | for (i = 0; i < 8 ; i++) | 92 | for (i = 0; i < 8 ; i++) |
90 | if (chip->fw_cache[i]) { | 93 | if (chip->fw_cache[i]) { |
91 | release_firmware(chip->fw_cache[i]); | 94 | release_firmware(chip->fw_cache[i]); |
92 | DE_ACT(("release_firmware(%d)\n", i)); | 95 | dev_dbg(chip->card->dev, "release_firmware(%d)\n", i); |
93 | } | 96 | } |
94 | 97 | ||
95 | DE_ACT(("firmware_cache released\n")); | ||
96 | #endif | 98 | #endif |
97 | } | 99 | } |
98 | 100 | ||
@@ -286,7 +288,7 @@ static int pcm_open(struct snd_pcm_substream *substream, | |||
286 | 288 | ||
287 | /* Set up hw capabilities and contraints */ | 289 | /* Set up hw capabilities and contraints */ |
288 | memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); | 290 | memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); |
289 | DE_HWP(("max_channels=%d\n", max_channels)); | 291 | dev_dbg(chip->card->dev, "max_channels=%d\n", max_channels); |
290 | pipe->constr.list = channels_list; | 292 | pipe->constr.list = channels_list; |
291 | pipe->constr.mask = 0; | 293 | pipe->constr.mask = 0; |
292 | for (i = 0; channels_list[i] <= max_channels; i++); | 294 | for (i = 0; channels_list[i] <= max_channels; i++); |
@@ -336,7 +338,7 @@ static int pcm_open(struct snd_pcm_substream *substream, | |||
336 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | 338 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, |
337 | snd_dma_pci_data(chip->pci), | 339 | snd_dma_pci_data(chip->pci), |
338 | PAGE_SIZE, &pipe->sgpage)) < 0) { | 340 | PAGE_SIZE, &pipe->sgpage)) < 0) { |
339 | DE_HWP(("s-g list allocation failed\n")); | 341 | dev_err(chip->card->dev, "s-g list allocation failed\n"); |
340 | return err; | 342 | return err; |
341 | } | 343 | } |
342 | 344 | ||
@@ -350,7 +352,6 @@ static int pcm_analog_in_open(struct snd_pcm_substream *substream) | |||
350 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | 352 | struct echoaudio *chip = snd_pcm_substream_chip(substream); |
351 | int err; | 353 | int err; |
352 | 354 | ||
353 | DE_ACT(("pcm_analog_in_open\n")); | ||
354 | if ((err = pcm_open(substream, num_analog_busses_in(chip) - | 355 | if ((err = pcm_open(substream, num_analog_busses_in(chip) - |
355 | substream->number)) < 0) | 356 | substream->number)) < 0) |
356 | return err; | 357 | return err; |
@@ -367,9 +368,9 @@ static int pcm_analog_in_open(struct snd_pcm_substream *substream) | |||
367 | atomic_inc(&chip->opencount); | 368 | atomic_inc(&chip->opencount); |
368 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | 369 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) |
369 | chip->can_set_rate=0; | 370 | chip->can_set_rate=0; |
370 | DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", | 371 | dev_dbg(chip->card->dev, "pcm_analog_in_open cs=%d oc=%d r=%d\n", |
371 | chip->can_set_rate, atomic_read(&chip->opencount), | 372 | chip->can_set_rate, atomic_read(&chip->opencount), |
372 | chip->sample_rate)); | 373 | chip->sample_rate); |
373 | return 0; | 374 | return 0; |
374 | } | 375 | } |
375 | 376 | ||
@@ -385,7 +386,6 @@ static int pcm_analog_out_open(struct snd_pcm_substream *substream) | |||
385 | #else | 386 | #else |
386 | max_channels = num_analog_busses_out(chip); | 387 | max_channels = num_analog_busses_out(chip); |
387 | #endif | 388 | #endif |
388 | DE_ACT(("pcm_analog_out_open\n")); | ||
389 | if ((err = pcm_open(substream, max_channels - substream->number)) < 0) | 389 | if ((err = pcm_open(substream, max_channels - substream->number)) < 0) |
390 | return err; | 390 | return err; |
391 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | 391 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, |
@@ -403,9 +403,9 @@ static int pcm_analog_out_open(struct snd_pcm_substream *substream) | |||
403 | atomic_inc(&chip->opencount); | 403 | atomic_inc(&chip->opencount); |
404 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | 404 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) |
405 | chip->can_set_rate=0; | 405 | chip->can_set_rate=0; |
406 | DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", | 406 | dev_dbg(chip->card->dev, "pcm_analog_out_open cs=%d oc=%d r=%d\n", |
407 | chip->can_set_rate, atomic_read(&chip->opencount), | 407 | chip->can_set_rate, atomic_read(&chip->opencount), |
408 | chip->sample_rate)); | 408 | chip->sample_rate); |
409 | return 0; | 409 | return 0; |
410 | } | 410 | } |
411 | 411 | ||
@@ -418,7 +418,6 @@ static int pcm_digital_in_open(struct snd_pcm_substream *substream) | |||
418 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | 418 | struct echoaudio *chip = snd_pcm_substream_chip(substream); |
419 | int err, max_channels; | 419 | int err, max_channels; |
420 | 420 | ||
421 | DE_ACT(("pcm_digital_in_open\n")); | ||
422 | max_channels = num_digital_busses_in(chip) - substream->number; | 421 | max_channels = num_digital_busses_in(chip) - substream->number; |
423 | mutex_lock(&chip->mode_mutex); | 422 | mutex_lock(&chip->mode_mutex); |
424 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | 423 | if (chip->digital_mode == DIGITAL_MODE_ADAT) |
@@ -460,7 +459,6 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream) | |||
460 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | 459 | struct echoaudio *chip = snd_pcm_substream_chip(substream); |
461 | int err, max_channels; | 460 | int err, max_channels; |
462 | 461 | ||
463 | DE_ACT(("pcm_digital_out_open\n")); | ||
464 | max_channels = num_digital_busses_out(chip) - substream->number; | 462 | max_channels = num_digital_busses_out(chip) - substream->number; |
465 | mutex_lock(&chip->mode_mutex); | 463 | mutex_lock(&chip->mode_mutex); |
466 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | 464 | if (chip->digital_mode == DIGITAL_MODE_ADAT) |
@@ -507,18 +505,17 @@ static int pcm_close(struct snd_pcm_substream *substream) | |||
507 | /* Nothing to do here. Audio is already off and pipe will be | 505 | /* Nothing to do here. Audio is already off and pipe will be |
508 | * freed by its callback | 506 | * freed by its callback |
509 | */ | 507 | */ |
510 | DE_ACT(("pcm_close\n")); | ||
511 | 508 | ||
512 | atomic_dec(&chip->opencount); | 509 | atomic_dec(&chip->opencount); |
513 | oc = atomic_read(&chip->opencount); | 510 | oc = atomic_read(&chip->opencount); |
514 | DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, | 511 | dev_dbg(chip->card->dev, "pcm_close oc=%d cs=%d rs=%d\n", oc, |
515 | chip->can_set_rate, chip->rate_set)); | 512 | chip->can_set_rate, chip->rate_set); |
516 | if (oc < 2) | 513 | if (oc < 2) |
517 | chip->can_set_rate = 1; | 514 | chip->can_set_rate = 1; |
518 | if (oc == 0) | 515 | if (oc == 0) |
519 | chip->rate_set = 0; | 516 | chip->rate_set = 0; |
520 | DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, | 517 | dev_dbg(chip->card->dev, "pcm_close2 oc=%d cs=%d rs=%d\n", oc, |
521 | chip->can_set_rate,chip->rate_set)); | 518 | chip->can_set_rate, chip->rate_set); |
522 | 519 | ||
523 | return 0; | 520 | return 0; |
524 | } | 521 | } |
@@ -542,7 +539,7 @@ static int init_engine(struct snd_pcm_substream *substream, | |||
542 | */ | 539 | */ |
543 | spin_lock_irq(&chip->lock); | 540 | spin_lock_irq(&chip->lock); |
544 | if (pipe->index >= 0) { | 541 | if (pipe->index >= 0) { |
545 | DE_HWP(("hwp_ie free(%d)\n", pipe->index)); | 542 | dev_dbg(chip->card->dev, "hwp_ie free(%d)\n", pipe->index); |
546 | err = free_pipes(chip, pipe); | 543 | err = free_pipes(chip, pipe); |
547 | snd_BUG_ON(err); | 544 | snd_BUG_ON(err); |
548 | chip->substream[pipe->index] = NULL; | 545 | chip->substream[pipe->index] = NULL; |
@@ -551,16 +548,17 @@ static int init_engine(struct snd_pcm_substream *substream, | |||
551 | err = allocate_pipes(chip, pipe, pipe_index, interleave); | 548 | err = allocate_pipes(chip, pipe, pipe_index, interleave); |
552 | if (err < 0) { | 549 | if (err < 0) { |
553 | spin_unlock_irq(&chip->lock); | 550 | spin_unlock_irq(&chip->lock); |
554 | DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", | 551 | dev_err(chip->card->dev, "allocate_pipes(%d) err=%d\n", |
555 | pipe_index, err)); | 552 | pipe_index, err); |
556 | return err; | 553 | return err; |
557 | } | 554 | } |
558 | spin_unlock_irq(&chip->lock); | 555 | spin_unlock_irq(&chip->lock); |
559 | DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); | 556 | dev_dbg(chip->card->dev, "allocate_pipes()=%d\n", pipe_index); |
560 | 557 | ||
561 | DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", | 558 | dev_dbg(chip->card->dev, |
559 | "pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", | ||
562 | params_buffer_bytes(hw_params), params_periods(hw_params), | 560 | params_buffer_bytes(hw_params), params_periods(hw_params), |
563 | params_period_bytes(hw_params))); | 561 | params_period_bytes(hw_params)); |
564 | err = snd_pcm_lib_malloc_pages(substream, | 562 | err = snd_pcm_lib_malloc_pages(substream, |
565 | params_buffer_bytes(hw_params)); | 563 | params_buffer_bytes(hw_params)); |
566 | if (err < 0) { | 564 | if (err < 0) { |
@@ -615,7 +613,6 @@ static int init_engine(struct snd_pcm_substream *substream, | |||
615 | spin_lock_irq(&chip->lock); | 613 | spin_lock_irq(&chip->lock); |
616 | set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); | 614 | set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); |
617 | spin_unlock_irq(&chip->lock); | 615 | spin_unlock_irq(&chip->lock); |
618 | DE_HWP(("pcm_hw_params ok\n")); | ||
619 | return 0; | 616 | return 0; |
620 | } | 617 | } |
621 | 618 | ||
@@ -679,14 +676,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream) | |||
679 | 676 | ||
680 | spin_lock_irq(&chip->lock); | 677 | spin_lock_irq(&chip->lock); |
681 | if (pipe->index >= 0) { | 678 | if (pipe->index >= 0) { |
682 | DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); | 679 | dev_dbg(chip->card->dev, "pcm_hw_free(%d)\n", pipe->index); |
683 | free_pipes(chip, pipe); | 680 | free_pipes(chip, pipe); |
684 | chip->substream[pipe->index] = NULL; | 681 | chip->substream[pipe->index] = NULL; |
685 | pipe->index = -1; | 682 | pipe->index = -1; |
686 | } | 683 | } |
687 | spin_unlock_irq(&chip->lock); | 684 | spin_unlock_irq(&chip->lock); |
688 | 685 | ||
689 | DE_HWP(("pcm_hw_freed\n")); | ||
690 | snd_pcm_lib_free_pages(substream); | 686 | snd_pcm_lib_free_pages(substream); |
691 | return 0; | 687 | return 0; |
692 | } | 688 | } |
@@ -700,8 +696,8 @@ static int pcm_prepare(struct snd_pcm_substream *substream) | |||
700 | struct audioformat format; | 696 | struct audioformat format; |
701 | int pipe_index = ((struct audiopipe *)runtime->private_data)->index; | 697 | int pipe_index = ((struct audiopipe *)runtime->private_data)->index; |
702 | 698 | ||
703 | DE_HWP(("Prepare rate=%d format=%d channels=%d\n", | 699 | dev_dbg(chip->card->dev, "Prepare rate=%d format=%d channels=%d\n", |
704 | runtime->rate, runtime->format, runtime->channels)); | 700 | runtime->rate, runtime->format, runtime->channels); |
705 | format.interleave = runtime->channels; | 701 | format.interleave = runtime->channels; |
706 | format.data_are_bigendian = 0; | 702 | format.data_are_bigendian = 0; |
707 | format.mono_to_stereo = 0; | 703 | format.mono_to_stereo = 0; |
@@ -721,8 +717,9 @@ static int pcm_prepare(struct snd_pcm_substream *substream) | |||
721 | format.bits_per_sample = 32; | 717 | format.bits_per_sample = 32; |
722 | break; | 718 | break; |
723 | default: | 719 | default: |
724 | DE_HWP(("Prepare error: unsupported format %d\n", | 720 | dev_err(chip->card->dev, |
725 | runtime->format)); | 721 | "Prepare error: unsupported format %d\n", |
722 | runtime->format); | ||
726 | return -EINVAL; | 723 | return -EINVAL; |
727 | } | 724 | } |
728 | 725 | ||
@@ -757,10 +754,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
757 | spin_lock(&chip->lock); | 754 | spin_lock(&chip->lock); |
758 | switch (cmd) { | 755 | switch (cmd) { |
759 | case SNDRV_PCM_TRIGGER_RESUME: | 756 | case SNDRV_PCM_TRIGGER_RESUME: |
760 | DE_ACT(("pcm_trigger resume\n")); | ||
761 | case SNDRV_PCM_TRIGGER_START: | 757 | case SNDRV_PCM_TRIGGER_START: |
762 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 758 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
763 | DE_ACT(("pcm_trigger start\n")); | ||
764 | for (i = 0; i < DSP_MAXPIPES; i++) { | 759 | for (i = 0; i < DSP_MAXPIPES; i++) { |
765 | if (channelmask & (1 << i)) { | 760 | if (channelmask & (1 << i)) { |
766 | pipe = chip->substream[i]->runtime->private_data; | 761 | pipe = chip->substream[i]->runtime->private_data; |
@@ -782,9 +777,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
782 | chip->pipe_cyclic_mask); | 777 | chip->pipe_cyclic_mask); |
783 | break; | 778 | break; |
784 | case SNDRV_PCM_TRIGGER_SUSPEND: | 779 | case SNDRV_PCM_TRIGGER_SUSPEND: |
785 | DE_ACT(("pcm_trigger suspend\n")); | ||
786 | case SNDRV_PCM_TRIGGER_STOP: | 780 | case SNDRV_PCM_TRIGGER_STOP: |
787 | DE_ACT(("pcm_trigger stop\n")); | ||
788 | for (i = 0; i < DSP_MAXPIPES; i++) { | 781 | for (i = 0; i < DSP_MAXPIPES; i++) { |
789 | if (channelmask & (1 << i)) { | 782 | if (channelmask & (1 << i)) { |
790 | pipe = chip->substream[i]->runtime->private_data; | 783 | pipe = chip->substream[i]->runtime->private_data; |
@@ -794,7 +787,6 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
794 | err = stop_transport(chip, channelmask); | 787 | err = stop_transport(chip, channelmask); |
795 | break; | 788 | break; |
796 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 789 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
797 | DE_ACT(("pcm_trigger pause\n")); | ||
798 | for (i = 0; i < DSP_MAXPIPES; i++) { | 790 | for (i = 0; i < DSP_MAXPIPES; i++) { |
799 | if (channelmask & (1 << i)) { | 791 | if (channelmask & (1 << i)) { |
800 | pipe = chip->substream[i]->runtime->private_data; | 792 | pipe = chip->substream[i]->runtime->private_data; |
@@ -931,7 +923,6 @@ static int snd_echo_new_pcm(struct echoaudio *chip) | |||
931 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); | 923 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); |
932 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | 924 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
933 | return err; | 925 | return err; |
934 | DE_INIT(("Analog PCM ok\n")); | ||
935 | 926 | ||
936 | #ifdef ECHOCARD_HAS_DIGITAL_IO | 927 | #ifdef ECHOCARD_HAS_DIGITAL_IO |
937 | /* PCM#1 Digital inputs, no outputs */ | 928 | /* PCM#1 Digital inputs, no outputs */ |
@@ -944,7 +935,6 @@ static int snd_echo_new_pcm(struct echoaudio *chip) | |||
944 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); | 935 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); |
945 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | 936 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
946 | return err; | 937 | return err; |
947 | DE_INIT(("Digital PCM ok\n")); | ||
948 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | 938 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ |
949 | 939 | ||
950 | #else /* ECHOCARD_HAS_VMIXER */ | 940 | #else /* ECHOCARD_HAS_VMIXER */ |
@@ -966,7 +956,6 @@ static int snd_echo_new_pcm(struct echoaudio *chip) | |||
966 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); | 956 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); |
967 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | 957 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
968 | return err; | 958 | return err; |
969 | DE_INIT(("Analog PCM ok\n")); | ||
970 | 959 | ||
971 | #ifdef ECHOCARD_HAS_DIGITAL_IO | 960 | #ifdef ECHOCARD_HAS_DIGITAL_IO |
972 | /* PCM#1 Digital i/o */ | 961 | /* PCM#1 Digital i/o */ |
@@ -981,7 +970,6 @@ static int snd_echo_new_pcm(struct echoaudio *chip) | |||
981 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); | 970 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); |
982 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | 971 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
983 | return err; | 972 | return err; |
984 | DE_INIT(("Digital PCM ok\n")); | ||
985 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | 973 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ |
986 | 974 | ||
987 | #endif /* ECHOCARD_HAS_VMIXER */ | 975 | #endif /* ECHOCARD_HAS_VMIXER */ |
@@ -1416,21 +1404,14 @@ static struct snd_kcontrol_new snd_echo_vmixer = { | |||
1416 | static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, | 1404 | static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, |
1417 | struct snd_ctl_elem_info *uinfo) | 1405 | struct snd_ctl_elem_info *uinfo) |
1418 | { | 1406 | { |
1419 | static char *names[4] = { | 1407 | static const char * const names[4] = { |
1420 | "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", | 1408 | "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", |
1421 | "S/PDIF Cdrom" | 1409 | "S/PDIF Cdrom" |
1422 | }; | 1410 | }; |
1423 | struct echoaudio *chip; | 1411 | struct echoaudio *chip; |
1424 | 1412 | ||
1425 | chip = snd_kcontrol_chip(kcontrol); | 1413 | chip = snd_kcontrol_chip(kcontrol); |
1426 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1414 | return snd_ctl_enum_info(uinfo, 1, chip->num_digital_modes, names); |
1427 | uinfo->value.enumerated.items = chip->num_digital_modes; | ||
1428 | uinfo->count = 1; | ||
1429 | if (uinfo->value.enumerated.item >= chip->num_digital_modes) | ||
1430 | uinfo->value.enumerated.item = chip->num_digital_modes - 1; | ||
1431 | strcpy(uinfo->value.enumerated.name, names[ | ||
1432 | chip->digital_mode_list[uinfo->value.enumerated.item]]); | ||
1433 | return 0; | ||
1434 | } | 1415 | } |
1435 | 1416 | ||
1436 | static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, | 1417 | static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, |
@@ -1481,7 +1462,8 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, | |||
1481 | snd_ctl_notify(chip->card, | 1462 | snd_ctl_notify(chip->card, |
1482 | SNDRV_CTL_EVENT_MASK_VALUE, | 1463 | SNDRV_CTL_EVENT_MASK_VALUE, |
1483 | &chip->clock_src_ctl->id); | 1464 | &chip->clock_src_ctl->id); |
1484 | DE_ACT(("SDM() =%d\n", changed)); | 1465 | dev_dbg(chip->card->dev, |
1466 | "SDM() =%d\n", changed); | ||
1485 | } | 1467 | } |
1486 | if (changed >= 0) | 1468 | if (changed >= 0) |
1487 | changed = 1; /* No errors */ | 1469 | changed = 1; /* No errors */ |
@@ -1509,16 +1491,9 @@ static struct snd_kcontrol_new snd_echo_digital_mode_switch = { | |||
1509 | static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, | 1491 | static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, |
1510 | struct snd_ctl_elem_info *uinfo) | 1492 | struct snd_ctl_elem_info *uinfo) |
1511 | { | 1493 | { |
1512 | static char *names[2] = {"Consumer", "Professional"}; | 1494 | static const char * const names[2] = {"Consumer", "Professional"}; |
1513 | 1495 | ||
1514 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1496 | return snd_ctl_enum_info(uinfo, 1, 2, names); |
1515 | uinfo->value.enumerated.items = 2; | ||
1516 | uinfo->count = 1; | ||
1517 | if (uinfo->value.enumerated.item) | ||
1518 | uinfo->value.enumerated.item = 1; | ||
1519 | strcpy(uinfo->value.enumerated.name, | ||
1520 | names[uinfo->value.enumerated.item]); | ||
1521 | return 0; | ||
1522 | } | 1497 | } |
1523 | 1498 | ||
1524 | static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, | 1499 | static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, |
@@ -1566,21 +1541,14 @@ static struct snd_kcontrol_new snd_echo_spdif_mode_switch = { | |||
1566 | static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, | 1541 | static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, |
1567 | struct snd_ctl_elem_info *uinfo) | 1542 | struct snd_ctl_elem_info *uinfo) |
1568 | { | 1543 | { |
1569 | static char *names[8] = { | 1544 | static const char * const names[8] = { |
1570 | "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", | 1545 | "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", |
1571 | "ESync96", "MTC" | 1546 | "ESync96", "MTC" |
1572 | }; | 1547 | }; |
1573 | struct echoaudio *chip; | 1548 | struct echoaudio *chip; |
1574 | 1549 | ||
1575 | chip = snd_kcontrol_chip(kcontrol); | 1550 | chip = snd_kcontrol_chip(kcontrol); |
1576 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1551 | return snd_ctl_enum_info(uinfo, 1, chip->num_clock_sources, names); |
1577 | uinfo->value.enumerated.items = chip->num_clock_sources; | ||
1578 | uinfo->count = 1; | ||
1579 | if (uinfo->value.enumerated.item >= chip->num_clock_sources) | ||
1580 | uinfo->value.enumerated.item = chip->num_clock_sources - 1; | ||
1581 | strcpy(uinfo->value.enumerated.name, names[ | ||
1582 | chip->clock_source_list[uinfo->value.enumerated.item]]); | ||
1583 | return 0; | ||
1584 | } | 1552 | } |
1585 | 1553 | ||
1586 | static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, | 1554 | static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, |
@@ -1622,7 +1590,8 @@ static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, | |||
1622 | } | 1590 | } |
1623 | 1591 | ||
1624 | if (changed < 0) | 1592 | if (changed < 0) |
1625 | DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); | 1593 | dev_dbg(chip->card->dev, |
1594 | "seticlk val%d err 0x%x\n", dclock, changed); | ||
1626 | 1595 | ||
1627 | return changed; | 1596 | return changed; |
1628 | } | 1597 | } |
@@ -1879,7 +1848,7 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) | |||
1879 | #ifdef ECHOCARD_HAS_MIDI | 1848 | #ifdef ECHOCARD_HAS_MIDI |
1880 | if (st > 0 && chip->midi_in) { | 1849 | if (st > 0 && chip->midi_in) { |
1881 | snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); | 1850 | snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); |
1882 | DE_MID(("rawmidi_iread=%d\n", st)); | 1851 | dev_dbg(chip->card->dev, "rawmidi_iread=%d\n", st); |
1883 | } | 1852 | } |
1884 | #endif | 1853 | #endif |
1885 | return IRQ_HANDLED; | 1854 | return IRQ_HANDLED; |
@@ -1894,10 +1863,8 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) | |||
1894 | 1863 | ||
1895 | static int snd_echo_free(struct echoaudio *chip) | 1864 | static int snd_echo_free(struct echoaudio *chip) |
1896 | { | 1865 | { |
1897 | DE_INIT(("Stop DSP...\n")); | ||
1898 | if (chip->comm_page) | 1866 | if (chip->comm_page) |
1899 | rest_in_peace(chip); | 1867 | rest_in_peace(chip); |
1900 | DE_INIT(("Stopped.\n")); | ||
1901 | 1868 | ||
1902 | if (chip->irq >= 0) | 1869 | if (chip->irq >= 0) |
1903 | free_irq(chip->irq, chip); | 1870 | free_irq(chip->irq, chip); |
@@ -1908,17 +1875,14 @@ static int snd_echo_free(struct echoaudio *chip) | |||
1908 | if (chip->dsp_registers) | 1875 | if (chip->dsp_registers) |
1909 | iounmap(chip->dsp_registers); | 1876 | iounmap(chip->dsp_registers); |
1910 | 1877 | ||
1911 | if (chip->iores) | 1878 | release_and_free_resource(chip->iores); |
1912 | release_and_free_resource(chip->iores); | ||
1913 | 1879 | ||
1914 | DE_INIT(("MMIO freed.\n")); | ||
1915 | 1880 | ||
1916 | pci_disable_device(chip->pci); | 1881 | pci_disable_device(chip->pci); |
1917 | 1882 | ||
1918 | /* release chip data */ | 1883 | /* release chip data */ |
1919 | free_firmware_cache(chip); | 1884 | free_firmware_cache(chip); |
1920 | kfree(chip); | 1885 | kfree(chip); |
1921 | DE_INIT(("Chip freed.\n")); | ||
1922 | return 0; | 1886 | return 0; |
1923 | } | 1887 | } |
1924 | 1888 | ||
@@ -1928,7 +1892,6 @@ static int snd_echo_dev_free(struct snd_device *device) | |||
1928 | { | 1892 | { |
1929 | struct echoaudio *chip = device->device_data; | 1893 | struct echoaudio *chip = device->device_data; |
1930 | 1894 | ||
1931 | DE_INIT(("snd_echo_dev_free()...\n")); | ||
1932 | return snd_echo_free(chip); | 1895 | return snd_echo_free(chip); |
1933 | } | 1896 | } |
1934 | 1897 | ||
@@ -1961,7 +1924,7 @@ static int snd_echo_create(struct snd_card *card, | |||
1961 | pci_disable_device(pci); | 1924 | pci_disable_device(pci); |
1962 | return -ENOMEM; | 1925 | return -ENOMEM; |
1963 | } | 1926 | } |
1964 | DE_INIT(("chip=%p\n", chip)); | 1927 | dev_dbg(card->dev, "chip=%p\n", chip); |
1965 | spin_lock_init(&chip->lock); | 1928 | spin_lock_init(&chip->lock); |
1966 | chip->card = card; | 1929 | chip->card = card; |
1967 | chip->pci = pci; | 1930 | chip->pci = pci; |
@@ -1998,8 +1961,8 @@ static int snd_echo_create(struct snd_card *card, | |||
1998 | return -EBUSY; | 1961 | return -EBUSY; |
1999 | } | 1962 | } |
2000 | chip->irq = pci->irq; | 1963 | chip->irq = pci->irq; |
2001 | DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", | 1964 | dev_dbg(card->dev, "pci=%p irq=%d subdev=%04x Init hardware...\n", |
2002 | chip->pci, chip->irq, chip->pci->subsystem_device)); | 1965 | chip->pci, chip->irq, chip->pci->subsystem_device); |
2003 | 1966 | ||
2004 | /* Create the DSP comm page - this is the area of memory used for most | 1967 | /* Create the DSP comm page - this is the area of memory used for most |
2005 | of the communication with the DSP, which accesses it via bus mastering */ | 1968 | of the communication with the DSP, which accesses it via bus mastering */ |
@@ -2017,11 +1980,10 @@ static int snd_echo_create(struct snd_card *card, | |||
2017 | if (err >= 0) | 1980 | if (err >= 0) |
2018 | err = set_mixer_defaults(chip); | 1981 | err = set_mixer_defaults(chip); |
2019 | if (err < 0) { | 1982 | if (err < 0) { |
2020 | DE_INIT(("init_hw err=%d\n", err)); | 1983 | dev_err(card->dev, "init_hw err=%d\n", err); |
2021 | snd_echo_free(chip); | 1984 | snd_echo_free(chip); |
2022 | return err; | 1985 | return err; |
2023 | } | 1986 | } |
2024 | DE_INIT(("Card init OK\n")); | ||
2025 | 1987 | ||
2026 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 1988 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
2027 | snd_echo_free(chip); | 1989 | snd_echo_free(chip); |
@@ -2051,7 +2013,6 @@ static int snd_echo_probe(struct pci_dev *pci, | |||
2051 | return -ENOENT; | 2013 | return -ENOENT; |
2052 | } | 2014 | } |
2053 | 2015 | ||
2054 | DE_INIT(("Echoaudio driver starting...\n")); | ||
2055 | i = 0; | 2016 | i = 0; |
2056 | err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, | 2017 | err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, |
2057 | 0, &card); | 2018 | 0, &card); |
@@ -2204,7 +2165,6 @@ static int snd_echo_suspend(struct device *dev) | |||
2204 | struct pci_dev *pci = to_pci_dev(dev); | 2165 | struct pci_dev *pci = to_pci_dev(dev); |
2205 | struct echoaudio *chip = dev_get_drvdata(dev); | 2166 | struct echoaudio *chip = dev_get_drvdata(dev); |
2206 | 2167 | ||
2207 | DE_INIT(("suspend start\n")); | ||
2208 | snd_pcm_suspend_all(chip->analog_pcm); | 2168 | snd_pcm_suspend_all(chip->analog_pcm); |
2209 | snd_pcm_suspend_all(chip->digital_pcm); | 2169 | snd_pcm_suspend_all(chip->digital_pcm); |
2210 | 2170 | ||
@@ -2231,7 +2191,6 @@ static int snd_echo_suspend(struct device *dev) | |||
2231 | pci_save_state(pci); | 2191 | pci_save_state(pci); |
2232 | pci_disable_device(pci); | 2192 | pci_disable_device(pci); |
2233 | 2193 | ||
2234 | DE_INIT(("suspend done\n")); | ||
2235 | return 0; | 2194 | return 0; |
2236 | } | 2195 | } |
2237 | 2196 | ||
@@ -2245,7 +2204,6 @@ static int snd_echo_resume(struct device *dev) | |||
2245 | u32 pipe_alloc_mask; | 2204 | u32 pipe_alloc_mask; |
2246 | int err; | 2205 | int err; |
2247 | 2206 | ||
2248 | DE_INIT(("resume start\n")); | ||
2249 | pci_restore_state(pci); | 2207 | pci_restore_state(pci); |
2250 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); | 2208 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); |
2251 | if (commpage_bak == NULL) | 2209 | if (commpage_bak == NULL) |
@@ -2256,11 +2214,10 @@ static int snd_echo_resume(struct device *dev) | |||
2256 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); | 2214 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); |
2257 | if (err < 0) { | 2215 | if (err < 0) { |
2258 | kfree(commpage_bak); | 2216 | kfree(commpage_bak); |
2259 | DE_INIT(("resume init_hw err=%d\n", err)); | 2217 | dev_err(dev, "resume init_hw err=%d\n", err); |
2260 | snd_echo_free(chip); | 2218 | snd_echo_free(chip); |
2261 | return err; | 2219 | return err; |
2262 | } | 2220 | } |
2263 | DE_INIT(("resume init OK\n")); | ||
2264 | 2221 | ||
2265 | /* Temporarily set chip->pipe_alloc_mask=0 otherwise | 2222 | /* Temporarily set chip->pipe_alloc_mask=0 otherwise |
2266 | * restore_dsp_settings() fails. | 2223 | * restore_dsp_settings() fails. |
@@ -2273,7 +2230,6 @@ static int snd_echo_resume(struct device *dev) | |||
2273 | kfree(commpage_bak); | 2230 | kfree(commpage_bak); |
2274 | return err; | 2231 | return err; |
2275 | } | 2232 | } |
2276 | DE_INIT(("resume restore OK\n")); | ||
2277 | 2233 | ||
2278 | memcpy(&commpage->audio_format, &commpage_bak->audio_format, | 2234 | memcpy(&commpage->audio_format, &commpage_bak->audio_format, |
2279 | sizeof(commpage->audio_format)); | 2235 | sizeof(commpage->audio_format)); |
@@ -2290,7 +2246,7 @@ static int snd_echo_resume(struct device *dev) | |||
2290 | return -EBUSY; | 2246 | return -EBUSY; |
2291 | } | 2247 | } |
2292 | chip->irq = pci->irq; | 2248 | chip->irq = pci->irq; |
2293 | DE_INIT(("resume irq=%d\n", chip->irq)); | 2249 | dev_dbg(dev, "resume irq=%d\n", chip->irq); |
2294 | 2250 | ||
2295 | #ifdef ECHOCARD_HAS_MIDI | 2251 | #ifdef ECHOCARD_HAS_MIDI |
2296 | if (chip->midi_input_enabled) | 2252 | if (chip->midi_input_enabled) |
@@ -2299,7 +2255,6 @@ static int snd_echo_resume(struct device *dev) | |||
2299 | snd_echo_midi_output_trigger(chip->midi_out, 1); | 2255 | snd_echo_midi_output_trigger(chip->midi_out, 1); |
2300 | #endif | 2256 | #endif |
2301 | 2257 | ||
2302 | DE_INIT(("resume done\n")); | ||
2303 | return 0; | 2258 | return 0; |
2304 | } | 2259 | } |
2305 | 2260 | ||
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index b86b88da81cd..32515227a692 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h | |||
@@ -295,34 +295,6 @@ | |||
295 | #define PIPE_STATE_PENDING 3 /* Pipe has pending start */ | 295 | #define PIPE_STATE_PENDING 3 /* Pipe has pending start */ |
296 | 296 | ||
297 | 297 | ||
298 | /* Debug initialization */ | ||
299 | #ifdef CONFIG_SND_DEBUG | ||
300 | #define DE_INIT(x) snd_printk x | ||
301 | #else | ||
302 | #define DE_INIT(x) | ||
303 | #endif | ||
304 | |||
305 | /* Debug hw_params callbacks */ | ||
306 | #ifdef CONFIG_SND_DEBUG | ||
307 | #define DE_HWP(x) snd_printk x | ||
308 | #else | ||
309 | #define DE_HWP(x) | ||
310 | #endif | ||
311 | |||
312 | /* Debug normal activity (open, start, stop...) */ | ||
313 | #ifdef CONFIG_SND_DEBUG | ||
314 | #define DE_ACT(x) snd_printk x | ||
315 | #else | ||
316 | #define DE_ACT(x) | ||
317 | #endif | ||
318 | |||
319 | /* Debug midi activity */ | ||
320 | #ifdef CONFIG_SND_DEBUG | ||
321 | #define DE_MID(x) snd_printk x | ||
322 | #else | ||
323 | #define DE_MID(x) | ||
324 | #endif | ||
325 | |||
326 | 298 | ||
327 | struct audiopipe { | 299 | struct audiopipe { |
328 | volatile u32 *dma_counter; /* Commpage register that contains | 300 | volatile u32 *dma_counter; /* Commpage register that contains |
@@ -468,7 +440,8 @@ static int wait_handshake(struct echoaudio *chip); | |||
468 | static int send_vector(struct echoaudio *chip, u32 command); | 440 | static int send_vector(struct echoaudio *chip, u32 command); |
469 | static int get_firmware(const struct firmware **fw_entry, | 441 | static int get_firmware(const struct firmware **fw_entry, |
470 | struct echoaudio *chip, const short fw_index); | 442 | struct echoaudio *chip, const short fw_index); |
471 | static void free_firmware(const struct firmware *fw_entry); | 443 | static void free_firmware(const struct firmware *fw_entry, |
444 | struct echoaudio *chip); | ||
472 | 445 | ||
473 | #ifdef ECHOCARD_HAS_MIDI | 446 | #ifdef ECHOCARD_HAS_MIDI |
474 | static int enable_midi_input(struct echoaudio *chip, char enable); | 447 | static int enable_midi_input(struct echoaudio *chip, char enable); |
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 658db44ef746..2fa66dc3e675 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c | |||
@@ -51,7 +51,7 @@ static int check_asic_status(struct echoaudio *chip) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | box_status = le32_to_cpu(chip->comm_page->ext_box_status); | 53 | box_status = le32_to_cpu(chip->comm_page->ext_box_status); |
54 | DE_INIT(("box_status=%x\n", box_status)); | 54 | dev_dbg(chip->card->dev, "box_status=%x\n", box_status); |
55 | if (box_status == E3G_ASIC_NOT_LOADED) | 55 | if (box_status == E3G_ASIC_NOT_LOADED) |
56 | return -ENODEV; | 56 | return -ENODEV; |
57 | 57 | ||
@@ -76,7 +76,8 @@ static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | |||
76 | if (wait_handshake(chip)) | 76 | if (wait_handshake(chip)) |
77 | return -EIO; | 77 | return -EIO; |
78 | 78 | ||
79 | DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); | 79 | dev_dbg(chip->card->dev, |
80 | "WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq); | ||
80 | 81 | ||
81 | ctl = cpu_to_le32(ctl); | 82 | ctl = cpu_to_le32(ctl); |
82 | frq = cpu_to_le32(frq); | 83 | frq = cpu_to_le32(frq); |
@@ -89,7 +90,7 @@ static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | |||
89 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); | 90 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); |
90 | } | 91 | } |
91 | 92 | ||
92 | DE_ACT(("WriteControlReg: not written, no change\n")); | 93 | dev_dbg(chip->card->dev, "WriteControlReg: not written, no change\n"); |
93 | return 0; | 94 | return 0; |
94 | } | 95 | } |
95 | 96 | ||
@@ -258,8 +259,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
258 | 259 | ||
259 | /* Only set the clock for internal mode. */ | 260 | /* Only set the clock for internal mode. */ |
260 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | 261 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { |
261 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | 262 | dev_warn(chip->card->dev, |
262 | "clock not set to CLK_CLOCKININTERNAL\n")); | 263 | "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); |
263 | /* Save the rate anyhow */ | 264 | /* Save the rate anyhow */ |
264 | chip->comm_page->sample_rate = cpu_to_le32(rate); | 265 | chip->comm_page->sample_rate = cpu_to_le32(rate); |
265 | chip->sample_rate = rate; | 266 | chip->sample_rate = rate; |
@@ -313,7 +314,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
313 | 314 | ||
314 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | 315 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ |
315 | chip->sample_rate = rate; | 316 | chip->sample_rate = rate; |
316 | DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); | 317 | dev_dbg(chip->card->dev, |
318 | "SetSampleRate: %d clock %x\n", rate, control_reg); | ||
317 | 319 | ||
318 | /* Tell the DSP about it - DSP reads both control reg & freq reg */ | 320 | /* Tell the DSP about it - DSP reads both control reg & freq reg */ |
319 | return write_control_reg(chip, control_reg, frq_reg, 0); | 321 | return write_control_reg(chip, control_reg, frq_reg, 0); |
@@ -326,7 +328,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
326 | { | 328 | { |
327 | u32 control_reg, clocks_from_dsp; | 329 | u32 control_reg, clocks_from_dsp; |
328 | 330 | ||
329 | DE_ACT(("set_input_clock:\n")); | ||
330 | 331 | ||
331 | /* Mask off the clock select bits */ | 332 | /* Mask off the clock select bits */ |
332 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | 333 | control_reg = le32_to_cpu(chip->comm_page->control_register) & |
@@ -335,13 +336,11 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
335 | 336 | ||
336 | switch (clock) { | 337 | switch (clock) { |
337 | case ECHO_CLOCK_INTERNAL: | 338 | case ECHO_CLOCK_INTERNAL: |
338 | DE_ACT(("Set Echo3G clock to INTERNAL\n")); | ||
339 | chip->input_clock = ECHO_CLOCK_INTERNAL; | 339 | chip->input_clock = ECHO_CLOCK_INTERNAL; |
340 | return set_sample_rate(chip, chip->sample_rate); | 340 | return set_sample_rate(chip, chip->sample_rate); |
341 | case ECHO_CLOCK_SPDIF: | 341 | case ECHO_CLOCK_SPDIF: |
342 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | 342 | if (chip->digital_mode == DIGITAL_MODE_ADAT) |
343 | return -EAGAIN; | 343 | return -EAGAIN; |
344 | DE_ACT(("Set Echo3G clock to SPDIF\n")); | ||
345 | control_reg |= E3G_SPDIF_CLOCK; | 344 | control_reg |= E3G_SPDIF_CLOCK; |
346 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) | 345 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) |
347 | control_reg |= E3G_DOUBLE_SPEED_MODE; | 346 | control_reg |= E3G_DOUBLE_SPEED_MODE; |
@@ -351,12 +350,10 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
351 | case ECHO_CLOCK_ADAT: | 350 | case ECHO_CLOCK_ADAT: |
352 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | 351 | if (chip->digital_mode != DIGITAL_MODE_ADAT) |
353 | return -EAGAIN; | 352 | return -EAGAIN; |
354 | DE_ACT(("Set Echo3G clock to ADAT\n")); | ||
355 | control_reg |= E3G_ADAT_CLOCK; | 353 | control_reg |= E3G_ADAT_CLOCK; |
356 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | 354 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; |
357 | break; | 355 | break; |
358 | case ECHO_CLOCK_WORD: | 356 | case ECHO_CLOCK_WORD: |
359 | DE_ACT(("Set Echo3G clock to WORD\n")); | ||
360 | control_reg |= E3G_WORD_CLOCK; | 357 | control_reg |= E3G_WORD_CLOCK; |
361 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) | 358 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) |
362 | control_reg |= E3G_DOUBLE_SPEED_MODE; | 359 | control_reg |= E3G_DOUBLE_SPEED_MODE; |
@@ -364,7 +361,8 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
364 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | 361 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; |
365 | break; | 362 | break; |
366 | default: | 363 | default: |
367 | DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); | 364 | dev_err(chip->card->dev, |
365 | "Input clock 0x%x not supported for Echo3G\n", clock); | ||
368 | return -EINVAL; | 366 | return -EINVAL; |
369 | } | 367 | } |
370 | 368 | ||
@@ -392,7 +390,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
392 | incompatible_clock = TRUE; | 390 | incompatible_clock = TRUE; |
393 | break; | 391 | break; |
394 | default: | 392 | default: |
395 | DE_ACT(("Digital mode not supported: %d\n", mode)); | 393 | dev_err(chip->card->dev, |
394 | "Digital mode not supported: %d\n", mode); | ||
396 | return -EINVAL; | 395 | return -EINVAL; |
397 | } | 396 | } |
398 | 397 | ||
@@ -427,6 +426,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
427 | return err; | 426 | return err; |
428 | chip->digital_mode = mode; | 427 | chip->digital_mode = mode; |
429 | 428 | ||
430 | DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); | 429 | dev_dbg(chip->card->dev, "set_digital_mode(%d)\n", chip->digital_mode); |
431 | return incompatible_clock; | 430 | return incompatible_clock; |
432 | } | 431 | } |
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 5a6a217b82e0..1a9427aabe1d 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c | |||
@@ -80,7 +80,7 @@ static int send_vector(struct echoaudio *chip, u32 command) | |||
80 | udelay(1); | 80 | udelay(1); |
81 | } | 81 | } |
82 | 82 | ||
83 | DE_ACT((KERN_ERR "timeout on send_vector\n")); | 83 | dev_err(chip->card->dev, "timeout on send_vector\n"); |
84 | return -EBUSY; | 84 | return -EBUSY; |
85 | } | 85 | } |
86 | 86 | ||
@@ -104,7 +104,7 @@ static int write_dsp(struct echoaudio *chip, u32 data) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ | 106 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ |
107 | DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n")); | 107 | dev_dbg(chip->card->dev, "write_dsp: Set bad_board to TRUE\n"); |
108 | return -EIO; | 108 | return -EIO; |
109 | } | 109 | } |
110 | 110 | ||
@@ -127,7 +127,7 @@ static int read_dsp(struct echoaudio *chip, u32 *data) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ | 129 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ |
130 | DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n")); | 130 | dev_err(chip->card->dev, "read_dsp: Set bad_board to TRUE\n"); |
131 | return -EIO; | 131 | return -EIO; |
132 | } | 132 | } |
133 | 133 | ||
@@ -154,8 +154,9 @@ static int read_sn(struct echoaudio *chip) | |||
154 | return -EIO; | 154 | return -EIO; |
155 | } | 155 | } |
156 | } | 156 | } |
157 | DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n", | 157 | dev_dbg(chip->card->dev, |
158 | sn[0], sn[1], sn[2], sn[3], sn[4])); | 158 | "Read serial number %08x %08x %08x %08x %08x\n", |
159 | sn[0], sn[1], sn[2], sn[3], sn[4]); | ||
159 | return 0; | 160 | return 0; |
160 | } | 161 | } |
161 | 162 | ||
@@ -205,13 +206,12 @@ static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic) | |||
205 | goto la_error; | 206 | goto la_error; |
206 | } | 207 | } |
207 | 208 | ||
208 | DE_INIT(("ASIC loaded\n")); | 209 | free_firmware(fw, chip); |
209 | free_firmware(fw); | ||
210 | return 0; | 210 | return 0; |
211 | 211 | ||
212 | la_error: | 212 | la_error: |
213 | DE_INIT(("failed on write_dsp\n")); | 213 | dev_err(chip->card->dev, "failed on write_dsp\n"); |
214 | free_firmware(fw); | 214 | free_firmware(fw, chip); |
215 | return -EIO; | 215 | return -EIO; |
216 | } | 216 | } |
217 | 217 | ||
@@ -241,8 +241,9 @@ static int install_resident_loader(struct echoaudio *chip) | |||
241 | loader is already installed, host flag 5 will be on. */ | 241 | loader is already installed, host flag 5 will be on. */ |
242 | status = get_dsp_register(chip, CHI32_STATUS_REG); | 242 | status = get_dsp_register(chip, CHI32_STATUS_REG); |
243 | if (status & CHI32_STATUS_REG_HF5) { | 243 | if (status & CHI32_STATUS_REG_HF5) { |
244 | DE_INIT(("Resident loader already installed; status is 0x%x\n", | 244 | dev_dbg(chip->card->dev, |
245 | status)); | 245 | "Resident loader already installed; status is 0x%x\n", |
246 | status); | ||
246 | return 0; | 247 | return 0; |
247 | } | 248 | } |
248 | 249 | ||
@@ -283,12 +284,14 @@ static int install_resident_loader(struct echoaudio *chip) | |||
283 | 284 | ||
284 | /* Write the count to the DSP */ | 285 | /* Write the count to the DSP */ |
285 | if (write_dsp(chip, words)) { | 286 | if (write_dsp(chip, words)) { |
286 | DE_INIT(("install_resident_loader: Failed to write word count!\n")); | 287 | dev_err(chip->card->dev, |
288 | "install_resident_loader: Failed to write word count!\n"); | ||
287 | goto irl_error; | 289 | goto irl_error; |
288 | } | 290 | } |
289 | /* Write the DSP address */ | 291 | /* Write the DSP address */ |
290 | if (write_dsp(chip, address)) { | 292 | if (write_dsp(chip, address)) { |
291 | DE_INIT(("install_resident_loader: Failed to write DSP address!\n")); | 293 | dev_err(chip->card->dev, |
294 | "install_resident_loader: Failed to write DSP address!\n"); | ||
292 | goto irl_error; | 295 | goto irl_error; |
293 | } | 296 | } |
294 | /* Write out this block of code to the DSP */ | 297 | /* Write out this block of code to the DSP */ |
@@ -297,7 +300,8 @@ static int install_resident_loader(struct echoaudio *chip) | |||
297 | 300 | ||
298 | data = ((u32)code[index] << 16) + code[index + 1]; | 301 | data = ((u32)code[index] << 16) + code[index + 1]; |
299 | if (write_dsp(chip, data)) { | 302 | if (write_dsp(chip, data)) { |
300 | DE_INIT(("install_resident_loader: Failed to write DSP code\n")); | 303 | dev_err(chip->card->dev, |
304 | "install_resident_loader: Failed to write DSP code\n"); | ||
301 | goto irl_error; | 305 | goto irl_error; |
302 | } | 306 | } |
303 | index += 2; | 307 | index += 2; |
@@ -312,16 +316,16 @@ static int install_resident_loader(struct echoaudio *chip) | |||
312 | } | 316 | } |
313 | 317 | ||
314 | if (i == 200) { | 318 | if (i == 200) { |
315 | DE_INIT(("Resident loader failed to set HF5\n")); | 319 | dev_err(chip->card->dev, "Resident loader failed to set HF5\n"); |
316 | goto irl_error; | 320 | goto irl_error; |
317 | } | 321 | } |
318 | 322 | ||
319 | DE_INIT(("Resident loader successfully installed\n")); | 323 | dev_dbg(chip->card->dev, "Resident loader successfully installed\n"); |
320 | free_firmware(fw); | 324 | free_firmware(fw, chip); |
321 | return 0; | 325 | return 0; |
322 | 326 | ||
323 | irl_error: | 327 | irl_error: |
324 | free_firmware(fw); | 328 | free_firmware(fw, chip); |
325 | return -EIO; | 329 | return -EIO; |
326 | } | 330 | } |
327 | 331 | ||
@@ -334,14 +338,14 @@ static int load_dsp(struct echoaudio *chip, u16 *code) | |||
334 | int index, words, i; | 338 | int index, words, i; |
335 | 339 | ||
336 | if (chip->dsp_code == code) { | 340 | if (chip->dsp_code == code) { |
337 | DE_INIT(("DSP is already loaded!\n")); | 341 | dev_warn(chip->card->dev, "DSP is already loaded!\n"); |
338 | return 0; | 342 | return 0; |
339 | } | 343 | } |
340 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ | 344 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ |
341 | chip->dsp_code = NULL; /* Current DSP code not loaded */ | 345 | chip->dsp_code = NULL; /* Current DSP code not loaded */ |
342 | chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ | 346 | chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ |
343 | 347 | ||
344 | DE_INIT(("load_dsp: Set bad_board to TRUE\n")); | 348 | dev_dbg(chip->card->dev, "load_dsp: Set bad_board to TRUE\n"); |
345 | 349 | ||
346 | /* If this board requires a resident loader, install it. */ | 350 | /* If this board requires a resident loader, install it. */ |
347 | #ifdef DSP_56361 | 351 | #ifdef DSP_56361 |
@@ -351,7 +355,8 @@ static int load_dsp(struct echoaudio *chip, u16 *code) | |||
351 | 355 | ||
352 | /* Send software reset command */ | 356 | /* Send software reset command */ |
353 | if (send_vector(chip, DSP_VC_RESET) < 0) { | 357 | if (send_vector(chip, DSP_VC_RESET) < 0) { |
354 | DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n")); | 358 | dev_err(chip->card->dev, |
359 | "LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n"); | ||
355 | return -EIO; | 360 | return -EIO; |
356 | } | 361 | } |
357 | /* Delay 10us */ | 362 | /* Delay 10us */ |
@@ -366,7 +371,8 @@ static int load_dsp(struct echoaudio *chip, u16 *code) | |||
366 | } | 371 | } |
367 | 372 | ||
368 | if (i == 1000) { | 373 | if (i == 1000) { |
369 | DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n")); | 374 | dev_err(chip->card->dev, |
375 | "load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n"); | ||
370 | return -EIO; | 376 | return -EIO; |
371 | } | 377 | } |
372 | 378 | ||
@@ -403,29 +409,34 @@ static int load_dsp(struct echoaudio *chip, u16 *code) | |||
403 | index += 2; | 409 | index += 2; |
404 | 410 | ||
405 | if (write_dsp(chip, words) < 0) { | 411 | if (write_dsp(chip, words) < 0) { |
406 | DE_INIT(("load_dsp: failed to write number of DSP words\n")); | 412 | dev_err(chip->card->dev, |
413 | "load_dsp: failed to write number of DSP words\n"); | ||
407 | return -EIO; | 414 | return -EIO; |
408 | } | 415 | } |
409 | if (write_dsp(chip, address) < 0) { | 416 | if (write_dsp(chip, address) < 0) { |
410 | DE_INIT(("load_dsp: failed to write DSP address\n")); | 417 | dev_err(chip->card->dev, |
418 | "load_dsp: failed to write DSP address\n"); | ||
411 | return -EIO; | 419 | return -EIO; |
412 | } | 420 | } |
413 | if (write_dsp(chip, mem_type) < 0) { | 421 | if (write_dsp(chip, mem_type) < 0) { |
414 | DE_INIT(("load_dsp: failed to write DSP memory type\n")); | 422 | dev_err(chip->card->dev, |
423 | "load_dsp: failed to write DSP memory type\n"); | ||
415 | return -EIO; | 424 | return -EIO; |
416 | } | 425 | } |
417 | /* Code */ | 426 | /* Code */ |
418 | for (i = 0; i < words; i++, index+=2) { | 427 | for (i = 0; i < words; i++, index+=2) { |
419 | data = ((u32)code[index] << 16) + code[index + 1]; | 428 | data = ((u32)code[index] << 16) + code[index + 1]; |
420 | if (write_dsp(chip, data) < 0) { | 429 | if (write_dsp(chip, data) < 0) { |
421 | DE_INIT(("load_dsp: failed to write DSP data\n")); | 430 | dev_err(chip->card->dev, |
431 | "load_dsp: failed to write DSP data\n"); | ||
422 | return -EIO; | 432 | return -EIO; |
423 | } | 433 | } |
424 | } | 434 | } |
425 | } | 435 | } |
426 | 436 | ||
427 | if (write_dsp(chip, 0) < 0) { /* We're done!!! */ | 437 | if (write_dsp(chip, 0) < 0) { /* We're done!!! */ |
428 | DE_INIT(("load_dsp: Failed to write final zero\n")); | 438 | dev_err(chip->card->dev, |
439 | "load_dsp: Failed to write final zero\n"); | ||
429 | return -EIO; | 440 | return -EIO; |
430 | } | 441 | } |
431 | udelay(10); | 442 | udelay(10); |
@@ -438,12 +449,14 @@ static int load_dsp(struct echoaudio *chip, u16 *code) | |||
438 | get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); | 449 | get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); |
439 | 450 | ||
440 | if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { | 451 | if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { |
441 | DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n")); | 452 | dev_err(chip->card->dev, |
453 | "load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n"); | ||
442 | return -EIO; | 454 | return -EIO; |
443 | } | 455 | } |
444 | 456 | ||
445 | if (write_dsp(chip, chip->comm_page_phys) < 0) { | 457 | if (write_dsp(chip, chip->comm_page_phys) < 0) { |
446 | DE_INIT(("load_dsp: Failed to write comm page address\n")); | 458 | dev_err(chip->card->dev, |
459 | "load_dsp: Failed to write comm page address\n"); | ||
447 | return -EIO; | 460 | return -EIO; |
448 | } | 461 | } |
449 | 462 | ||
@@ -452,19 +465,20 @@ static int load_dsp(struct echoaudio *chip, u16 *code) | |||
452 | We don't actually use the serial number but we have to | 465 | We don't actually use the serial number but we have to |
453 | get it as part of the DSP init voodoo. */ | 466 | get it as part of the DSP init voodoo. */ |
454 | if (read_sn(chip) < 0) { | 467 | if (read_sn(chip) < 0) { |
455 | DE_INIT(("load_dsp: Failed to read serial number\n")); | 468 | dev_err(chip->card->dev, |
469 | "load_dsp: Failed to read serial number\n"); | ||
456 | return -EIO; | 470 | return -EIO; |
457 | } | 471 | } |
458 | 472 | ||
459 | chip->dsp_code = code; /* Show which DSP code loaded */ | 473 | chip->dsp_code = code; /* Show which DSP code loaded */ |
460 | chip->bad_board = FALSE; /* DSP OK */ | 474 | chip->bad_board = FALSE; /* DSP OK */ |
461 | DE_INIT(("load_dsp: OK!\n")); | ||
462 | return 0; | 475 | return 0; |
463 | } | 476 | } |
464 | udelay(100); | 477 | udelay(100); |
465 | } | 478 | } |
466 | 479 | ||
467 | DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n")); | 480 | dev_err(chip->card->dev, |
481 | "load_dsp: DSP load timed out waiting for HF4\n"); | ||
468 | return -EIO; | 482 | return -EIO; |
469 | } | 483 | } |
470 | 484 | ||
@@ -491,7 +505,7 @@ static int load_firmware(struct echoaudio *chip) | |||
491 | if (err < 0) | 505 | if (err < 0) |
492 | return err; | 506 | return err; |
493 | err = load_dsp(chip, (u16 *)fw->data); | 507 | err = load_dsp(chip, (u16 *)fw->data); |
494 | free_firmware(fw); | 508 | free_firmware(fw, chip); |
495 | if (err < 0) | 509 | if (err < 0) |
496 | return err; | 510 | return err; |
497 | 511 | ||
@@ -658,7 +672,6 @@ static void get_audio_meters(struct echoaudio *chip, long *meters) | |||
658 | static int restore_dsp_rettings(struct echoaudio *chip) | 672 | static int restore_dsp_rettings(struct echoaudio *chip) |
659 | { | 673 | { |
660 | int i, o, err; | 674 | int i, o, err; |
661 | DE_INIT(("restore_dsp_settings\n")); | ||
662 | 675 | ||
663 | if ((err = check_asic_status(chip)) < 0) | 676 | if ((err = check_asic_status(chip)) < 0) |
664 | return err; | 677 | return err; |
@@ -755,7 +768,6 @@ static int restore_dsp_rettings(struct echoaudio *chip) | |||
755 | if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0) | 768 | if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0) |
756 | return -EIO; | 769 | return -EIO; |
757 | 770 | ||
758 | DE_INIT(("restore_dsp_rettings done\n")); | ||
759 | return 0; | 771 | return 0; |
760 | } | 772 | } |
761 | 773 | ||
@@ -835,7 +847,8 @@ static void set_audio_format(struct echoaudio *chip, u16 pipe_index, | |||
835 | break; | 847 | break; |
836 | } | 848 | } |
837 | } | 849 | } |
838 | DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format)); | 850 | dev_dbg(chip->card->dev, |
851 | "set_audio_format[%d] = %x\n", pipe_index, dsp_format); | ||
839 | chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); | 852 | chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); |
840 | } | 853 | } |
841 | 854 | ||
@@ -848,7 +861,6 @@ Same thing for pause_ and stop_ -trasport below. */ | |||
848 | static int start_transport(struct echoaudio *chip, u32 channel_mask, | 861 | static int start_transport(struct echoaudio *chip, u32 channel_mask, |
849 | u32 cyclic_mask) | 862 | u32 cyclic_mask) |
850 | { | 863 | { |
851 | DE_ACT(("start_transport %x\n", channel_mask)); | ||
852 | 864 | ||
853 | if (wait_handshake(chip)) | 865 | if (wait_handshake(chip)) |
854 | return -EIO; | 866 | return -EIO; |
@@ -866,7 +878,7 @@ static int start_transport(struct echoaudio *chip, u32 channel_mask, | |||
866 | return 0; | 878 | return 0; |
867 | } | 879 | } |
868 | 880 | ||
869 | DE_ACT(("start_transport: No pipes to start!\n")); | 881 | dev_err(chip->card->dev, "start_transport: No pipes to start!\n"); |
870 | return -EINVAL; | 882 | return -EINVAL; |
871 | } | 883 | } |
872 | 884 | ||
@@ -874,7 +886,6 @@ static int start_transport(struct echoaudio *chip, u32 channel_mask, | |||
874 | 886 | ||
875 | static int pause_transport(struct echoaudio *chip, u32 channel_mask) | 887 | static int pause_transport(struct echoaudio *chip, u32 channel_mask) |
876 | { | 888 | { |
877 | DE_ACT(("pause_transport %x\n", channel_mask)); | ||
878 | 889 | ||
879 | if (wait_handshake(chip)) | 890 | if (wait_handshake(chip)) |
880 | return -EIO; | 891 | return -EIO; |
@@ -893,7 +904,7 @@ static int pause_transport(struct echoaudio *chip, u32 channel_mask) | |||
893 | return 0; | 904 | return 0; |
894 | } | 905 | } |
895 | 906 | ||
896 | DE_ACT(("pause_transport: No pipes to stop!\n")); | 907 | dev_warn(chip->card->dev, "pause_transport: No pipes to stop!\n"); |
897 | return 0; | 908 | return 0; |
898 | } | 909 | } |
899 | 910 | ||
@@ -901,7 +912,6 @@ static int pause_transport(struct echoaudio *chip, u32 channel_mask) | |||
901 | 912 | ||
902 | static int stop_transport(struct echoaudio *chip, u32 channel_mask) | 913 | static int stop_transport(struct echoaudio *chip, u32 channel_mask) |
903 | { | 914 | { |
904 | DE_ACT(("stop_transport %x\n", channel_mask)); | ||
905 | 915 | ||
906 | if (wait_handshake(chip)) | 916 | if (wait_handshake(chip)) |
907 | return -EIO; | 917 | return -EIO; |
@@ -920,7 +930,7 @@ static int stop_transport(struct echoaudio *chip, u32 channel_mask) | |||
920 | return 0; | 930 | return 0; |
921 | } | 931 | } |
922 | 932 | ||
923 | DE_ACT(("stop_transport: No pipes to stop!\n")); | 933 | dev_warn(chip->card->dev, "stop_transport: No pipes to stop!\n"); |
924 | return 0; | 934 | return 0; |
925 | } | 935 | } |
926 | 936 | ||
@@ -937,7 +947,6 @@ static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index) | |||
937 | stopped and unallocated. */ | 947 | stopped and unallocated. */ |
938 | static int rest_in_peace(struct echoaudio *chip) | 948 | static int rest_in_peace(struct echoaudio *chip) |
939 | { | 949 | { |
940 | DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask)); | ||
941 | 950 | ||
942 | /* Stops all active pipes (just to be sure) */ | 951 | /* Stops all active pipes (just to be sure) */ |
943 | stop_transport(chip, chip->active_mask); | 952 | stop_transport(chip, chip->active_mask); |
@@ -965,7 +974,8 @@ static int init_dsp_comm_page(struct echoaudio *chip) | |||
965 | { | 974 | { |
966 | /* Check if the compiler added extra padding inside the structure */ | 975 | /* Check if the compiler added extra padding inside the structure */ |
967 | if (offsetof(struct comm_page, midi_output) != 0xbe0) { | 976 | if (offsetof(struct comm_page, midi_output) != 0xbe0) { |
968 | DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n")); | 977 | dev_err(chip->card->dev, |
978 | "init_dsp_comm_page() - Invalid struct comm_page structure\n"); | ||
969 | return -EPERM; | 979 | return -EPERM; |
970 | } | 980 | } |
971 | 981 | ||
@@ -999,7 +1009,6 @@ static int init_dsp_comm_page(struct echoaudio *chip) | |||
999 | */ | 1009 | */ |
1000 | static int init_line_levels(struct echoaudio *chip) | 1010 | static int init_line_levels(struct echoaudio *chip) |
1001 | { | 1011 | { |
1002 | DE_INIT(("init_line_levels\n")); | ||
1003 | memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain)); | 1012 | memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain)); |
1004 | memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain)); | 1013 | memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain)); |
1005 | memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain)); | 1014 | memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain)); |
@@ -1051,7 +1060,8 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, | |||
1051 | u32 channel_mask; | 1060 | u32 channel_mask; |
1052 | char is_cyclic; | 1061 | char is_cyclic; |
1053 | 1062 | ||
1054 | DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave)); | 1063 | dev_dbg(chip->card->dev, |
1064 | "allocate_pipes: ch=%d int=%d\n", pipe_index, interleave); | ||
1055 | 1065 | ||
1056 | if (chip->bad_board) | 1066 | if (chip->bad_board) |
1057 | return -EIO; | 1067 | return -EIO; |
@@ -1061,7 +1071,8 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, | |||
1061 | for (channel_mask = i = 0; i < interleave; i++) | 1071 | for (channel_mask = i = 0; i < interleave; i++) |
1062 | channel_mask |= 1 << (pipe_index + i); | 1072 | channel_mask |= 1 << (pipe_index + i); |
1063 | if (chip->pipe_alloc_mask & channel_mask) { | 1073 | if (chip->pipe_alloc_mask & channel_mask) { |
1064 | DE_ACT(("allocate_pipes: channel already open\n")); | 1074 | dev_err(chip->card->dev, |
1075 | "allocate_pipes: channel already open\n"); | ||
1065 | return -EAGAIN; | 1076 | return -EAGAIN; |
1066 | } | 1077 | } |
1067 | 1078 | ||
@@ -1078,7 +1089,6 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, | |||
1078 | it moves data. The DMA counter is in units of bytes, not samples. */ | 1089 | it moves data. The DMA counter is in units of bytes, not samples. */ |
1079 | pipe->dma_counter = &chip->comm_page->position[pipe_index]; | 1090 | pipe->dma_counter = &chip->comm_page->position[pipe_index]; |
1080 | *pipe->dma_counter = 0; | 1091 | *pipe->dma_counter = 0; |
1081 | DE_ACT(("allocate_pipes: ok\n")); | ||
1082 | return pipe_index; | 1092 | return pipe_index; |
1083 | } | 1093 | } |
1084 | 1094 | ||
@@ -1089,7 +1099,6 @@ static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) | |||
1089 | u32 channel_mask; | 1099 | u32 channel_mask; |
1090 | int i; | 1100 | int i; |
1091 | 1101 | ||
1092 | DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); | ||
1093 | if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index))) | 1102 | if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index))) |
1094 | return -EINVAL; | 1103 | return -EINVAL; |
1095 | if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED)) | 1104 | if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED)) |
@@ -1131,7 +1140,7 @@ static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe, | |||
1131 | list[head].size = cpu_to_le32(length); | 1140 | list[head].size = cpu_to_le32(length); |
1132 | pipe->sglist_head++; | 1141 | pipe->sglist_head++; |
1133 | } else { | 1142 | } else { |
1134 | DE_ACT(("SGlist: too many fragments\n")); | 1143 | dev_err(chip->card->dev, "SGlist: too many fragments\n"); |
1135 | return -ENOMEM; | 1144 | return -ENOMEM; |
1136 | } | 1145 | } |
1137 | return 0; | 1146 | return 0; |
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c index afa273330e8a..23a099425834 100644 --- a/sound/pci/echoaudio/echoaudio_gml.c +++ b/sound/pci/echoaudio/echoaudio_gml.c | |||
@@ -46,7 +46,8 @@ static int check_asic_status(struct echoaudio *chip) | |||
46 | /* The DSP will return a value to indicate whether or not the | 46 | /* The DSP will return a value to indicate whether or not the |
47 | ASIC is currently loaded */ | 47 | ASIC is currently loaded */ |
48 | if (read_dsp(chip, &asic_status) < 0) { | 48 | if (read_dsp(chip, &asic_status) < 0) { |
49 | DE_INIT(("check_asic_status: failed on read_dsp\n")); | 49 | dev_err(chip->card->dev, |
50 | "check_asic_status: failed on read_dsp\n"); | ||
50 | chip->asic_loaded = FALSE; | 51 | chip->asic_loaded = FALSE; |
51 | return -EIO; | 52 | return -EIO; |
52 | } | 53 | } |
@@ -68,7 +69,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force) | |||
68 | else | 69 | else |
69 | value &= ~GML_DIGITAL_IN_AUTO_MUTE; | 70 | value &= ~GML_DIGITAL_IN_AUTO_MUTE; |
70 | 71 | ||
71 | DE_ACT(("write_control_reg: 0x%x\n", value)); | 72 | dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value); |
72 | 73 | ||
73 | /* Write the control register */ | 74 | /* Write the control register */ |
74 | value = cpu_to_le32(value); | 75 | value = cpu_to_le32(value); |
@@ -91,7 +92,7 @@ If the auto-mute is disabled, the digital inputs are enabled regardless of | |||
91 | what the input clock is set or what is connected. */ | 92 | what the input clock is set or what is connected. */ |
92 | static int set_input_auto_mute(struct echoaudio *chip, int automute) | 93 | static int set_input_auto_mute(struct echoaudio *chip, int automute) |
93 | { | 94 | { |
94 | DE_ACT(("set_input_auto_mute %d\n", automute)); | 95 | dev_dbg(chip->card->dev, "set_input_auto_mute %d\n", automute); |
95 | 96 | ||
96 | chip->digital_in_automute = automute; | 97 | chip->digital_in_automute = automute; |
97 | 98 | ||
@@ -194,7 +195,7 @@ static int set_professional_spdif(struct echoaudio *chip, char prof) | |||
194 | if ((err = write_control_reg(chip, control_reg, FALSE))) | 195 | if ((err = write_control_reg(chip, control_reg, FALSE))) |
195 | return err; | 196 | return err; |
196 | chip->professional_spdif = prof; | 197 | chip->professional_spdif = prof; |
197 | DE_ACT(("set_professional_spdif to %s\n", | 198 | dev_dbg(chip->card->dev, "set_professional_spdif to %s\n", |
198 | prof ? "Professional" : "Consumer")); | 199 | prof ? "Professional" : "Consumer"); |
199 | return 0; | 200 | return 0; |
200 | } | 201 | } |
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c index d1615a0579d1..5dafe9260cb4 100644 --- a/sound/pci/echoaudio/gina20_dsp.c +++ b/sound/pci/echoaudio/gina20_dsp.c | |||
@@ -37,12 +37,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
37 | { | 37 | { |
38 | int err; | 38 | int err; |
39 | 39 | ||
40 | DE_INIT(("init_hw() - Gina20\n")); | ||
41 | if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20)) | 40 | if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20)) |
42 | return -ENODEV; | 41 | return -ENODEV; |
43 | 42 | ||
44 | if ((err = init_dsp_comm_page(chip))) { | 43 | if ((err = init_dsp_comm_page(chip))) { |
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 44 | dev_err(chip->card->dev, |
45 | "init_hw - could not initialize DSP comm page\n"); | ||
46 | return err; | 46 | return err; |
47 | } | 47 | } |
48 | 48 | ||
@@ -62,7 +62,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
62 | return err; | 62 | return err; |
63 | chip->bad_board = FALSE; | 63 | chip->bad_board = FALSE; |
64 | 64 | ||
65 | DE_INIT(("init_hw done\n")); | ||
66 | return err; | 65 | return err; |
67 | } | 66 | } |
68 | 67 | ||
@@ -149,7 +148,6 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
149 | 148 | ||
150 | static int set_input_clock(struct echoaudio *chip, u16 clock) | 149 | static int set_input_clock(struct echoaudio *chip, u16 clock) |
151 | { | 150 | { |
152 | DE_ACT(("set_input_clock:\n")); | ||
153 | 151 | ||
154 | switch (clock) { | 152 | switch (clock) { |
155 | case ECHO_CLOCK_INTERNAL: | 153 | case ECHO_CLOCK_INTERNAL: |
@@ -158,7 +156,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
158 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | 156 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; |
159 | set_sample_rate(chip, chip->sample_rate); | 157 | set_sample_rate(chip, chip->sample_rate); |
160 | chip->input_clock = clock; | 158 | chip->input_clock = clock; |
161 | DE_ACT(("Set Gina clock to INTERNAL\n")); | ||
162 | break; | 159 | break; |
163 | case ECHO_CLOCK_SPDIF: | 160 | case ECHO_CLOCK_SPDIF: |
164 | chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; | 161 | chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; |
@@ -166,7 +163,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
166 | clear_handshake(chip); | 163 | clear_handshake(chip); |
167 | send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | 164 | send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); |
168 | chip->clock_state = GD_CLOCK_SPDIFIN; | 165 | chip->clock_state = GD_CLOCK_SPDIFIN; |
169 | DE_ACT(("Set Gina20 clock to SPDIF\n")); | ||
170 | chip->input_clock = clock; | 166 | chip->input_clock = clock; |
171 | break; | 167 | break; |
172 | default: | 168 | default: |
@@ -208,7 +204,6 @@ static int update_flags(struct echoaudio *chip) | |||
208 | 204 | ||
209 | static int set_professional_spdif(struct echoaudio *chip, char prof) | 205 | static int set_professional_spdif(struct echoaudio *chip, char prof) |
210 | { | 206 | { |
211 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
212 | if (prof) | 207 | if (prof) |
213 | chip->comm_page->flags |= | 208 | chip->comm_page->flags |= |
214 | cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | 209 | cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); |
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c index 98f7cfa81b5f..6971766938bf 100644 --- a/sound/pci/echoaudio/gina24_dsp.c +++ b/sound/pci/echoaudio/gina24_dsp.c | |||
@@ -41,12 +41,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
41 | { | 41 | { |
42 | int err; | 42 | int err; |
43 | 43 | ||
44 | DE_INIT(("init_hw() - Gina24\n")); | ||
45 | if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24)) | 44 | if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24)) |
46 | return -ENODEV; | 45 | return -ENODEV; |
47 | 46 | ||
48 | if ((err = init_dsp_comm_page(chip))) { | 47 | if ((err = init_dsp_comm_page(chip))) { |
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 48 | dev_err(chip->card->dev, |
49 | "init_hw - could not initialize DSP comm page\n"); | ||
50 | return err; | 50 | return err; |
51 | } | 51 | } |
52 | 52 | ||
@@ -78,7 +78,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
78 | return err; | 78 | return err; |
79 | chip->bad_board = FALSE; | 79 | chip->bad_board = FALSE; |
80 | 80 | ||
81 | DE_INIT(("init_hw done\n")); | ||
82 | return err; | 81 | return err; |
83 | } | 82 | } |
84 | 83 | ||
@@ -155,7 +154,6 @@ static int load_asic(struct echoaudio *chip) | |||
155 | control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; | 154 | control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; |
156 | err = write_control_reg(chip, control_reg, TRUE); | 155 | err = write_control_reg(chip, control_reg, TRUE); |
157 | } | 156 | } |
158 | DE_INIT(("load_asic() done\n")); | ||
159 | return err; | 157 | return err; |
160 | } | 158 | } |
161 | 159 | ||
@@ -171,8 +169,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
171 | 169 | ||
172 | /* Only set the clock for internal mode. */ | 170 | /* Only set the clock for internal mode. */ |
173 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | 171 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { |
174 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | 172 | dev_warn(chip->card->dev, |
175 | "clock not set to CLK_CLOCKININTERNAL\n")); | 173 | "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); |
176 | /* Save the rate anyhow */ | 174 | /* Save the rate anyhow */ |
177 | chip->comm_page->sample_rate = cpu_to_le32(rate); | 175 | chip->comm_page->sample_rate = cpu_to_le32(rate); |
178 | chip->sample_rate = rate; | 176 | chip->sample_rate = rate; |
@@ -217,7 +215,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
217 | clock = GML_8KHZ; | 215 | clock = GML_8KHZ; |
218 | break; | 216 | break; |
219 | default: | 217 | default: |
220 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | 218 | dev_err(chip->card->dev, |
219 | "set_sample_rate: %d invalid!\n", rate); | ||
221 | return -EINVAL; | 220 | return -EINVAL; |
222 | } | 221 | } |
223 | 222 | ||
@@ -225,7 +224,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
225 | 224 | ||
226 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | 225 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ |
227 | chip->sample_rate = rate; | 226 | chip->sample_rate = rate; |
228 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | 227 | dev_dbg(chip->card->dev, "set_sample_rate: %d clock %d\n", rate, clock); |
229 | 228 | ||
230 | return write_control_reg(chip, control_reg, FALSE); | 229 | return write_control_reg(chip, control_reg, FALSE); |
231 | } | 230 | } |
@@ -236,7 +235,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
236 | { | 235 | { |
237 | u32 control_reg, clocks_from_dsp; | 236 | u32 control_reg, clocks_from_dsp; |
238 | 237 | ||
239 | DE_ACT(("set_input_clock:\n")); | ||
240 | 238 | ||
241 | /* Mask off the clock select bits */ | 239 | /* Mask off the clock select bits */ |
242 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | 240 | control_reg = le32_to_cpu(chip->comm_page->control_register) & |
@@ -245,13 +243,11 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
245 | 243 | ||
246 | switch (clock) { | 244 | switch (clock) { |
247 | case ECHO_CLOCK_INTERNAL: | 245 | case ECHO_CLOCK_INTERNAL: |
248 | DE_ACT(("Set Gina24 clock to INTERNAL\n")); | ||
249 | chip->input_clock = ECHO_CLOCK_INTERNAL; | 246 | chip->input_clock = ECHO_CLOCK_INTERNAL; |
250 | return set_sample_rate(chip, chip->sample_rate); | 247 | return set_sample_rate(chip, chip->sample_rate); |
251 | case ECHO_CLOCK_SPDIF: | 248 | case ECHO_CLOCK_SPDIF: |
252 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | 249 | if (chip->digital_mode == DIGITAL_MODE_ADAT) |
253 | return -EAGAIN; | 250 | return -EAGAIN; |
254 | DE_ACT(("Set Gina24 clock to SPDIF\n")); | ||
255 | control_reg |= GML_SPDIF_CLOCK; | 251 | control_reg |= GML_SPDIF_CLOCK; |
256 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) | 252 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) |
257 | control_reg |= GML_DOUBLE_SPEED_MODE; | 253 | control_reg |= GML_DOUBLE_SPEED_MODE; |
@@ -261,21 +257,19 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
261 | case ECHO_CLOCK_ADAT: | 257 | case ECHO_CLOCK_ADAT: |
262 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | 258 | if (chip->digital_mode != DIGITAL_MODE_ADAT) |
263 | return -EAGAIN; | 259 | return -EAGAIN; |
264 | DE_ACT(("Set Gina24 clock to ADAT\n")); | ||
265 | control_reg |= GML_ADAT_CLOCK; | 260 | control_reg |= GML_ADAT_CLOCK; |
266 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 261 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
267 | break; | 262 | break; |
268 | case ECHO_CLOCK_ESYNC: | 263 | case ECHO_CLOCK_ESYNC: |
269 | DE_ACT(("Set Gina24 clock to ESYNC\n")); | ||
270 | control_reg |= GML_ESYNC_CLOCK; | 264 | control_reg |= GML_ESYNC_CLOCK; |
271 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 265 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
272 | break; | 266 | break; |
273 | case ECHO_CLOCK_ESYNC96: | 267 | case ECHO_CLOCK_ESYNC96: |
274 | DE_ACT(("Set Gina24 clock to ESYNC96\n")); | ||
275 | control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; | 268 | control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; |
276 | break; | 269 | break; |
277 | default: | 270 | default: |
278 | DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock)); | 271 | dev_err(chip->card->dev, |
272 | "Input clock 0x%x not supported for Gina24\n", clock); | ||
279 | return -EINVAL; | 273 | return -EINVAL; |
280 | } | 274 | } |
281 | 275 | ||
@@ -304,7 +298,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
304 | incompatible_clock = TRUE; | 298 | incompatible_clock = TRUE; |
305 | break; | 299 | break; |
306 | default: | 300 | default: |
307 | DE_ACT(("Digital mode not supported: %d\n", mode)); | 301 | dev_err(chip->card->dev, |
302 | "Digital mode not supported: %d\n", mode); | ||
308 | return -EINVAL; | 303 | return -EINVAL; |
309 | } | 304 | } |
310 | 305 | ||
@@ -344,6 +339,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
344 | return err; | 339 | return err; |
345 | chip->digital_mode = mode; | 340 | chip->digital_mode = mode; |
346 | 341 | ||
347 | DE_ACT(("set_digital_mode to %d\n", chip->digital_mode)); | 342 | dev_dbg(chip->card->dev, |
343 | "set_digital_mode to %d\n", chip->digital_mode); | ||
348 | return incompatible_clock; | 344 | return incompatible_clock; |
349 | } | 345 | } |
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c index 5e85f14fe5a8..54edd67edff7 100644 --- a/sound/pci/echoaudio/indigo_dsp.c +++ b/sound/pci/echoaudio/indigo_dsp.c | |||
@@ -38,12 +38,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
38 | { | 38 | { |
39 | int err; | 39 | int err; |
40 | 40 | ||
41 | DE_INIT(("init_hw() - Indigo\n")); | ||
42 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO)) | 41 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO)) |
43 | return -ENODEV; | 42 | return -ENODEV; |
44 | 43 | ||
45 | if ((err = init_dsp_comm_page(chip))) { | 44 | if ((err = init_dsp_comm_page(chip))) { |
46 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 45 | dev_err(chip->card->dev, |
46 | "init_hw - could not initialize DSP comm page\n"); | ||
47 | return err; | 47 | return err; |
48 | } | 48 | } |
49 | 49 | ||
@@ -60,7 +60,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
60 | return err; | 60 | return err; |
61 | chip->bad_board = FALSE; | 61 | chip->bad_board = FALSE; |
62 | 62 | ||
63 | DE_INIT(("init_hw done\n")); | ||
64 | return err; | 63 | return err; |
65 | } | 64 | } |
66 | 65 | ||
@@ -109,7 +108,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
109 | control_reg = MIA_32000; | 108 | control_reg = MIA_32000; |
110 | break; | 109 | break; |
111 | default: | 110 | default: |
112 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | 111 | dev_err(chip->card->dev, |
112 | "set_sample_rate: %d invalid!\n", rate); | ||
113 | return -EINVAL; | 113 | return -EINVAL; |
114 | } | 114 | } |
115 | 115 | ||
@@ -147,7 +147,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | |||
147 | index = output * num_pipes_out(chip) + pipe; | 147 | index = output * num_pipes_out(chip) + pipe; |
148 | chip->comm_page->vmixer[index] = gain; | 148 | chip->comm_page->vmixer[index] = gain; |
149 | 149 | ||
150 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | 150 | dev_dbg(chip->card->dev, |
151 | "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); | ||
151 | return 0; | 152 | return 0; |
152 | } | 153 | } |
153 | 154 | ||
diff --git a/sound/pci/echoaudio/indigo_express_dsp.c b/sound/pci/echoaudio/indigo_express_dsp.c index 2e4ab3e34a74..ceda2d7046ac 100644 --- a/sound/pci/echoaudio/indigo_express_dsp.c +++ b/sound/pci/echoaudio/indigo_express_dsp.c | |||
@@ -61,7 +61,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
61 | 61 | ||
62 | control_reg |= clock; | 62 | control_reg |= clock; |
63 | if (control_reg != old_control_reg) { | 63 | if (control_reg != old_control_reg) { |
64 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | 64 | dev_dbg(chip->card->dev, |
65 | "set_sample_rate: %d clock %d\n", rate, clock); | ||
65 | chip->comm_page->control_register = cpu_to_le32(control_reg); | 66 | chip->comm_page->control_register = cpu_to_le32(control_reg); |
66 | chip->sample_rate = rate; | 67 | chip->sample_rate = rate; |
67 | clear_handshake(chip); | 68 | clear_handshake(chip); |
@@ -89,7 +90,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | |||
89 | index = output * num_pipes_out(chip) + pipe; | 90 | index = output * num_pipes_out(chip) + pipe; |
90 | chip->comm_page->vmixer[index] = gain; | 91 | chip->comm_page->vmixer[index] = gain; |
91 | 92 | ||
92 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | 93 | dev_dbg(chip->card->dev, |
94 | "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); | ||
93 | return 0; | 95 | return 0; |
94 | } | 96 | } |
95 | 97 | ||
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c index 68f3c8ccc1bf..2cf5cc092d7a 100644 --- a/sound/pci/echoaudio/indigodj_dsp.c +++ b/sound/pci/echoaudio/indigodj_dsp.c | |||
@@ -38,12 +38,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
38 | { | 38 | { |
39 | int err; | 39 | int err; |
40 | 40 | ||
41 | DE_INIT(("init_hw() - Indigo DJ\n")); | ||
42 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ)) | 41 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ)) |
43 | return -ENODEV; | 42 | return -ENODEV; |
44 | 43 | ||
45 | if ((err = init_dsp_comm_page(chip))) { | 44 | if ((err = init_dsp_comm_page(chip))) { |
46 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 45 | dev_err(chip->card->dev, |
46 | "init_hw - could not initialize DSP comm page\n"); | ||
47 | return err; | 47 | return err; |
48 | } | 48 | } |
49 | 49 | ||
@@ -60,7 +60,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
60 | return err; | 60 | return err; |
61 | chip->bad_board = FALSE; | 61 | chip->bad_board = FALSE; |
62 | 62 | ||
63 | DE_INIT(("init_hw done\n")); | ||
64 | return err; | 63 | return err; |
65 | } | 64 | } |
66 | 65 | ||
@@ -109,7 +108,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
109 | control_reg = MIA_32000; | 108 | control_reg = MIA_32000; |
110 | break; | 109 | break; |
111 | default: | 110 | default: |
112 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | 111 | dev_err(chip->card->dev, |
112 | "set_sample_rate: %d invalid!\n", rate); | ||
113 | return -EINVAL; | 113 | return -EINVAL; |
114 | } | 114 | } |
115 | 115 | ||
@@ -147,7 +147,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | |||
147 | index = output * num_pipes_out(chip) + pipe; | 147 | index = output * num_pipes_out(chip) + pipe; |
148 | chip->comm_page->vmixer[index] = gain; | 148 | chip->comm_page->vmixer[index] = gain; |
149 | 149 | ||
150 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | 150 | dev_dbg(chip->card->dev, |
151 | "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); | ||
151 | return 0; | 152 | return 0; |
152 | } | 153 | } |
153 | 154 | ||
diff --git a/sound/pci/echoaudio/indigodjx_dsp.c b/sound/pci/echoaudio/indigodjx_dsp.c index bb9632c752a9..5252863f1681 100644 --- a/sound/pci/echoaudio/indigodjx_dsp.c +++ b/sound/pci/echoaudio/indigodjx_dsp.c | |||
@@ -35,13 +35,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
35 | { | 35 | { |
36 | int err; | 36 | int err; |
37 | 37 | ||
38 | DE_INIT(("init_hw() - Indigo DJx\n")); | ||
39 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJX)) | 38 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJX)) |
40 | return -ENODEV; | 39 | return -ENODEV; |
41 | 40 | ||
42 | err = init_dsp_comm_page(chip); | 41 | err = init_dsp_comm_page(chip); |
43 | if (err < 0) { | 42 | if (err < 0) { |
44 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 43 | dev_err(chip->card->dev, |
44 | "init_hw - could not initialize DSP comm page\n"); | ||
45 | return err; | 45 | return err; |
46 | } | 46 | } |
47 | 47 | ||
@@ -59,7 +59,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
59 | return err; | 59 | return err; |
60 | chip->bad_board = FALSE; | 60 | chip->bad_board = FALSE; |
61 | 61 | ||
62 | DE_INIT(("init_hw done\n")); | ||
63 | return err; | 62 | return err; |
64 | } | 63 | } |
65 | 64 | ||
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c index beb9a5b69892..4e81787627e0 100644 --- a/sound/pci/echoaudio/indigoio_dsp.c +++ b/sound/pci/echoaudio/indigoio_dsp.c | |||
@@ -38,12 +38,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
38 | { | 38 | { |
39 | int err; | 39 | int err; |
40 | 40 | ||
41 | DE_INIT(("init_hw() - Indigo IO\n")); | ||
42 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO)) | 41 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO)) |
43 | return -ENODEV; | 42 | return -ENODEV; |
44 | 43 | ||
45 | if ((err = init_dsp_comm_page(chip))) { | 44 | if ((err = init_dsp_comm_page(chip))) { |
46 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 45 | dev_err(chip->card->dev, |
46 | "init_hw - could not initialize DSP comm page\n"); | ||
47 | return err; | 47 | return err; |
48 | } | 48 | } |
49 | 49 | ||
@@ -60,7 +60,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
60 | return err; | 60 | return err; |
61 | chip->bad_board = FALSE; | 61 | chip->bad_board = FALSE; |
62 | 62 | ||
63 | DE_INIT(("init_hw done\n")); | ||
64 | return err; | 63 | return err; |
65 | } | 64 | } |
66 | 65 | ||
@@ -118,7 +117,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | |||
118 | index = output * num_pipes_out(chip) + pipe; | 117 | index = output * num_pipes_out(chip) + pipe; |
119 | chip->comm_page->vmixer[index] = gain; | 118 | chip->comm_page->vmixer[index] = gain; |
120 | 119 | ||
121 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | 120 | dev_dbg(chip->card->dev, |
121 | "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); | ||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
diff --git a/sound/pci/echoaudio/indigoiox_dsp.c b/sound/pci/echoaudio/indigoiox_dsp.c index 394c6e76bcbc..6de3f9bc6d26 100644 --- a/sound/pci/echoaudio/indigoiox_dsp.c +++ b/sound/pci/echoaudio/indigoiox_dsp.c | |||
@@ -35,13 +35,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
35 | { | 35 | { |
36 | int err; | 36 | int err; |
37 | 37 | ||
38 | DE_INIT(("init_hw() - Indigo IOx\n")); | ||
39 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IOX)) | 38 | if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IOX)) |
40 | return -ENODEV; | 39 | return -ENODEV; |
41 | 40 | ||
42 | err = init_dsp_comm_page(chip); | 41 | err = init_dsp_comm_page(chip); |
43 | if (err < 0) { | 42 | if (err < 0) { |
44 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 43 | dev_err(chip->card->dev, |
44 | "init_hw - could not initialize DSP comm page\n"); | ||
45 | return err; | 45 | return err; |
46 | } | 46 | } |
47 | 47 | ||
@@ -59,7 +59,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
59 | return err; | 59 | return err; |
60 | chip->bad_board = FALSE; | 60 | chip->bad_board = FALSE; |
61 | 61 | ||
62 | DE_INIT(("init_hw done\n")); | ||
63 | return err; | 62 | return err; |
64 | } | 63 | } |
65 | 64 | ||
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c index 53ce94605044..f2024a3565af 100644 --- a/sound/pci/echoaudio/layla20_dsp.c +++ b/sound/pci/echoaudio/layla20_dsp.c | |||
@@ -40,12 +40,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
40 | { | 40 | { |
41 | int err; | 41 | int err; |
42 | 42 | ||
43 | DE_INIT(("init_hw() - Layla20\n")); | ||
44 | if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20)) | 43 | if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20)) |
45 | return -ENODEV; | 44 | return -ENODEV; |
46 | 45 | ||
47 | if ((err = init_dsp_comm_page(chip))) { | 46 | if ((err = init_dsp_comm_page(chip))) { |
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 47 | dev_err(chip->card->dev, |
48 | "init_hw - could not initialize DSP comm page\n"); | ||
49 | return err; | 49 | return err; |
50 | } | 50 | } |
51 | 51 | ||
@@ -64,7 +64,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
64 | return err; | 64 | return err; |
65 | chip->bad_board = FALSE; | 65 | chip->bad_board = FALSE; |
66 | 66 | ||
67 | DE_INIT(("init_hw done\n")); | ||
68 | return err; | 67 | return err; |
69 | } | 68 | } |
70 | 69 | ||
@@ -121,7 +120,8 @@ static int check_asic_status(struct echoaudio *chip) | |||
121 | /* The DSP will return a value to indicate whether or not | 120 | /* The DSP will return a value to indicate whether or not |
122 | the ASIC is currently loaded */ | 121 | the ASIC is currently loaded */ |
123 | if (read_dsp(chip, &asic_status) < 0) { | 122 | if (read_dsp(chip, &asic_status) < 0) { |
124 | DE_ACT(("check_asic_status: failed on read_dsp\n")); | 123 | dev_err(chip->card->dev, |
124 | "check_asic_status: failed on read_dsp\n"); | ||
125 | return -EIO; | 125 | return -EIO; |
126 | } | 126 | } |
127 | 127 | ||
@@ -164,8 +164,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
164 | /* Only set the clock for internal mode. Do not return failure, | 164 | /* Only set the clock for internal mode. Do not return failure, |
165 | simply treat it as a non-event. */ | 165 | simply treat it as a non-event. */ |
166 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | 166 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { |
167 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | 167 | dev_warn(chip->card->dev, |
168 | "clock not set to CLK_CLOCKININTERNAL\n")); | 168 | "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); |
169 | chip->comm_page->sample_rate = cpu_to_le32(rate); | 169 | chip->comm_page->sample_rate = cpu_to_le32(rate); |
170 | chip->sample_rate = rate; | 170 | chip->sample_rate = rate; |
171 | return 0; | 171 | return 0; |
@@ -174,7 +174,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
174 | if (wait_handshake(chip)) | 174 | if (wait_handshake(chip)) |
175 | return -EIO; | 175 | return -EIO; |
176 | 176 | ||
177 | DE_ACT(("set_sample_rate(%d)\n", rate)); | 177 | dev_dbg(chip->card->dev, "set_sample_rate(%d)\n", rate); |
178 | chip->sample_rate = rate; | 178 | chip->sample_rate = rate; |
179 | chip->comm_page->sample_rate = cpu_to_le32(rate); | 179 | chip->comm_page->sample_rate = cpu_to_le32(rate); |
180 | clear_handshake(chip); | 180 | clear_handshake(chip); |
@@ -188,29 +188,25 @@ static int set_input_clock(struct echoaudio *chip, u16 clock_source) | |||
188 | u16 clock; | 188 | u16 clock; |
189 | u32 rate; | 189 | u32 rate; |
190 | 190 | ||
191 | DE_ACT(("set_input_clock:\n")); | ||
192 | rate = 0; | 191 | rate = 0; |
193 | switch (clock_source) { | 192 | switch (clock_source) { |
194 | case ECHO_CLOCK_INTERNAL: | 193 | case ECHO_CLOCK_INTERNAL: |
195 | DE_ACT(("Set Layla20 clock to INTERNAL\n")); | ||
196 | rate = chip->sample_rate; | 194 | rate = chip->sample_rate; |
197 | clock = LAYLA20_CLOCK_INTERNAL; | 195 | clock = LAYLA20_CLOCK_INTERNAL; |
198 | break; | 196 | break; |
199 | case ECHO_CLOCK_SPDIF: | 197 | case ECHO_CLOCK_SPDIF: |
200 | DE_ACT(("Set Layla20 clock to SPDIF\n")); | ||
201 | clock = LAYLA20_CLOCK_SPDIF; | 198 | clock = LAYLA20_CLOCK_SPDIF; |
202 | break; | 199 | break; |
203 | case ECHO_CLOCK_WORD: | 200 | case ECHO_CLOCK_WORD: |
204 | DE_ACT(("Set Layla20 clock to WORD\n")); | ||
205 | clock = LAYLA20_CLOCK_WORD; | 201 | clock = LAYLA20_CLOCK_WORD; |
206 | break; | 202 | break; |
207 | case ECHO_CLOCK_SUPER: | 203 | case ECHO_CLOCK_SUPER: |
208 | DE_ACT(("Set Layla20 clock to SUPER\n")); | ||
209 | clock = LAYLA20_CLOCK_SUPER; | 204 | clock = LAYLA20_CLOCK_SUPER; |
210 | break; | 205 | break; |
211 | default: | 206 | default: |
212 | DE_ACT(("Input clock 0x%x not supported for Layla24\n", | 207 | dev_err(chip->card->dev, |
213 | clock_source)); | 208 | "Input clock 0x%x not supported for Layla24\n", |
209 | clock_source); | ||
214 | return -EINVAL; | 210 | return -EINVAL; |
215 | } | 211 | } |
216 | chip->input_clock = clock_source; | 212 | chip->input_clock = clock_source; |
@@ -229,7 +225,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock_source) | |||
229 | 225 | ||
230 | static int set_output_clock(struct echoaudio *chip, u16 clock) | 226 | static int set_output_clock(struct echoaudio *chip, u16 clock) |
231 | { | 227 | { |
232 | DE_ACT(("set_output_clock: %d\n", clock)); | ||
233 | switch (clock) { | 228 | switch (clock) { |
234 | case ECHO_CLOCK_SUPER: | 229 | case ECHO_CLOCK_SUPER: |
235 | clock = LAYLA20_OUTPUT_CLOCK_SUPER; | 230 | clock = LAYLA20_OUTPUT_CLOCK_SUPER; |
@@ -238,7 +233,7 @@ static int set_output_clock(struct echoaudio *chip, u16 clock) | |||
238 | clock = LAYLA20_OUTPUT_CLOCK_WORD; | 233 | clock = LAYLA20_OUTPUT_CLOCK_WORD; |
239 | break; | 234 | break; |
240 | default: | 235 | default: |
241 | DE_ACT(("set_output_clock wrong clock\n")); | 236 | dev_err(chip->card->dev, "set_output_clock wrong clock\n"); |
242 | return -EINVAL; | 237 | return -EINVAL; |
243 | } | 238 | } |
244 | 239 | ||
@@ -283,7 +278,6 @@ static int update_flags(struct echoaudio *chip) | |||
283 | 278 | ||
284 | static int set_professional_spdif(struct echoaudio *chip, char prof) | 279 | static int set_professional_spdif(struct echoaudio *chip, char prof) |
285 | { | 280 | { |
286 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
287 | if (prof) | 281 | if (prof) |
288 | chip->comm_page->flags |= | 282 | chip->comm_page->flags |= |
289 | cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | 283 | cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); |
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c index 8c041647f285..4f11e81f6c0e 100644 --- a/sound/pci/echoaudio/layla24_dsp.c +++ b/sound/pci/echoaudio/layla24_dsp.c | |||
@@ -40,12 +40,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
40 | { | 40 | { |
41 | int err; | 41 | int err; |
42 | 42 | ||
43 | DE_INIT(("init_hw() - Layla24\n")); | ||
44 | if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24)) | 43 | if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24)) |
45 | return -ENODEV; | 44 | return -ENODEV; |
46 | 45 | ||
47 | if ((err = init_dsp_comm_page(chip))) { | 46 | if ((err = init_dsp_comm_page(chip))) { |
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 47 | dev_err(chip->card->dev, |
48 | "init_hw - could not initialize DSP comm page\n"); | ||
49 | return err; | 49 | return err; |
50 | } | 50 | } |
51 | 51 | ||
@@ -69,7 +69,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
69 | if ((err = init_line_levels(chip)) < 0) | 69 | if ((err = init_line_levels(chip)) < 0) |
70 | return err; | 70 | return err; |
71 | 71 | ||
72 | DE_INIT(("init_hw done\n")); | ||
73 | return err; | 72 | return err; |
74 | } | 73 | } |
75 | 74 | ||
@@ -117,7 +116,6 @@ static int load_asic(struct echoaudio *chip) | |||
117 | if (chip->asic_loaded) | 116 | if (chip->asic_loaded) |
118 | return 1; | 117 | return 1; |
119 | 118 | ||
120 | DE_INIT(("load_asic\n")); | ||
121 | 119 | ||
122 | /* Give the DSP a few milliseconds to settle down */ | 120 | /* Give the DSP a few milliseconds to settle down */ |
123 | mdelay(10); | 121 | mdelay(10); |
@@ -151,7 +149,6 @@ static int load_asic(struct echoaudio *chip) | |||
151 | err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, | 149 | err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, |
152 | TRUE); | 150 | TRUE); |
153 | 151 | ||
154 | DE_INIT(("load_asic() done\n")); | ||
155 | return err; | 152 | return err; |
156 | } | 153 | } |
157 | 154 | ||
@@ -167,8 +164,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
167 | 164 | ||
168 | /* Only set the clock for internal mode. */ | 165 | /* Only set the clock for internal mode. */ |
169 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | 166 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { |
170 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | 167 | dev_warn(chip->card->dev, |
171 | "clock not set to CLK_CLOCKININTERNAL\n")); | 168 | "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); |
172 | /* Save the rate anyhow */ | 169 | /* Save the rate anyhow */ |
173 | chip->comm_page->sample_rate = cpu_to_le32(rate); | 170 | chip->comm_page->sample_rate = cpu_to_le32(rate); |
174 | chip->sample_rate = rate; | 171 | chip->sample_rate = rate; |
@@ -241,7 +238,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
241 | 238 | ||
242 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ | 239 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ |
243 | chip->sample_rate = rate; | 240 | chip->sample_rate = rate; |
244 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg)); | 241 | dev_dbg(chip->card->dev, |
242 | "set_sample_rate: %d clock %d\n", rate, control_reg); | ||
245 | 243 | ||
246 | return write_control_reg(chip, control_reg, FALSE); | 244 | return write_control_reg(chip, control_reg, FALSE); |
247 | } | 245 | } |
@@ -260,7 +258,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
260 | /* Pick the new clock */ | 258 | /* Pick the new clock */ |
261 | switch (clock) { | 259 | switch (clock) { |
262 | case ECHO_CLOCK_INTERNAL: | 260 | case ECHO_CLOCK_INTERNAL: |
263 | DE_ACT(("Set Layla24 clock to INTERNAL\n")); | ||
264 | chip->input_clock = ECHO_CLOCK_INTERNAL; | 261 | chip->input_clock = ECHO_CLOCK_INTERNAL; |
265 | return set_sample_rate(chip, chip->sample_rate); | 262 | return set_sample_rate(chip, chip->sample_rate); |
266 | case ECHO_CLOCK_SPDIF: | 263 | case ECHO_CLOCK_SPDIF: |
@@ -269,7 +266,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
269 | control_reg |= GML_SPDIF_CLOCK; | 266 | control_reg |= GML_SPDIF_CLOCK; |
270 | /* Layla24 doesn't support 96KHz S/PDIF */ | 267 | /* Layla24 doesn't support 96KHz S/PDIF */ |
271 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 268 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
272 | DE_ACT(("Set Layla24 clock to SPDIF\n")); | ||
273 | break; | 269 | break; |
274 | case ECHO_CLOCK_WORD: | 270 | case ECHO_CLOCK_WORD: |
275 | control_reg |= GML_WORD_CLOCK; | 271 | control_reg |= GML_WORD_CLOCK; |
@@ -277,17 +273,16 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
277 | control_reg |= GML_DOUBLE_SPEED_MODE; | 273 | control_reg |= GML_DOUBLE_SPEED_MODE; |
278 | else | 274 | else |
279 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 275 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
280 | DE_ACT(("Set Layla24 clock to WORD\n")); | ||
281 | break; | 276 | break; |
282 | case ECHO_CLOCK_ADAT: | 277 | case ECHO_CLOCK_ADAT: |
283 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | 278 | if (chip->digital_mode != DIGITAL_MODE_ADAT) |
284 | return -EAGAIN; | 279 | return -EAGAIN; |
285 | control_reg |= GML_ADAT_CLOCK; | 280 | control_reg |= GML_ADAT_CLOCK; |
286 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 281 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
287 | DE_ACT(("Set Layla24 clock to ADAT\n")); | ||
288 | break; | 282 | break; |
289 | default: | 283 | default: |
290 | DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock)); | 284 | dev_err(chip->card->dev, |
285 | "Input clock 0x%x not supported for Layla24\n", clock); | ||
291 | return -EINVAL; | 286 | return -EINVAL; |
292 | } | 287 | } |
293 | 288 | ||
@@ -353,7 +348,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
353 | asic = FW_LAYLA24_2A_ASIC; | 348 | asic = FW_LAYLA24_2A_ASIC; |
354 | break; | 349 | break; |
355 | default: | 350 | default: |
356 | DE_ACT(("Digital mode not supported: %d\n", mode)); | 351 | dev_err(chip->card->dev, |
352 | "Digital mode not supported: %d\n", mode); | ||
357 | return -EINVAL; | 353 | return -EINVAL; |
358 | } | 354 | } |
359 | 355 | ||
@@ -393,6 +389,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
393 | return err; | 389 | return err; |
394 | chip->digital_mode = mode; | 390 | chip->digital_mode = mode; |
395 | 391 | ||
396 | DE_ACT(("set_digital_mode to %d\n", mode)); | 392 | dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode); |
397 | return incompatible_clock; | 393 | return incompatible_clock; |
398 | } | 394 | } |
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c index 6ebfa6e7ab9e..fdad079ad9a1 100644 --- a/sound/pci/echoaudio/mia_dsp.c +++ b/sound/pci/echoaudio/mia_dsp.c | |||
@@ -41,12 +41,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
41 | { | 41 | { |
42 | int err; | 42 | int err; |
43 | 43 | ||
44 | DE_INIT(("init_hw() - Mia\n")); | ||
45 | if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA)) | 44 | if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA)) |
46 | return -ENODEV; | 45 | return -ENODEV; |
47 | 46 | ||
48 | if ((err = init_dsp_comm_page(chip))) { | 47 | if ((err = init_dsp_comm_page(chip))) { |
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 48 | dev_err(chip->card->dev, |
49 | "init_hw - could not initialize DSP comm page\n"); | ||
50 | return err; | 50 | return err; |
51 | } | 51 | } |
52 | 52 | ||
@@ -66,7 +66,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
66 | return err; | 66 | return err; |
67 | chip->bad_board = FALSE; | 67 | chip->bad_board = FALSE; |
68 | 68 | ||
69 | DE_INIT(("init_hw done\n")); | ||
70 | return err; | 69 | return err; |
71 | } | 70 | } |
72 | 71 | ||
@@ -126,7 +125,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
126 | control_reg = MIA_32000; | 125 | control_reg = MIA_32000; |
127 | break; | 126 | break; |
128 | default: | 127 | default: |
129 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | 128 | dev_err(chip->card->dev, |
129 | "set_sample_rate: %d invalid!\n", rate); | ||
130 | return -EINVAL; | 130 | return -EINVAL; |
131 | } | 131 | } |
132 | 132 | ||
@@ -153,7 +153,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
153 | 153 | ||
154 | static int set_input_clock(struct echoaudio *chip, u16 clock) | 154 | static int set_input_clock(struct echoaudio *chip, u16 clock) |
155 | { | 155 | { |
156 | DE_ACT(("set_input_clock(%d)\n", clock)); | 156 | dev_dbg(chip->card->dev, "set_input_clock(%d)\n", clock); |
157 | if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && | 157 | if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && |
158 | clock != ECHO_CLOCK_SPDIF)) | 158 | clock != ECHO_CLOCK_SPDIF)) |
159 | return -EINVAL; | 159 | return -EINVAL; |
@@ -181,7 +181,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | |||
181 | index = output * num_pipes_out(chip) + pipe; | 181 | index = output * num_pipes_out(chip) + pipe; |
182 | chip->comm_page->vmixer[index] = gain; | 182 | chip->comm_page->vmixer[index] = gain; |
183 | 183 | ||
184 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | 184 | dev_dbg(chip->card->dev, |
185 | "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); | ||
185 | return 0; | 186 | return 0; |
186 | } | 187 | } |
187 | 188 | ||
@@ -211,7 +212,7 @@ static int update_flags(struct echoaudio *chip) | |||
211 | 212 | ||
212 | static int set_professional_spdif(struct echoaudio *chip, char prof) | 213 | static int set_professional_spdif(struct echoaudio *chip, char prof) |
213 | { | 214 | { |
214 | DE_ACT(("set_professional_spdif %d\n", prof)); | 215 | dev_dbg(chip->card->dev, "set_professional_spdif %d\n", prof); |
215 | if (prof) | 216 | if (prof) |
216 | chip->comm_page->flags |= | 217 | chip->comm_page->flags |= |
217 | cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | 218 | cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); |
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c index 7f4dfae0323a..d913749d154a 100644 --- a/sound/pci/echoaudio/midi.c +++ b/sound/pci/echoaudio/midi.c | |||
@@ -36,7 +36,7 @@ | |||
36 | /* Start and stop Midi input */ | 36 | /* Start and stop Midi input */ |
37 | static int enable_midi_input(struct echoaudio *chip, char enable) | 37 | static int enable_midi_input(struct echoaudio *chip, char enable) |
38 | { | 38 | { |
39 | DE_MID(("enable_midi_input(%d)\n", enable)); | 39 | dev_dbg(chip->card->dev, "enable_midi_input(%d)\n", enable); |
40 | 40 | ||
41 | if (wait_handshake(chip)) | 41 | if (wait_handshake(chip)) |
42 | return -EIO; | 42 | return -EIO; |
@@ -74,7 +74,7 @@ static int write_midi(struct echoaudio *chip, u8 *data, int bytes) | |||
74 | chip->comm_page->midi_out_free_count = 0; | 74 | chip->comm_page->midi_out_free_count = 0; |
75 | clear_handshake(chip); | 75 | clear_handshake(chip); |
76 | send_vector(chip, DSP_VC_MIDI_WRITE); | 76 | send_vector(chip, DSP_VC_MIDI_WRITE); |
77 | DE_MID(("write_midi: %d\n", bytes)); | 77 | dev_dbg(chip->card->dev, "write_midi: %d\n", bytes); |
78 | return bytes; | 78 | return bytes; |
79 | } | 79 | } |
80 | 80 | ||
@@ -157,7 +157,6 @@ static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream) | |||
157 | struct echoaudio *chip = substream->rmidi->private_data; | 157 | struct echoaudio *chip = substream->rmidi->private_data; |
158 | 158 | ||
159 | chip->midi_in = substream; | 159 | chip->midi_in = substream; |
160 | DE_MID(("rawmidi_iopen\n")); | ||
161 | return 0; | 160 | return 0; |
162 | } | 161 | } |
163 | 162 | ||
@@ -183,7 +182,6 @@ static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream) | |||
183 | struct echoaudio *chip = substream->rmidi->private_data; | 182 | struct echoaudio *chip = substream->rmidi->private_data; |
184 | 183 | ||
185 | chip->midi_in = NULL; | 184 | chip->midi_in = NULL; |
186 | DE_MID(("rawmidi_iclose\n")); | ||
187 | return 0; | 185 | return 0; |
188 | } | 186 | } |
189 | 187 | ||
@@ -196,7 +194,6 @@ static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream) | |||
196 | chip->tinuse = 0; | 194 | chip->tinuse = 0; |
197 | chip->midi_full = 0; | 195 | chip->midi_full = 0; |
198 | chip->midi_out = substream; | 196 | chip->midi_out = substream; |
199 | DE_MID(("rawmidi_oopen\n")); | ||
200 | return 0; | 197 | return 0; |
201 | } | 198 | } |
202 | 199 | ||
@@ -209,7 +206,6 @@ static void snd_echo_midi_output_write(unsigned long data) | |||
209 | int bytes, sent, time; | 206 | int bytes, sent, time; |
210 | unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; | 207 | unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; |
211 | 208 | ||
212 | DE_MID(("snd_echo_midi_output_write\n")); | ||
213 | /* No interrupts are involved: we have to check at regular intervals | 209 | /* No interrupts are involved: we have to check at regular intervals |
214 | if the card's output buffer has room for new data. */ | 210 | if the card's output buffer has room for new data. */ |
215 | sent = bytes = 0; | 211 | sent = bytes = 0; |
@@ -218,7 +214,7 @@ static void snd_echo_midi_output_write(unsigned long data) | |||
218 | if (!snd_rawmidi_transmit_empty(chip->midi_out)) { | 214 | if (!snd_rawmidi_transmit_empty(chip->midi_out)) { |
219 | bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, | 215 | bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, |
220 | MIDI_OUT_BUFFER_SIZE - 1); | 216 | MIDI_OUT_BUFFER_SIZE - 1); |
221 | DE_MID(("Try to send %d bytes...\n", bytes)); | 217 | dev_dbg(chip->card->dev, "Try to send %d bytes...\n", bytes); |
222 | sent = write_midi(chip, buf, bytes); | 218 | sent = write_midi(chip, buf, bytes); |
223 | if (sent < 0) { | 219 | if (sent < 0) { |
224 | dev_err(chip->card->dev, | 220 | dev_err(chip->card->dev, |
@@ -227,12 +223,12 @@ static void snd_echo_midi_output_write(unsigned long data) | |||
227 | sent = 9000; | 223 | sent = 9000; |
228 | chip->midi_full = 1; | 224 | chip->midi_full = 1; |
229 | } else if (sent > 0) { | 225 | } else if (sent > 0) { |
230 | DE_MID(("%d bytes sent\n", sent)); | 226 | dev_dbg(chip->card->dev, "%d bytes sent\n", sent); |
231 | snd_rawmidi_transmit_ack(chip->midi_out, sent); | 227 | snd_rawmidi_transmit_ack(chip->midi_out, sent); |
232 | } else { | 228 | } else { |
233 | /* Buffer is full. DSP's internal buffer is 64 (128 ?) | 229 | /* Buffer is full. DSP's internal buffer is 64 (128 ?) |
234 | bytes long. Let's wait until half of them are sent */ | 230 | bytes long. Let's wait until half of them are sent */ |
235 | DE_MID(("Full\n")); | 231 | dev_dbg(chip->card->dev, "Full\n"); |
236 | sent = 32; | 232 | sent = 32; |
237 | chip->midi_full = 1; | 233 | chip->midi_full = 1; |
238 | } | 234 | } |
@@ -244,7 +240,8 @@ static void snd_echo_midi_output_write(unsigned long data) | |||
244 | sent */ | 240 | sent */ |
245 | time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ | 241 | time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ |
246 | mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); | 242 | mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); |
247 | DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000))); | 243 | dev_dbg(chip->card->dev, |
244 | "Timer armed(%d)\n", ((time * HZ + 999) / 1000)); | ||
248 | } | 245 | } |
249 | spin_unlock_irqrestore(&chip->lock, flags); | 246 | spin_unlock_irqrestore(&chip->lock, flags); |
250 | } | 247 | } |
@@ -256,7 +253,7 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream | |||
256 | { | 253 | { |
257 | struct echoaudio *chip = substream->rmidi->private_data; | 254 | struct echoaudio *chip = substream->rmidi->private_data; |
258 | 255 | ||
259 | DE_MID(("snd_echo_midi_output_trigger(%d)\n", up)); | 256 | dev_dbg(chip->card->dev, "snd_echo_midi_output_trigger(%d)\n", up); |
260 | spin_lock_irq(&chip->lock); | 257 | spin_lock_irq(&chip->lock); |
261 | if (up) { | 258 | if (up) { |
262 | if (!chip->tinuse) { | 259 | if (!chip->tinuse) { |
@@ -270,7 +267,7 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream | |||
270 | chip->tinuse = 0; | 267 | chip->tinuse = 0; |
271 | spin_unlock_irq(&chip->lock); | 268 | spin_unlock_irq(&chip->lock); |
272 | del_timer_sync(&chip->timer); | 269 | del_timer_sync(&chip->timer); |
273 | DE_MID(("Timer removed\n")); | 270 | dev_dbg(chip->card->dev, "Timer removed\n"); |
274 | return; | 271 | return; |
275 | } | 272 | } |
276 | } | 273 | } |
@@ -287,7 +284,6 @@ static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream) | |||
287 | struct echoaudio *chip = substream->rmidi->private_data; | 284 | struct echoaudio *chip = substream->rmidi->private_data; |
288 | 285 | ||
289 | chip->midi_out = NULL; | 286 | chip->midi_out = NULL; |
290 | DE_MID(("rawmidi_oclose\n")); | ||
291 | return 0; | 287 | return 0; |
292 | } | 288 | } |
293 | 289 | ||
@@ -327,6 +323,5 @@ static int snd_echo_midi_create(struct snd_card *card, | |||
327 | 323 | ||
328 | chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | | 324 | chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | |
329 | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | 325 | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; |
330 | DE_INIT(("MIDI ok\n")); | ||
331 | return 0; | 326 | return 0; |
332 | } | 327 | } |
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c index 6e6a7eb555b8..843c7a5e5105 100644 --- a/sound/pci/echoaudio/mona_dsp.c +++ b/sound/pci/echoaudio/mona_dsp.c | |||
@@ -41,12 +41,12 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
41 | { | 41 | { |
42 | int err; | 42 | int err; |
43 | 43 | ||
44 | DE_INIT(("init_hw() - Mona\n")); | ||
45 | if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA)) | 44 | if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA)) |
46 | return -ENODEV; | 45 | return -ENODEV; |
47 | 46 | ||
48 | if ((err = init_dsp_comm_page(chip))) { | 47 | if ((err = init_dsp_comm_page(chip))) { |
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | 48 | dev_err(chip->card->dev, |
49 | "init_hw - could not initialize DSP comm page\n"); | ||
50 | return err; | 50 | return err; |
51 | } | 51 | } |
52 | 52 | ||
@@ -71,7 +71,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | |||
71 | return err; | 71 | return err; |
72 | chip->bad_board = FALSE; | 72 | chip->bad_board = FALSE; |
73 | 73 | ||
74 | DE_INIT(("init_hw done\n")); | ||
75 | return err; | 74 | return err; |
76 | } | 75 | } |
77 | 76 | ||
@@ -202,8 +201,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
202 | 201 | ||
203 | /* Only set the clock for internal mode. */ | 202 | /* Only set the clock for internal mode. */ |
204 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | 203 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { |
205 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | 204 | dev_dbg(chip->card->dev, |
206 | "clock not set to CLK_CLOCKININTERNAL\n")); | 205 | "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); |
207 | /* Save the rate anyhow */ | 206 | /* Save the rate anyhow */ |
208 | chip->comm_page->sample_rate = cpu_to_le32(rate); | 207 | chip->comm_page->sample_rate = cpu_to_le32(rate); |
209 | chip->sample_rate = rate; | 208 | chip->sample_rate = rate; |
@@ -279,7 +278,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
279 | clock = GML_8KHZ; | 278 | clock = GML_8KHZ; |
280 | break; | 279 | break; |
281 | default: | 280 | default: |
282 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | 281 | dev_err(chip->card->dev, |
282 | "set_sample_rate: %d invalid!\n", rate); | ||
283 | return -EINVAL; | 283 | return -EINVAL; |
284 | } | 284 | } |
285 | 285 | ||
@@ -287,7 +287,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) | |||
287 | 287 | ||
288 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | 288 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ |
289 | chip->sample_rate = rate; | 289 | chip->sample_rate = rate; |
290 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | 290 | dev_dbg(chip->card->dev, |
291 | "set_sample_rate: %d clock %d\n", rate, clock); | ||
291 | 292 | ||
292 | return write_control_reg(chip, control_reg, force_write); | 293 | return write_control_reg(chip, control_reg, force_write); |
293 | } | 294 | } |
@@ -299,7 +300,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
299 | u32 control_reg, clocks_from_dsp; | 300 | u32 control_reg, clocks_from_dsp; |
300 | int err; | 301 | int err; |
301 | 302 | ||
302 | DE_ACT(("set_input_clock:\n")); | ||
303 | 303 | ||
304 | /* Prevent two simultaneous calls to switch_asic() */ | 304 | /* Prevent two simultaneous calls to switch_asic() */ |
305 | if (atomic_read(&chip->opencount)) | 305 | if (atomic_read(&chip->opencount)) |
@@ -312,7 +312,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
312 | 312 | ||
313 | switch (clock) { | 313 | switch (clock) { |
314 | case ECHO_CLOCK_INTERNAL: | 314 | case ECHO_CLOCK_INTERNAL: |
315 | DE_ACT(("Set Mona clock to INTERNAL\n")); | ||
316 | chip->input_clock = ECHO_CLOCK_INTERNAL; | 315 | chip->input_clock = ECHO_CLOCK_INTERNAL; |
317 | return set_sample_rate(chip, chip->sample_rate); | 316 | return set_sample_rate(chip, chip->sample_rate); |
318 | case ECHO_CLOCK_SPDIF: | 317 | case ECHO_CLOCK_SPDIF: |
@@ -324,7 +323,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
324 | spin_lock_irq(&chip->lock); | 323 | spin_lock_irq(&chip->lock); |
325 | if (err < 0) | 324 | if (err < 0) |
326 | return err; | 325 | return err; |
327 | DE_ACT(("Set Mona clock to SPDIF\n")); | ||
328 | control_reg |= GML_SPDIF_CLOCK; | 326 | control_reg |= GML_SPDIF_CLOCK; |
329 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) | 327 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) |
330 | control_reg |= GML_DOUBLE_SPEED_MODE; | 328 | control_reg |= GML_DOUBLE_SPEED_MODE; |
@@ -332,7 +330,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
332 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 330 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
333 | break; | 331 | break; |
334 | case ECHO_CLOCK_WORD: | 332 | case ECHO_CLOCK_WORD: |
335 | DE_ACT(("Set Mona clock to WORD\n")); | ||
336 | spin_unlock_irq(&chip->lock); | 333 | spin_unlock_irq(&chip->lock); |
337 | err = switch_asic(chip, clocks_from_dsp & | 334 | err = switch_asic(chip, clocks_from_dsp & |
338 | GML_CLOCK_DETECT_BIT_WORD96); | 335 | GML_CLOCK_DETECT_BIT_WORD96); |
@@ -346,14 +343,15 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) | |||
346 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 343 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
347 | break; | 344 | break; |
348 | case ECHO_CLOCK_ADAT: | 345 | case ECHO_CLOCK_ADAT: |
349 | DE_ACT(("Set Mona clock to ADAT\n")); | 346 | dev_dbg(chip->card->dev, "Set Mona clock to ADAT\n"); |
350 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | 347 | if (chip->digital_mode != DIGITAL_MODE_ADAT) |
351 | return -EAGAIN; | 348 | return -EAGAIN; |
352 | control_reg |= GML_ADAT_CLOCK; | 349 | control_reg |= GML_ADAT_CLOCK; |
353 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | 350 | control_reg &= ~GML_DOUBLE_SPEED_MODE; |
354 | break; | 351 | break; |
355 | default: | 352 | default: |
356 | DE_ACT(("Input clock 0x%x not supported for Mona\n", clock)); | 353 | dev_err(chip->card->dev, |
354 | "Input clock 0x%x not supported for Mona\n", clock); | ||
357 | return -EINVAL; | 355 | return -EINVAL; |
358 | } | 356 | } |
359 | 357 | ||
@@ -381,7 +379,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
381 | incompatible_clock = TRUE; | 379 | incompatible_clock = TRUE; |
382 | break; | 380 | break; |
383 | default: | 381 | default: |
384 | DE_ACT(("Digital mode not supported: %d\n", mode)); | 382 | dev_err(chip->card->dev, |
383 | "Digital mode not supported: %d\n", mode); | ||
385 | return -EINVAL; | 384 | return -EINVAL; |
386 | } | 385 | } |
387 | 386 | ||
@@ -422,6 +421,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | |||
422 | return err; | 421 | return err; |
423 | chip->digital_mode = mode; | 422 | chip->digital_mode = mode; |
424 | 423 | ||
425 | DE_ACT(("set_digital_mode to %d\n", mode)); | 424 | dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode); |
426 | return incompatible_clock; | 425 | return incompatible_clock; |
427 | } | 426 | } |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 229269788023..b4458a630a7c 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -1289,10 +1289,8 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
1289 | } | 1289 | } |
1290 | if (emu->emu1010.firmware_thread) | 1290 | if (emu->emu1010.firmware_thread) |
1291 | kthread_stop(emu->emu1010.firmware_thread); | 1291 | kthread_stop(emu->emu1010.firmware_thread); |
1292 | if (emu->firmware) | 1292 | release_firmware(emu->firmware); |
1293 | release_firmware(emu->firmware); | 1293 | release_firmware(emu->dock_fw); |
1294 | if (emu->dock_fw) | ||
1295 | release_firmware(emu->dock_fw); | ||
1296 | if (emu->irq >= 0) | 1294 | if (emu->irq >= 0) |
1297 | free_irq(emu->irq, emu); | 1295 | free_irq(emu->irq, emu); |
1298 | /* remove reserved page */ | 1296 | /* remove reserved page */ |
@@ -1301,8 +1299,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
1301 | (struct snd_util_memblk *)emu->reserved_page); | 1299 | (struct snd_util_memblk *)emu->reserved_page); |
1302 | emu->reserved_page = NULL; | 1300 | emu->reserved_page = NULL; |
1303 | } | 1301 | } |
1304 | if (emu->memhdr) | 1302 | snd_util_memhdr_free(emu->memhdr); |
1305 | snd_util_memhdr_free(emu->memhdr); | ||
1306 | if (emu->silent_page.area) | 1303 | if (emu->silent_page.area) |
1307 | snd_dma_free_pages(&emu->silent_page); | 1304 | snd_dma_free_pages(&emu->silent_page); |
1308 | if (emu->ptb_pages.area) | 1305 | if (emu->ptb_pages.area) |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index e223de1408c0..15933f92f63a 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -180,7 +180,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard."); | |||
180 | 180 | ||
181 | /* From 0x50 - 0x5f, last samples captured */ | 181 | /* From 0x50 - 0x5f, last samples captured */ |
182 | 182 | ||
183 | /** | 183 | /* |
184 | * The hardware has 3 channels for playback and 1 for capture. | 184 | * The hardware has 3 channels for playback and 1 for capture. |
185 | * - channel 0 is the front channel | 185 | * - channel 0 is the front channel |
186 | * - channel 1 is the rear channel | 186 | * - channel 1 is the rear channel |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 745f0627c634..eb5c0aba41c1 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -777,8 +777,7 @@ static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl) | |||
777 | kctl->private_value = 0; | 777 | kctl->private_value = 0; |
778 | list_del(&ctl->list); | 778 | list_del(&ctl->list); |
779 | kfree(ctl); | 779 | kfree(ctl); |
780 | if (kctl->tlv.p) | 780 | kfree(kctl->tlv.p); |
781 | kfree(kctl->tlv.p); | ||
782 | } | 781 | } |
783 | 782 | ||
784 | static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, | 783 | static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index c5ae2a24d8a5..1de33025669a 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -83,7 +83,7 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, | |||
83 | * Items labels in enum mixer controls assigning source data to | 83 | * Items labels in enum mixer controls assigning source data to |
84 | * each destination | 84 | * each destination |
85 | */ | 85 | */ |
86 | static char *emu1010_src_texts[] = { | 86 | static const char * const emu1010_src_texts[] = { |
87 | "Silence", | 87 | "Silence", |
88 | "Dock Mic A", | 88 | "Dock Mic A", |
89 | "Dock Mic B", | 89 | "Dock Mic B", |
@@ -141,7 +141,7 @@ static char *emu1010_src_texts[] = { | |||
141 | 141 | ||
142 | /* 1616(m) cardbus */ | 142 | /* 1616(m) cardbus */ |
143 | 143 | ||
144 | static char *emu1616_src_texts[] = { | 144 | static const char * const emu1616_src_texts[] = { |
145 | "Silence", | 145 | "Silence", |
146 | "Dock Mic A", | 146 | "Dock Mic A", |
147 | "Dock Mic B", | 147 | "Dock Mic B", |
@@ -393,23 +393,11 @@ static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, | |||
393 | struct snd_ctl_elem_info *uinfo) | 393 | struct snd_ctl_elem_info *uinfo) |
394 | { | 394 | { |
395 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 395 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
396 | char **items; | ||
397 | 396 | ||
398 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 397 | if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) |
399 | uinfo->count = 1; | 398 | return snd_ctl_enum_info(uinfo, 1, 49, emu1616_src_texts); |
400 | if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) { | 399 | else |
401 | uinfo->value.enumerated.items = 49; | 400 | return snd_ctl_enum_info(uinfo, 1, 53, emu1010_src_texts); |
402 | items = emu1616_src_texts; | ||
403 | } else { | ||
404 | uinfo->value.enumerated.items = 53; | ||
405 | items = emu1010_src_texts; | ||
406 | } | ||
407 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
408 | uinfo->value.enumerated.item = | ||
409 | uinfo->value.enumerated.items - 1; | ||
410 | strcpy(uinfo->value.enumerated.name, | ||
411 | items[uinfo->value.enumerated.item]); | ||
412 | return 0; | ||
413 | } | 401 | } |
414 | 402 | ||
415 | static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, | 403 | static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, |
@@ -699,19 +687,11 @@ static struct snd_kcontrol_new snd_emu1010_dac_pads[] = { | |||
699 | static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol, | 687 | static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol, |
700 | struct snd_ctl_elem_info *uinfo) | 688 | struct snd_ctl_elem_info *uinfo) |
701 | { | 689 | { |
702 | static char *texts[4] = { | 690 | static const char * const texts[4] = { |
703 | "44100", "48000", "SPDIF", "ADAT" | 691 | "44100", "48000", "SPDIF", "ADAT" |
704 | }; | 692 | }; |
705 | 693 | ||
706 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 694 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
707 | uinfo->count = 1; | ||
708 | uinfo->value.enumerated.items = 4; | ||
709 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
710 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
711 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
712 | return 0; | ||
713 | |||
714 | |||
715 | } | 695 | } |
716 | 696 | ||
717 | static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol, | 697 | static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol, |
@@ -830,21 +810,15 @@ static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol, | |||
830 | struct snd_ctl_elem_info *uinfo) | 810 | struct snd_ctl_elem_info *uinfo) |
831 | { | 811 | { |
832 | #if 0 | 812 | #if 0 |
833 | static char *texts[4] = { | 813 | static const char * const texts[4] = { |
834 | "Unknown1", "Unknown2", "Mic", "Line" | 814 | "Unknown1", "Unknown2", "Mic", "Line" |
835 | }; | 815 | }; |
836 | #endif | 816 | #endif |
837 | static char *texts[2] = { | 817 | static const char * const texts[2] = { |
838 | "Mic", "Line" | 818 | "Mic", "Line" |
839 | }; | 819 | }; |
840 | 820 | ||
841 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 821 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
842 | uinfo->count = 1; | ||
843 | uinfo->value.enumerated.items = 2; | ||
844 | if (uinfo->value.enumerated.item > 1) | ||
845 | uinfo->value.enumerated.item = 1; | ||
846 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
847 | return 0; | ||
848 | } | 822 | } |
849 | 823 | ||
850 | static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol, | 824 | static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol, |
@@ -997,15 +971,9 @@ static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] = { | |||
997 | #if 0 | 971 | #if 0 |
998 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 972 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
999 | { | 973 | { |
1000 | static char *texts[] = {"44100", "48000", "96000"}; | 974 | static const char * const texts[] = {"44100", "48000", "96000"}; |
1001 | 975 | ||
1002 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 976 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
1003 | uinfo->count = 1; | ||
1004 | uinfo->value.enumerated.items = 3; | ||
1005 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1006 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1007 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1008 | return 0; | ||
1009 | } | 977 | } |
1010 | 978 | ||
1011 | static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol, | 979 | static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index a4fe7f0c9458..7ef3898a7806 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -757,18 +757,12 @@ static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol, | |||
757 | static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol, | 757 | static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol, |
758 | struct snd_ctl_elem_info *uinfo) | 758 | struct snd_ctl_elem_info *uinfo) |
759 | { | 759 | { |
760 | static char *texts[8] = { | 760 | static const char * const texts[8] = { |
761 | "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", | 761 | "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", |
762 | "CDIF", "FX", "AC97" | 762 | "CDIF", "FX", "AC97" |
763 | }; | 763 | }; |
764 | 764 | ||
765 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 765 | return snd_ctl_enum_info(uinfo, 1, 8, texts); |
766 | uinfo->count = 1; | ||
767 | uinfo->value.enumerated.items = 8; | ||
768 | if (uinfo->value.enumerated.item > 7) | ||
769 | uinfo->value.enumerated.item = 7; | ||
770 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
771 | return 0; | ||
772 | } | 766 | } |
773 | 767 | ||
774 | static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol, | 768 | static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol, |
@@ -805,15 +799,9 @@ static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol, | |||
805 | static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol, | 799 | static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol, |
806 | struct snd_ctl_elem_info *uinfo) | 800 | struct snd_ctl_elem_info *uinfo) |
807 | { | 801 | { |
808 | static char *texts[4] = { "0", "1", "2", "3", }; | 802 | static const char * const texts[4] = { "0", "1", "2", "3", }; |
809 | 803 | ||
810 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 804 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
811 | uinfo->count = 1; | ||
812 | uinfo->value.enumerated.items = 4; | ||
813 | if (uinfo->value.enumerated.item > 3) | ||
814 | uinfo->value.enumerated.item = 3; | ||
815 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
816 | return 0; | ||
817 | } | 805 | } |
818 | 806 | ||
819 | static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol, | 807 | static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 639962443ccc..0fc46eb4e251 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -1045,18 +1045,12 @@ static int snd_es1938_new_pcm(struct es1938 *chip, int device) | |||
1045 | static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol, | 1045 | static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol, |
1046 | struct snd_ctl_elem_info *uinfo) | 1046 | struct snd_ctl_elem_info *uinfo) |
1047 | { | 1047 | { |
1048 | static char *texts[8] = { | 1048 | static const char * const texts[8] = { |
1049 | "Mic", "Mic Master", "CD", "AOUT", | 1049 | "Mic", "Mic Master", "CD", "AOUT", |
1050 | "Mic1", "Mix", "Line", "Master" | 1050 | "Mic1", "Mix", "Line", "Master" |
1051 | }; | 1051 | }; |
1052 | 1052 | ||
1053 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1053 | return snd_ctl_enum_info(uinfo, 1, 8, texts); |
1054 | uinfo->count = 1; | ||
1055 | uinfo->value.enumerated.items = 8; | ||
1056 | if (uinfo->value.enumerated.item > 7) | ||
1057 | uinfo->value.enumerated.item = 7; | ||
1058 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1059 | return 0; | ||
1060 | } | 1054 | } |
1061 | 1055 | ||
1062 | static int snd_es1938_get_mux(struct snd_kcontrol *kcontrol, | 1056 | static int snd_es1938_get_mux(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index a9956a7c5677..6039700f8579 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -1710,7 +1710,8 @@ static void es1968_measure_clock(struct es1968 *chip) | |||
1710 | int i, apu; | 1710 | int i, apu; |
1711 | unsigned int pa, offset, t; | 1711 | unsigned int pa, offset, t; |
1712 | struct esm_memory *memory; | 1712 | struct esm_memory *memory; |
1713 | struct timeval start_time, stop_time; | 1713 | ktime_t start_time, stop_time; |
1714 | ktime_t diff; | ||
1714 | 1715 | ||
1715 | if (chip->clock == 0) | 1716 | if (chip->clock == 0) |
1716 | chip->clock = 48000; /* default clock value */ | 1717 | chip->clock = 48000; /* default clock value */ |
@@ -1761,12 +1762,12 @@ static void es1968_measure_clock(struct es1968 *chip) | |||
1761 | snd_es1968_bob_inc(chip, ESM_BOB_FREQ); | 1762 | snd_es1968_bob_inc(chip, ESM_BOB_FREQ); |
1762 | __apu_set_register(chip, apu, 5, pa & 0xffff); | 1763 | __apu_set_register(chip, apu, 5, pa & 0xffff); |
1763 | snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); | 1764 | snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); |
1764 | do_gettimeofday(&start_time); | 1765 | start_time = ktime_get(); |
1765 | spin_unlock_irq(&chip->reg_lock); | 1766 | spin_unlock_irq(&chip->reg_lock); |
1766 | msleep(50); | 1767 | msleep(50); |
1767 | spin_lock_irq(&chip->reg_lock); | 1768 | spin_lock_irq(&chip->reg_lock); |
1768 | offset = __apu_get_register(chip, apu, 5); | 1769 | offset = __apu_get_register(chip, apu, 5); |
1769 | do_gettimeofday(&stop_time); | 1770 | stop_time = ktime_get(); |
1770 | snd_es1968_trigger_apu(chip, apu, 0); /* stop */ | 1771 | snd_es1968_trigger_apu(chip, apu, 0); /* stop */ |
1771 | snd_es1968_bob_dec(chip); | 1772 | snd_es1968_bob_dec(chip); |
1772 | chip->in_measurement = 0; | 1773 | chip->in_measurement = 0; |
@@ -1777,12 +1778,8 @@ static void es1968_measure_clock(struct es1968 *chip) | |||
1777 | offset &= 0xfffe; | 1778 | offset &= 0xfffe; |
1778 | offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2); | 1779 | offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2); |
1779 | 1780 | ||
1780 | t = stop_time.tv_sec - start_time.tv_sec; | 1781 | diff = ktime_sub(stop_time, start_time); |
1781 | t *= 1000000; | 1782 | t = ktime_to_us(diff); |
1782 | if (stop_time.tv_usec < start_time.tv_usec) | ||
1783 | t -= start_time.tv_usec - stop_time.tv_usec; | ||
1784 | else | ||
1785 | t += stop_time.tv_usec - start_time.tv_usec; | ||
1786 | if (t == 0) { | 1783 | if (t == 0) { |
1787 | dev_err(chip->card->dev, "?? calculation error..\n"); | 1784 | dev_err(chip->card->dev, "?? calculation error..\n"); |
1788 | } else { | 1785 | } else { |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c5038303a126..d167afffce5f 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -958,17 +958,11 @@ static int snd_fm801_put_double(struct snd_kcontrol *kcontrol, | |||
958 | static int snd_fm801_info_mux(struct snd_kcontrol *kcontrol, | 958 | static int snd_fm801_info_mux(struct snd_kcontrol *kcontrol, |
959 | struct snd_ctl_elem_info *uinfo) | 959 | struct snd_ctl_elem_info *uinfo) |
960 | { | 960 | { |
961 | static char *texts[5] = { | 961 | static const char * const texts[5] = { |
962 | "AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary" | 962 | "AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary" |
963 | }; | 963 | }; |
964 | 964 | ||
965 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 965 | return snd_ctl_enum_info(uinfo, 1, 5, texts); |
966 | uinfo->count = 1; | ||
967 | uinfo->value.enumerated.items = 5; | ||
968 | if (uinfo->value.enumerated.item > 4) | ||
969 | uinfo->value.enumerated.item = 4; | ||
970 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
971 | return 0; | ||
972 | } | 966 | } |
973 | 967 | ||
974 | static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol, | 968 | static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index fcc5e478c9a1..1ede82200ee5 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -441,6 +441,13 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
441 | } | 441 | } |
442 | EXPORT_SYMBOL_GPL(snd_hda_parse_pin_defcfg); | 442 | EXPORT_SYMBOL_GPL(snd_hda_parse_pin_defcfg); |
443 | 443 | ||
444 | /** | ||
445 | * snd_hda_get_input_pin_attr - Get the input pin attribute from pin config | ||
446 | * @def_conf: pin configuration value | ||
447 | * | ||
448 | * Guess the input pin attribute (INPUT_PIN_ATTR_XXX) from the given | ||
449 | * default pin configuration value. | ||
450 | */ | ||
444 | int snd_hda_get_input_pin_attr(unsigned int def_conf) | 451 | int snd_hda_get_input_pin_attr(unsigned int def_conf) |
445 | { | 452 | { |
446 | unsigned int loc = get_defcfg_location(def_conf); | 453 | unsigned int loc = get_defcfg_location(def_conf); |
@@ -464,12 +471,15 @@ EXPORT_SYMBOL_GPL(snd_hda_get_input_pin_attr); | |||
464 | 471 | ||
465 | /** | 472 | /** |
466 | * hda_get_input_pin_label - Give a label for the given input pin | 473 | * hda_get_input_pin_label - Give a label for the given input pin |
474 | * @codec: the HDA codec | ||
475 | * @item: ping config item to refer | ||
476 | * @pin: the pin NID | ||
477 | * @check_location: flag to add the jack location prefix | ||
467 | * | 478 | * |
468 | * When check_location is true, the function checks the pin location | 479 | * When @check_location is true, the function checks the pin location |
469 | * for mic and line-in pins, and set an appropriate prefix like "Front", | 480 | * for mic and line-in pins, and set an appropriate prefix like "Front", |
470 | * "Rear", "Internal". | 481 | * "Rear", "Internal". |
471 | */ | 482 | */ |
472 | |||
473 | static const char *hda_get_input_pin_label(struct hda_codec *codec, | 483 | static const char *hda_get_input_pin_label(struct hda_codec *codec, |
474 | const struct auto_pin_cfg_item *item, | 484 | const struct auto_pin_cfg_item *item, |
475 | hda_nid_t pin, bool check_location) | 485 | hda_nid_t pin, bool check_location) |
@@ -550,6 +560,9 @@ static int check_mic_location_need(struct hda_codec *codec, | |||
550 | 560 | ||
551 | /** | 561 | /** |
552 | * hda_get_autocfg_input_label - Get a label for the given input | 562 | * hda_get_autocfg_input_label - Get a label for the given input |
563 | * @codec: the HDA codec | ||
564 | * @cfg: the parsed pin configuration | ||
565 | * @input: the input index number | ||
553 | * | 566 | * |
554 | * Get a label for the given input pin defined by the autocfg item. | 567 | * Get a label for the given input pin defined by the autocfg item. |
555 | * Unlike hda_get_input_pin_label(), this function checks all inputs | 568 | * Unlike hda_get_input_pin_label(), this function checks all inputs |
@@ -677,6 +690,12 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | |||
677 | 690 | ||
678 | /** | 691 | /** |
679 | * snd_hda_get_pin_label - Get a label for the given I/O pin | 692 | * snd_hda_get_pin_label - Get a label for the given I/O pin |
693 | * @codec: the HDA codec | ||
694 | * @nid: pin NID | ||
695 | * @cfg: the parsed pin configuration | ||
696 | * @label: the string buffer to store | ||
697 | * @maxlen: the max length of string buffer (including termination) | ||
698 | * @indexp: the pointer to return the index number (for multiple ctls) | ||
680 | * | 699 | * |
681 | * Get a label for the given pin. This function works for both input and | 700 | * Get a label for the given pin. This function works for both input and |
682 | * output pins. When @cfg is given as non-NULL, the function tries to get | 701 | * output pins. When @cfg is given as non-NULL, the function tries to get |
@@ -748,6 +767,14 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | |||
748 | } | 767 | } |
749 | EXPORT_SYMBOL_GPL(snd_hda_get_pin_label); | 768 | EXPORT_SYMBOL_GPL(snd_hda_get_pin_label); |
750 | 769 | ||
770 | /** | ||
771 | * snd_hda_add_verbs - Add verbs to the init list | ||
772 | * @codec: the HDA codec | ||
773 | * @list: zero-terminated verb list to add | ||
774 | * | ||
775 | * Append the given verb list to the execution list. The verbs will be | ||
776 | * performed at init and resume time via snd_hda_apply_verbs(). | ||
777 | */ | ||
751 | int snd_hda_add_verbs(struct hda_codec *codec, | 778 | int snd_hda_add_verbs(struct hda_codec *codec, |
752 | const struct hda_verb *list) | 779 | const struct hda_verb *list) |
753 | { | 780 | { |
@@ -760,6 +787,10 @@ int snd_hda_add_verbs(struct hda_codec *codec, | |||
760 | } | 787 | } |
761 | EXPORT_SYMBOL_GPL(snd_hda_add_verbs); | 788 | EXPORT_SYMBOL_GPL(snd_hda_add_verbs); |
762 | 789 | ||
790 | /** | ||
791 | * snd_hda_apply_verbs - Execute the init verb lists | ||
792 | * @codec: the HDA codec | ||
793 | */ | ||
763 | void snd_hda_apply_verbs(struct hda_codec *codec) | 794 | void snd_hda_apply_verbs(struct hda_codec *codec) |
764 | { | 795 | { |
765 | int i; | 796 | int i; |
@@ -770,6 +801,11 @@ void snd_hda_apply_verbs(struct hda_codec *codec) | |||
770 | } | 801 | } |
771 | EXPORT_SYMBOL_GPL(snd_hda_apply_verbs); | 802 | EXPORT_SYMBOL_GPL(snd_hda_apply_verbs); |
772 | 803 | ||
804 | /** | ||
805 | * snd_hda_apply_pincfgs - Set each pin config in the given list | ||
806 | * @codec: the HDA codec | ||
807 | * @cfg: NULL-terminated pin config table | ||
808 | */ | ||
773 | void snd_hda_apply_pincfgs(struct hda_codec *codec, | 809 | void snd_hda_apply_pincfgs(struct hda_codec *codec, |
774 | const struct hda_pintbl *cfg) | 810 | const struct hda_pintbl *cfg) |
775 | { | 811 | { |
@@ -837,6 +873,11 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth) | |||
837 | } | 873 | } |
838 | } | 874 | } |
839 | 875 | ||
876 | /** | ||
877 | * snd_hda_apply_fixup - Apply the fixup chain with the given action | ||
878 | * @codec: the HDA codec | ||
879 | * @action: fixup action (HDA_FIXUP_ACT_XXX) | ||
880 | */ | ||
840 | void snd_hda_apply_fixup(struct hda_codec *codec, int action) | 881 | void snd_hda_apply_fixup(struct hda_codec *codec, int action) |
841 | { | 882 | { |
842 | if (codec->fixup_list) | 883 | if (codec->fixup_list) |
@@ -855,6 +896,12 @@ static bool pin_config_match(struct hda_codec *codec, | |||
855 | return true; | 896 | return true; |
856 | } | 897 | } |
857 | 898 | ||
899 | /** | ||
900 | * snd_hda_pick_pin_fixup - Pick up a fixup matching with the pin quirk list | ||
901 | * @codec: the HDA codec | ||
902 | * @pin_quirk: zero-terminated pin quirk list | ||
903 | * @fixlist: the fixup list | ||
904 | */ | ||
858 | void snd_hda_pick_pin_fixup(struct hda_codec *codec, | 905 | void snd_hda_pick_pin_fixup(struct hda_codec *codec, |
859 | const struct snd_hda_pin_quirk *pin_quirk, | 906 | const struct snd_hda_pin_quirk *pin_quirk, |
860 | const struct hda_fixup *fixlist) | 907 | const struct hda_fixup *fixlist) |
@@ -881,6 +928,21 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec, | |||
881 | } | 928 | } |
882 | EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup); | 929 | EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup); |
883 | 930 | ||
931 | /** | ||
932 | * snd_hda_pick_fixup - Pick up a fixup matching with PCI/codec SSID or model string | ||
933 | * @codec: the HDA codec | ||
934 | * @models: NULL-terminated model string list | ||
935 | * @quirk: zero-terminated PCI/codec SSID quirk list | ||
936 | * @fixlist: the fixup list | ||
937 | * | ||
938 | * Pick up a fixup entry matching with the given model string or SSID. | ||
939 | * If a fixup was already set beforehand, the function doesn't do anything. | ||
940 | * When a special model string "nofixup" is given, also no fixup is applied. | ||
941 | * | ||
942 | * The function tries to find the matching model name at first, if given. | ||
943 | * If nothing matched, try to look up the PCI SSID. | ||
944 | * If still nothing matched, try to look up the codec SSID. | ||
945 | */ | ||
884 | void snd_hda_pick_fixup(struct hda_codec *codec, | 946 | void snd_hda_pick_fixup(struct hda_codec *codec, |
885 | const struct hda_model_fixup *models, | 947 | const struct hda_model_fixup *models, |
886 | const struct snd_pci_quirk *quirk, | 948 | const struct snd_pci_quirk *quirk, |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 8c6c50afc0b7..1e7de08e77cb 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -175,6 +175,11 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | /** | ||
179 | * snd_hda_enable_beep_device - Turn on/off beep sound | ||
180 | * @codec: the HDA codec | ||
181 | * @enable: flag to turn on/off | ||
182 | */ | ||
178 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | 183 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) |
179 | { | 184 | { |
180 | struct hda_beep *beep = codec->beep; | 185 | struct hda_beep *beep = codec->beep; |
@@ -191,6 +196,20 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | |||
191 | } | 196 | } |
192 | EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device); | 197 | EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device); |
193 | 198 | ||
199 | /** | ||
200 | * snd_hda_attach_beep_device - Attach a beep input device | ||
201 | * @codec: the HDA codec | ||
202 | * @nid: beep NID | ||
203 | * | ||
204 | * Attach a beep object to the given widget. If beep hint is turned off | ||
205 | * explicitly or beep_mode of the codec is turned off, this doesn't nothing. | ||
206 | * | ||
207 | * The attached beep device has to be registered via | ||
208 | * snd_hda_register_beep_device() and released via snd_hda_detach_beep_device() | ||
209 | * appropriately. | ||
210 | * | ||
211 | * Currently, only one beep device is allowed to each codec. | ||
212 | */ | ||
194 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | 213 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) |
195 | { | 214 | { |
196 | struct hda_beep *beep; | 215 | struct hda_beep *beep; |
@@ -228,6 +247,10 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
228 | } | 247 | } |
229 | EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device); | 248 | EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device); |
230 | 249 | ||
250 | /** | ||
251 | * snd_hda_detach_beep_device - Detach the beep device | ||
252 | * @codec: the HDA codec | ||
253 | */ | ||
231 | void snd_hda_detach_beep_device(struct hda_codec *codec) | 254 | void snd_hda_detach_beep_device(struct hda_codec *codec) |
232 | { | 255 | { |
233 | struct hda_beep *beep = codec->beep; | 256 | struct hda_beep *beep = codec->beep; |
@@ -240,6 +263,10 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
240 | } | 263 | } |
241 | EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device); | 264 | EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device); |
242 | 265 | ||
266 | /** | ||
267 | * snd_hda_register_beep_device - Register the beep device | ||
268 | * @codec: the HDA codec | ||
269 | */ | ||
243 | int snd_hda_register_beep_device(struct hda_codec *codec) | 270 | int snd_hda_register_beep_device(struct hda_codec *codec) |
244 | { | 271 | { |
245 | struct hda_beep *beep = codec->beep; | 272 | struct hda_beep *beep = codec->beep; |
@@ -269,6 +296,12 @@ static bool ctl_has_mute(struct snd_kcontrol *kcontrol) | |||
269 | } | 296 | } |
270 | 297 | ||
271 | /* get/put callbacks for beep mute mixer switches */ | 298 | /* get/put callbacks for beep mute mixer switches */ |
299 | |||
300 | /** | ||
301 | * snd_hda_mixer_amp_switch_get_beep - Get callback for beep controls | ||
302 | * @kcontrol: ctl element | ||
303 | * @ucontrol: pointer to get/store the data | ||
304 | */ | ||
272 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | 305 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, |
273 | struct snd_ctl_elem_value *ucontrol) | 306 | struct snd_ctl_elem_value *ucontrol) |
274 | { | 307 | { |
@@ -283,6 +316,11 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | |||
283 | } | 316 | } |
284 | EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get_beep); | 317 | EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get_beep); |
285 | 318 | ||
319 | /** | ||
320 | * snd_hda_mixer_amp_switch_put_beep - Put callback for beep controls | ||
321 | * @kcontrol: ctl element | ||
322 | * @ucontrol: pointer to get/store the data | ||
323 | */ | ||
286 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | 324 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, |
287 | struct snd_ctl_elem_value *ucontrol) | 325 | struct snd_ctl_elem_value *ucontrol) |
288 | { | 326 | { |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 15e0089492f7..2fe86d2e1b09 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -77,6 +77,10 @@ static struct hda_vendor_id hda_vendor_ids[] = { | |||
77 | static DEFINE_MUTEX(preset_mutex); | 77 | static DEFINE_MUTEX(preset_mutex); |
78 | static LIST_HEAD(hda_preset_tables); | 78 | static LIST_HEAD(hda_preset_tables); |
79 | 79 | ||
80 | /** | ||
81 | * snd_hda_add_codec_preset - Add a codec preset to the chain | ||
82 | * @preset: codec preset table to add | ||
83 | */ | ||
80 | int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) | 84 | int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) |
81 | { | 85 | { |
82 | mutex_lock(&preset_mutex); | 86 | mutex_lock(&preset_mutex); |
@@ -86,6 +90,10 @@ int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) | |||
86 | } | 90 | } |
87 | EXPORT_SYMBOL_GPL(snd_hda_add_codec_preset); | 91 | EXPORT_SYMBOL_GPL(snd_hda_add_codec_preset); |
88 | 92 | ||
93 | /** | ||
94 | * snd_hda_delete_codec_preset - Delete a codec preset from the chain | ||
95 | * @preset: codec preset table to delete | ||
96 | */ | ||
89 | int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) | 97 | int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) |
90 | { | 98 | { |
91 | mutex_lock(&preset_mutex); | 99 | mutex_lock(&preset_mutex); |
@@ -338,8 +346,10 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, | |||
338 | unsigned int parm; | 346 | unsigned int parm; |
339 | 347 | ||
340 | parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT); | 348 | parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT); |
341 | if (parm == -1) | 349 | if (parm == -1) { |
350 | *start_id = 0; | ||
342 | return 0; | 351 | return 0; |
352 | } | ||
343 | *start_id = (parm >> 16) & 0x7fff; | 353 | *start_id = (parm >> 16) & 0x7fff; |
344 | return (int)(parm & 0x7fff); | 354 | return (int)(parm & 0x7fff); |
345 | } | 355 | } |
@@ -416,7 +426,6 @@ static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) | |||
416 | * snd_hda_get_conn_list - get connection list | 426 | * snd_hda_get_conn_list - get connection list |
417 | * @codec: the HDA codec | 427 | * @codec: the HDA codec |
418 | * @nid: NID to parse | 428 | * @nid: NID to parse |
419 | * @len: number of connection list entries | ||
420 | * @listp: the pointer to store NID list | 429 | * @listp: the pointer to store NID list |
421 | * | 430 | * |
422 | * Parses the connection list of the given widget and stores the pointer | 431 | * Parses the connection list of the given widget and stores the pointer |
@@ -827,8 +836,7 @@ static void snd_hda_bus_free(struct hda_bus *bus) | |||
827 | WARN_ON(!list_empty(&bus->codec_list)); | 836 | WARN_ON(!list_empty(&bus->codec_list)); |
828 | if (bus->workq) | 837 | if (bus->workq) |
829 | flush_workqueue(bus->workq); | 838 | flush_workqueue(bus->workq); |
830 | if (bus->unsol) | 839 | kfree(bus->unsol); |
831 | kfree(bus->unsol); | ||
832 | if (bus->ops.private_free) | 840 | if (bus->ops.private_free) |
833 | bus->ops.private_free(bus); | 841 | bus->ops.private_free(bus); |
834 | if (bus->workq) | 842 | if (bus->workq) |
@@ -966,14 +974,12 @@ find_codec_preset(struct hda_codec *codec) | |||
966 | mutex_unlock(&preset_mutex); | 974 | mutex_unlock(&preset_mutex); |
967 | 975 | ||
968 | if (mod_requested < HDA_MODREQ_MAX_COUNT) { | 976 | if (mod_requested < HDA_MODREQ_MAX_COUNT) { |
969 | char name[32]; | ||
970 | if (!mod_requested) | 977 | if (!mod_requested) |
971 | snprintf(name, sizeof(name), "snd-hda-codec-id:%08x", | 978 | request_module("snd-hda-codec-id:%08x", |
972 | codec->vendor_id); | 979 | codec->vendor_id); |
973 | else | 980 | else |
974 | snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*", | 981 | request_module("snd-hda-codec-id:%04x*", |
975 | (codec->vendor_id >> 16) & 0xffff); | 982 | (codec->vendor_id >> 16) & 0xffff); |
976 | request_module(name); | ||
977 | mod_requested++; | 983 | mod_requested++; |
978 | goto again; | 984 | goto again; |
979 | } | 985 | } |
@@ -1190,7 +1196,16 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid) | |||
1190 | } | 1196 | } |
1191 | EXPORT_SYMBOL_GPL(snd_hda_codec_get_pincfg); | 1197 | EXPORT_SYMBOL_GPL(snd_hda_codec_get_pincfg); |
1192 | 1198 | ||
1193 | /* remember the current pinctl target value */ | 1199 | /** |
1200 | * snd_hda_codec_set_pin_target - remember the current pinctl target value | ||
1201 | * @codec: the HDA codec | ||
1202 | * @nid: pin NID | ||
1203 | * @val: assigned pinctl value | ||
1204 | * | ||
1205 | * This function stores the given value to a pinctl target value in the | ||
1206 | * pincfg table. This isn't always as same as the actually written value | ||
1207 | * but can be referred at any time via snd_hda_codec_get_pin_target(). | ||
1208 | */ | ||
1194 | int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, | 1209 | int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, |
1195 | unsigned int val) | 1210 | unsigned int val) |
1196 | { | 1211 | { |
@@ -1204,7 +1219,11 @@ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, | |||
1204 | } | 1219 | } |
1205 | EXPORT_SYMBOL_GPL(snd_hda_codec_set_pin_target); | 1220 | EXPORT_SYMBOL_GPL(snd_hda_codec_set_pin_target); |
1206 | 1221 | ||
1207 | /* return the current pinctl target value */ | 1222 | /** |
1223 | * snd_hda_codec_get_pin_target - return the current pinctl target value | ||
1224 | * @codec: the HDA codec | ||
1225 | * @nid: pin NID | ||
1226 | */ | ||
1208 | int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid) | 1227 | int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid) |
1209 | { | 1228 | { |
1210 | struct hda_pincfg *pin; | 1229 | struct hda_pincfg *pin; |
@@ -1576,6 +1595,13 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1576 | } | 1595 | } |
1577 | EXPORT_SYMBOL_GPL(snd_hda_codec_new); | 1596 | EXPORT_SYMBOL_GPL(snd_hda_codec_new); |
1578 | 1597 | ||
1598 | /** | ||
1599 | * snd_hda_codec_update_widgets - Refresh widget caps and pin defaults | ||
1600 | * @codec: the HDA codec | ||
1601 | * | ||
1602 | * Forcibly refresh the all widget caps and the init pin configurations of | ||
1603 | * the given codec. | ||
1604 | */ | ||
1579 | int snd_hda_codec_update_widgets(struct hda_codec *codec) | 1605 | int snd_hda_codec_update_widgets(struct hda_codec *codec) |
1580 | { | 1606 | { |
1581 | hda_nid_t fg; | 1607 | hda_nid_t fg; |
@@ -2006,6 +2032,7 @@ EXPORT_SYMBOL_GPL(query_amp_caps); | |||
2006 | * @codec: the HD-audio codec | 2032 | * @codec: the HD-audio codec |
2007 | * @nid: the NID to query | 2033 | * @nid: the NID to query |
2008 | * @dir: either #HDA_INPUT or #HDA_OUTPUT | 2034 | * @dir: either #HDA_INPUT or #HDA_OUTPUT |
2035 | * @bits: bit mask to check the result | ||
2009 | * | 2036 | * |
2010 | * Check whether the widget has the given amp capability for the direction. | 2037 | * Check whether the widget has the given amp capability for the direction. |
2011 | */ | 2038 | */ |
@@ -2025,7 +2052,7 @@ EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps); | |||
2025 | * snd_hda_override_amp_caps - Override the AMP capabilities | 2052 | * snd_hda_override_amp_caps - Override the AMP capabilities |
2026 | * @codec: the CODEC to clean up | 2053 | * @codec: the CODEC to clean up |
2027 | * @nid: the NID to clean up | 2054 | * @nid: the NID to clean up |
2028 | * @direction: either #HDA_INPUT or #HDA_OUTPUT | 2055 | * @dir: either #HDA_INPUT or #HDA_OUTPUT |
2029 | * @caps: the capability bits to set | 2056 | * @caps: the capability bits to set |
2030 | * | 2057 | * |
2031 | * Override the cached AMP caps bits value by the given one. | 2058 | * Override the cached AMP caps bits value by the given one. |
@@ -2241,7 +2268,17 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | |||
2241 | } | 2268 | } |
2242 | EXPORT_SYMBOL_GPL(snd_hda_codec_amp_stereo); | 2269 | EXPORT_SYMBOL_GPL(snd_hda_codec_amp_stereo); |
2243 | 2270 | ||
2244 | /* Works like snd_hda_codec_amp_update() but it writes the value only at | 2271 | /** |
2272 | * snd_hda_codec_amp_init - initialize the AMP value | ||
2273 | * @codec: the HDA codec | ||
2274 | * @nid: NID to read the AMP value | ||
2275 | * @ch: channel (left=0 or right=1) | ||
2276 | * @dir: #HDA_INPUT or #HDA_OUTPUT | ||
2277 | * @idx: the index value (only for input direction) | ||
2278 | * @mask: bit mask to set | ||
2279 | * @val: the bits value to set | ||
2280 | * | ||
2281 | * Works like snd_hda_codec_amp_update() but it writes the value only at | ||
2245 | * the first access. If the amp was already initialized / updated beforehand, | 2282 | * the first access. If the amp was already initialized / updated beforehand, |
2246 | * this does nothing. | 2283 | * this does nothing. |
2247 | */ | 2284 | */ |
@@ -2252,6 +2289,17 @@ int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
2252 | } | 2289 | } |
2253 | EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init); | 2290 | EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init); |
2254 | 2291 | ||
2292 | /** | ||
2293 | * snd_hda_codec_amp_init_stereo - initialize the stereo AMP value | ||
2294 | * @codec: the HDA codec | ||
2295 | * @nid: NID to read the AMP value | ||
2296 | * @dir: #HDA_INPUT or #HDA_OUTPUT | ||
2297 | * @idx: the index value (only for input direction) | ||
2298 | * @mask: bit mask to set | ||
2299 | * @val: the bits value to set | ||
2300 | * | ||
2301 | * Call snd_hda_codec_amp_init() for both stereo channels. | ||
2302 | */ | ||
2255 | int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, | 2303 | int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, |
2256 | int dir, int idx, int mask, int val) | 2304 | int dir, int idx, int mask, int val) |
2257 | { | 2305 | { |
@@ -2322,6 +2370,8 @@ static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
2322 | 2370 | ||
2323 | /** | 2371 | /** |
2324 | * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer | 2372 | * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer |
2373 | * @kcontrol: referred ctl element | ||
2374 | * @uinfo: pointer to get/store the data | ||
2325 | * | 2375 | * |
2326 | * The control element is supposed to have the private_value field | 2376 | * The control element is supposed to have the private_value field |
2327 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 2377 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -2383,6 +2433,8 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid, | |||
2383 | 2433 | ||
2384 | /** | 2434 | /** |
2385 | * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume | 2435 | * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume |
2436 | * @kcontrol: ctl element | ||
2437 | * @ucontrol: pointer to get/store the data | ||
2386 | * | 2438 | * |
2387 | * The control element is supposed to have the private_value field | 2439 | * The control element is supposed to have the private_value field |
2388 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 2440 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -2408,6 +2460,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_get); | |||
2408 | 2460 | ||
2409 | /** | 2461 | /** |
2410 | * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume | 2462 | * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume |
2463 | * @kcontrol: ctl element | ||
2464 | * @ucontrol: pointer to get/store the data | ||
2411 | * | 2465 | * |
2412 | * The control element is supposed to have the private_value field | 2466 | * The control element is supposed to have the private_value field |
2413 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 2467 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -2438,6 +2492,10 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put); | |||
2438 | 2492 | ||
2439 | /** | 2493 | /** |
2440 | * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume | 2494 | * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume |
2495 | * @kcontrol: ctl element | ||
2496 | * @op_flag: operation flag | ||
2497 | * @size: byte size of input TLV | ||
2498 | * @_tlv: TLV data | ||
2441 | * | 2499 | * |
2442 | * The control element is supposed to have the private_value field | 2500 | * The control element is supposed to have the private_value field |
2443 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 2501 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -2636,7 +2694,10 @@ void snd_hda_ctls_clear(struct hda_codec *codec) | |||
2636 | snd_array_free(&codec->nids); | 2694 | snd_array_free(&codec->nids); |
2637 | } | 2695 | } |
2638 | 2696 | ||
2639 | /* pseudo device locking | 2697 | /** |
2698 | * snd_hda_lock_devices - pseudo device locking | ||
2699 | * @bus: the BUS | ||
2700 | * | ||
2640 | * toggle card->shutdown to allow/disallow the device access (as a hack) | 2701 | * toggle card->shutdown to allow/disallow the device access (as a hack) |
2641 | */ | 2702 | */ |
2642 | int snd_hda_lock_devices(struct hda_bus *bus) | 2703 | int snd_hda_lock_devices(struct hda_bus *bus) |
@@ -2673,6 +2734,10 @@ int snd_hda_lock_devices(struct hda_bus *bus) | |||
2673 | } | 2734 | } |
2674 | EXPORT_SYMBOL_GPL(snd_hda_lock_devices); | 2735 | EXPORT_SYMBOL_GPL(snd_hda_lock_devices); |
2675 | 2736 | ||
2737 | /** | ||
2738 | * snd_hda_unlock_devices - pseudo device unlocking | ||
2739 | * @bus: the BUS | ||
2740 | */ | ||
2676 | void snd_hda_unlock_devices(struct hda_bus *bus) | 2741 | void snd_hda_unlock_devices(struct hda_bus *bus) |
2677 | { | 2742 | { |
2678 | struct snd_card *card = bus->card; | 2743 | struct snd_card *card = bus->card; |
@@ -2859,7 +2924,7 @@ static int add_slave(struct hda_codec *codec, | |||
2859 | } | 2924 | } |
2860 | 2925 | ||
2861 | /** | 2926 | /** |
2862 | * snd_hda_add_vmaster - create a virtual master control and add slaves | 2927 | * __snd_hda_add_vmaster - create a virtual master control and add slaves |
2863 | * @codec: HD-audio codec | 2928 | * @codec: HD-audio codec |
2864 | * @name: vmaster control name | 2929 | * @name: vmaster control name |
2865 | * @tlv: TLV data (optional) | 2930 | * @tlv: TLV data (optional) |
@@ -2927,16 +2992,8 @@ static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol, | |||
2927 | static const char * const texts[] = { | 2992 | static const char * const texts[] = { |
2928 | "On", "Off", "Follow Master" | 2993 | "On", "Off", "Follow Master" |
2929 | }; | 2994 | }; |
2930 | unsigned int index; | ||
2931 | 2995 | ||
2932 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2996 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2933 | uinfo->count = 1; | ||
2934 | uinfo->value.enumerated.items = 3; | ||
2935 | index = uinfo->value.enumerated.item; | ||
2936 | if (index >= 3) | ||
2937 | index = 2; | ||
2938 | strcpy(uinfo->value.enumerated.name, texts[index]); | ||
2939 | return 0; | ||
2940 | } | 2997 | } |
2941 | 2998 | ||
2942 | static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol, | 2999 | static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol, |
@@ -2970,10 +3027,15 @@ static struct snd_kcontrol_new vmaster_mute_mode = { | |||
2970 | .put = vmaster_mute_mode_put, | 3027 | .put = vmaster_mute_mode_put, |
2971 | }; | 3028 | }; |
2972 | 3029 | ||
2973 | /* | 3030 | /** |
2974 | * Add a mute-LED hook with the given vmaster switch kctl | 3031 | * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED |
2975 | * "Mute-LED Mode" control is automatically created and associated with | 3032 | * @codec: the HDA codec |
2976 | * the given hook. | 3033 | * @hook: the vmaster hook object |
3034 | * @expose_enum_ctl: flag to create an enum ctl | ||
3035 | * | ||
3036 | * Add a mute-LED hook with the given vmaster switch kctl. | ||
3037 | * When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically | ||
3038 | * created and associated with the given hook. | ||
2977 | */ | 3039 | */ |
2978 | int snd_hda_add_vmaster_hook(struct hda_codec *codec, | 3040 | int snd_hda_add_vmaster_hook(struct hda_codec *codec, |
2979 | struct hda_vmaster_mute_hook *hook, | 3041 | struct hda_vmaster_mute_hook *hook, |
@@ -2995,9 +3057,12 @@ int snd_hda_add_vmaster_hook(struct hda_codec *codec, | |||
2995 | } | 3057 | } |
2996 | EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook); | 3058 | EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook); |
2997 | 3059 | ||
2998 | /* | 3060 | /** |
2999 | * Call the hook with the current value for synchronization | 3061 | * snd_hda_sync_vmaster_hook - Sync vmaster hook |
3000 | * Should be called in init callback | 3062 | * @hook: the vmaster hook |
3063 | * | ||
3064 | * Call the hook with the current value for synchronization. | ||
3065 | * Should be called in init callback. | ||
3001 | */ | 3066 | */ |
3002 | void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook) | 3067 | void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook) |
3003 | { | 3068 | { |
@@ -3022,6 +3087,8 @@ EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook); | |||
3022 | 3087 | ||
3023 | /** | 3088 | /** |
3024 | * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch | 3089 | * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch |
3090 | * @kcontrol: referred ctl element | ||
3091 | * @uinfo: pointer to get/store the data | ||
3025 | * | 3092 | * |
3026 | * The control element is supposed to have the private_value field | 3093 | * The control element is supposed to have the private_value field |
3027 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 3094 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -3041,6 +3108,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_info); | |||
3041 | 3108 | ||
3042 | /** | 3109 | /** |
3043 | * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch | 3110 | * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch |
3111 | * @kcontrol: ctl element | ||
3112 | * @ucontrol: pointer to get/store the data | ||
3044 | * | 3113 | * |
3045 | * The control element is supposed to have the private_value field | 3114 | * The control element is supposed to have the private_value field |
3046 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 3115 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -3067,6 +3136,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get); | |||
3067 | 3136 | ||
3068 | /** | 3137 | /** |
3069 | * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch | 3138 | * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch |
3139 | * @kcontrol: ctl element | ||
3140 | * @ucontrol: pointer to get/store the data | ||
3070 | * | 3141 | * |
3071 | * The control element is supposed to have the private_value field | 3142 | * The control element is supposed to have the private_value field |
3072 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | 3143 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. |
@@ -3110,6 +3181,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put); | |||
3110 | 3181 | ||
3111 | /** | 3182 | /** |
3112 | * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control | 3183 | * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control |
3184 | * @kcontrol: ctl element | ||
3185 | * @ucontrol: pointer to get/store the data | ||
3113 | * | 3186 | * |
3114 | * The control element is supposed to have the private_value field | 3187 | * The control element is supposed to have the private_value field |
3115 | * set up via HDA_BIND_MUTE*() macros. | 3188 | * set up via HDA_BIND_MUTE*() macros. |
@@ -3133,6 +3206,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_get); | |||
3133 | 3206 | ||
3134 | /** | 3207 | /** |
3135 | * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control | 3208 | * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control |
3209 | * @kcontrol: ctl element | ||
3210 | * @ucontrol: pointer to get/store the data | ||
3136 | * | 3211 | * |
3137 | * The control element is supposed to have the private_value field | 3212 | * The control element is supposed to have the private_value field |
3138 | * set up via HDA_BIND_MUTE*() macros. | 3213 | * set up via HDA_BIND_MUTE*() macros. |
@@ -3163,6 +3238,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_put); | |||
3163 | 3238 | ||
3164 | /** | 3239 | /** |
3165 | * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control | 3240 | * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control |
3241 | * @kcontrol: referred ctl element | ||
3242 | * @uinfo: pointer to get/store the data | ||
3166 | * | 3243 | * |
3167 | * The control element is supposed to have the private_value field | 3244 | * The control element is supposed to have the private_value field |
3168 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. | 3245 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. |
@@ -3186,6 +3263,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_info); | |||
3186 | 3263 | ||
3187 | /** | 3264 | /** |
3188 | * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control | 3265 | * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control |
3266 | * @kcontrol: ctl element | ||
3267 | * @ucontrol: pointer to get/store the data | ||
3189 | * | 3268 | * |
3190 | * The control element is supposed to have the private_value field | 3269 | * The control element is supposed to have the private_value field |
3191 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. | 3270 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. |
@@ -3209,6 +3288,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_get); | |||
3209 | 3288 | ||
3210 | /** | 3289 | /** |
3211 | * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control | 3290 | * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control |
3291 | * @kcontrol: ctl element | ||
3292 | * @ucontrol: pointer to get/store the data | ||
3212 | * | 3293 | * |
3213 | * The control element is supposed to have the private_value field | 3294 | * The control element is supposed to have the private_value field |
3214 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. | 3295 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. |
@@ -3238,6 +3319,10 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_put); | |||
3238 | 3319 | ||
3239 | /** | 3320 | /** |
3240 | * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control | 3321 | * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control |
3322 | * @kcontrol: ctl element | ||
3323 | * @op_flag: operation flag | ||
3324 | * @size: byte size of input TLV | ||
3325 | * @tlv: TLV data | ||
3241 | * | 3326 | * |
3242 | * The control element is supposed to have the private_value field | 3327 | * The control element is supposed to have the private_value field |
3243 | * set up via HDA_BIND_VOL() macro. | 3328 | * set up via HDA_BIND_VOL() macro. |
@@ -3579,7 +3664,11 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec, | |||
3579 | } | 3664 | } |
3580 | EXPORT_SYMBOL_GPL(snd_hda_create_dig_out_ctls); | 3665 | EXPORT_SYMBOL_GPL(snd_hda_create_dig_out_ctls); |
3581 | 3666 | ||
3582 | /* get the hda_spdif_out entry from the given NID | 3667 | /** |
3668 | * snd_hda_spdif_out_of_nid - get the hda_spdif_out entry from the given NID | ||
3669 | * @codec: the HDA codec | ||
3670 | * @nid: widget NID | ||
3671 | * | ||
3583 | * call within spdif_mutex lock | 3672 | * call within spdif_mutex lock |
3584 | */ | 3673 | */ |
3585 | struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, | 3674 | struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, |
@@ -3596,6 +3685,13 @@ struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, | |||
3596 | } | 3685 | } |
3597 | EXPORT_SYMBOL_GPL(snd_hda_spdif_out_of_nid); | 3686 | EXPORT_SYMBOL_GPL(snd_hda_spdif_out_of_nid); |
3598 | 3687 | ||
3688 | /** | ||
3689 | * snd_hda_spdif_ctls_unassign - Unassign the given SPDIF ctl | ||
3690 | * @codec: the HDA codec | ||
3691 | * @idx: the SPDIF ctl index | ||
3692 | * | ||
3693 | * Unassign the widget from the given SPDIF control. | ||
3694 | */ | ||
3599 | void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) | 3695 | void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) |
3600 | { | 3696 | { |
3601 | struct hda_spdif_out *spdif; | 3697 | struct hda_spdif_out *spdif; |
@@ -3607,6 +3703,14 @@ void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) | |||
3607 | } | 3703 | } |
3608 | EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign); | 3704 | EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign); |
3609 | 3705 | ||
3706 | /** | ||
3707 | * snd_hda_spdif_ctls_assign - Assign the SPDIF controls to the given NID | ||
3708 | * @codec: the HDA codec | ||
3709 | * @idx: the SPDIF ctl idx | ||
3710 | * @nid: widget NID | ||
3711 | * | ||
3712 | * Assign the widget to the SPDIF control with the given index. | ||
3713 | */ | ||
3610 | void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) | 3714 | void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) |
3611 | { | 3715 | { |
3612 | struct hda_spdif_out *spdif; | 3716 | struct hda_spdif_out *spdif; |
@@ -3926,6 +4030,16 @@ void snd_hda_codec_flush_cache(struct hda_codec *codec) | |||
3926 | } | 4030 | } |
3927 | EXPORT_SYMBOL_GPL(snd_hda_codec_flush_cache); | 4031 | EXPORT_SYMBOL_GPL(snd_hda_codec_flush_cache); |
3928 | 4032 | ||
4033 | /** | ||
4034 | * snd_hda_codec_set_power_to_all - Set the power state to all widgets | ||
4035 | * @codec: the HDA codec | ||
4036 | * @fg: function group (not used now) | ||
4037 | * @power_state: the power state to set (AC_PWRST_*) | ||
4038 | * | ||
4039 | * Set the given power state to all widgets that have the power control. | ||
4040 | * If the codec has power_filter set, it evaluates the power state and | ||
4041 | * filter out if it's unchanged as D3. | ||
4042 | */ | ||
3929 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | 4043 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, |
3930 | unsigned int power_state) | 4044 | unsigned int power_state) |
3931 | { | 4045 | { |
@@ -3990,7 +4104,15 @@ static unsigned int hda_sync_power_state(struct hda_codec *codec, | |||
3990 | return state; | 4104 | return state; |
3991 | } | 4105 | } |
3992 | 4106 | ||
3993 | /* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */ | 4107 | /** |
4108 | * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD | ||
4109 | * @codec: the HDA codec | ||
4110 | * @nid: widget NID | ||
4111 | * @power_state: power state to evalue | ||
4112 | * | ||
4113 | * Don't power down the widget if it controls eapd and EAPD_BTLENABLE is set. | ||
4114 | * This can be used a codec power_filter callback. | ||
4115 | */ | ||
3994 | unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, | 4116 | unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, |
3995 | hda_nid_t nid, | 4117 | hda_nid_t nid, |
3996 | unsigned int power_state) | 4118 | unsigned int power_state) |
@@ -4315,6 +4437,7 @@ static struct hda_rate_tbl rate_bits[] = { | |||
4315 | * @channels: the number of channels | 4437 | * @channels: the number of channels |
4316 | * @format: the PCM format (SNDRV_PCM_FORMAT_XXX) | 4438 | * @format: the PCM format (SNDRV_PCM_FORMAT_XXX) |
4317 | * @maxbps: the max. bps | 4439 | * @maxbps: the max. bps |
4440 | * @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant) | ||
4318 | * | 4441 | * |
4319 | * Calculate the format bitset from the given rate, channels and th PCM format. | 4442 | * Calculate the format bitset from the given rate, channels and th PCM format. |
4320 | * | 4443 | * |
@@ -4650,6 +4773,17 @@ static int set_pcm_default_values(struct hda_codec *codec, | |||
4650 | /* | 4773 | /* |
4651 | * codec prepare/cleanup entries | 4774 | * codec prepare/cleanup entries |
4652 | */ | 4775 | */ |
4776 | /** | ||
4777 | * snd_hda_codec_prepare - Prepare a stream | ||
4778 | * @codec: the HDA codec | ||
4779 | * @hinfo: PCM information | ||
4780 | * @stream: stream tag to assign | ||
4781 | * @format: format id to assign | ||
4782 | * @substream: PCM substream to assign | ||
4783 | * | ||
4784 | * Calls the prepare callback set by the codec with the given arguments. | ||
4785 | * Clean up the inactive streams when successful. | ||
4786 | */ | ||
4653 | int snd_hda_codec_prepare(struct hda_codec *codec, | 4787 | int snd_hda_codec_prepare(struct hda_codec *codec, |
4654 | struct hda_pcm_stream *hinfo, | 4788 | struct hda_pcm_stream *hinfo, |
4655 | unsigned int stream, | 4789 | unsigned int stream, |
@@ -4666,6 +4800,14 @@ int snd_hda_codec_prepare(struct hda_codec *codec, | |||
4666 | } | 4800 | } |
4667 | EXPORT_SYMBOL_GPL(snd_hda_codec_prepare); | 4801 | EXPORT_SYMBOL_GPL(snd_hda_codec_prepare); |
4668 | 4802 | ||
4803 | /** | ||
4804 | * snd_hda_codec_cleanup - Prepare a stream | ||
4805 | * @codec: the HDA codec | ||
4806 | * @hinfo: PCM information | ||
4807 | * @substream: PCM substream | ||
4808 | * | ||
4809 | * Calls the cleanup callback set by the codec with the given arguments. | ||
4810 | */ | ||
4669 | void snd_hda_codec_cleanup(struct hda_codec *codec, | 4811 | void snd_hda_codec_cleanup(struct hda_codec *codec, |
4670 | struct hda_pcm_stream *hinfo, | 4812 | struct hda_pcm_stream *hinfo, |
4671 | struct snd_pcm_substream *substream) | 4813 | struct snd_pcm_substream *substream) |
@@ -4990,6 +5132,7 @@ static void __snd_hda_power_down(struct hda_codec *codec) | |||
4990 | * snd_hda_power_save - Power-up/down/sync the codec | 5132 | * snd_hda_power_save - Power-up/down/sync the codec |
4991 | * @codec: HD-audio codec | 5133 | * @codec: HD-audio codec |
4992 | * @delta: the counter delta to change | 5134 | * @delta: the counter delta to change |
5135 | * @d3wait: sync for D3 transition complete | ||
4993 | * | 5136 | * |
4994 | * Change the power-up counter via @delta, and power up or down the hardware | 5137 | * Change the power-up counter via @delta, and power up or down the hardware |
4995 | * appropriately. For the power-down, queue to the delayed action. | 5138 | * appropriately. For the power-down, queue to the delayed action. |
@@ -5065,6 +5208,10 @@ EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power); | |||
5065 | 5208 | ||
5066 | /** | 5209 | /** |
5067 | * snd_hda_ch_mode_info - Info callback helper for the channel mode enum | 5210 | * snd_hda_ch_mode_info - Info callback helper for the channel mode enum |
5211 | * @codec: the HDA codec | ||
5212 | * @uinfo: pointer to get/store the data | ||
5213 | * @chmode: channel mode array | ||
5214 | * @num_chmodes: channel mode array size | ||
5068 | */ | 5215 | */ |
5069 | int snd_hda_ch_mode_info(struct hda_codec *codec, | 5216 | int snd_hda_ch_mode_info(struct hda_codec *codec, |
5070 | struct snd_ctl_elem_info *uinfo, | 5217 | struct snd_ctl_elem_info *uinfo, |
@@ -5084,6 +5231,11 @@ EXPORT_SYMBOL_GPL(snd_hda_ch_mode_info); | |||
5084 | 5231 | ||
5085 | /** | 5232 | /** |
5086 | * snd_hda_ch_mode_get - Get callback helper for the channel mode enum | 5233 | * snd_hda_ch_mode_get - Get callback helper for the channel mode enum |
5234 | * @codec: the HDA codec | ||
5235 | * @ucontrol: pointer to get/store the data | ||
5236 | * @chmode: channel mode array | ||
5237 | * @num_chmodes: channel mode array size | ||
5238 | * @max_channels: max number of channels | ||
5087 | */ | 5239 | */ |
5088 | int snd_hda_ch_mode_get(struct hda_codec *codec, | 5240 | int snd_hda_ch_mode_get(struct hda_codec *codec, |
5089 | struct snd_ctl_elem_value *ucontrol, | 5241 | struct snd_ctl_elem_value *ucontrol, |
@@ -5105,6 +5257,11 @@ EXPORT_SYMBOL_GPL(snd_hda_ch_mode_get); | |||
5105 | 5257 | ||
5106 | /** | 5258 | /** |
5107 | * snd_hda_ch_mode_put - Put callback helper for the channel mode enum | 5259 | * snd_hda_ch_mode_put - Put callback helper for the channel mode enum |
5260 | * @codec: the HDA codec | ||
5261 | * @ucontrol: pointer to get/store the data | ||
5262 | * @chmode: channel mode array | ||
5263 | * @num_chmodes: channel mode array size | ||
5264 | * @max_channelsp: pointer to store the max channels | ||
5108 | */ | 5265 | */ |
5109 | int snd_hda_ch_mode_put(struct hda_codec *codec, | 5266 | int snd_hda_ch_mode_put(struct hda_codec *codec, |
5110 | struct snd_ctl_elem_value *ucontrol, | 5267 | struct snd_ctl_elem_value *ucontrol, |
@@ -5133,6 +5290,8 @@ EXPORT_SYMBOL_GPL(snd_hda_ch_mode_put); | |||
5133 | 5290 | ||
5134 | /** | 5291 | /** |
5135 | * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum | 5292 | * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum |
5293 | * @imux: imux helper object | ||
5294 | * @uinfo: pointer to get/store the data | ||
5136 | */ | 5295 | */ |
5137 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, | 5296 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, |
5138 | struct snd_ctl_elem_info *uinfo) | 5297 | struct snd_ctl_elem_info *uinfo) |
@@ -5154,6 +5313,11 @@ EXPORT_SYMBOL_GPL(snd_hda_input_mux_info); | |||
5154 | 5313 | ||
5155 | /** | 5314 | /** |
5156 | * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum | 5315 | * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum |
5316 | * @codec: the HDA codec | ||
5317 | * @imux: imux helper object | ||
5318 | * @ucontrol: pointer to get/store the data | ||
5319 | * @nid: input mux NID | ||
5320 | * @cur_val: pointer to get/store the current imux value | ||
5157 | */ | 5321 | */ |
5158 | int snd_hda_input_mux_put(struct hda_codec *codec, | 5322 | int snd_hda_input_mux_put(struct hda_codec *codec, |
5159 | const struct hda_input_mux *imux, | 5323 | const struct hda_input_mux *imux, |
@@ -5178,7 +5342,13 @@ int snd_hda_input_mux_put(struct hda_codec *codec, | |||
5178 | EXPORT_SYMBOL_GPL(snd_hda_input_mux_put); | 5342 | EXPORT_SYMBOL_GPL(snd_hda_input_mux_put); |
5179 | 5343 | ||
5180 | 5344 | ||
5181 | /* | 5345 | /** |
5346 | * snd_hda_enum_helper_info - Helper for simple enum ctls | ||
5347 | * @kcontrol: ctl element | ||
5348 | * @uinfo: pointer to get/store the data | ||
5349 | * @num_items: number of enum items | ||
5350 | * @texts: enum item string array | ||
5351 | * | ||
5182 | * process kcontrol info callback of a simple string enum array | 5352 | * process kcontrol info callback of a simple string enum array |
5183 | * when @num_items is 0 or @texts is NULL, assume a boolean enum array | 5353 | * when @num_items is 0 or @texts is NULL, assume a boolean enum array |
5184 | */ | 5354 | */ |
@@ -5195,14 +5365,7 @@ int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol, | |||
5195 | texts = texts_default; | 5365 | texts = texts_default; |
5196 | } | 5366 | } |
5197 | 5367 | ||
5198 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 5368 | return snd_ctl_enum_info(uinfo, 1, num_items, texts); |
5199 | uinfo->count = 1; | ||
5200 | uinfo->value.enumerated.items = num_items; | ||
5201 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
5202 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
5203 | strcpy(uinfo->value.enumerated.name, | ||
5204 | texts[uinfo->value.enumerated.item]); | ||
5205 | return 0; | ||
5206 | } | 5369 | } |
5207 | EXPORT_SYMBOL_GPL(snd_hda_enum_helper_info); | 5370 | EXPORT_SYMBOL_GPL(snd_hda_enum_helper_info); |
5208 | 5371 | ||
@@ -5274,6 +5437,8 @@ EXPORT_SYMBOL_GPL(snd_hda_bus_reboot_notify); | |||
5274 | 5437 | ||
5275 | /** | 5438 | /** |
5276 | * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode | 5439 | * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode |
5440 | * @codec: the HDA codec | ||
5441 | * @mout: hda_multi_out object | ||
5277 | */ | 5442 | */ |
5278 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, | 5443 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, |
5279 | struct hda_multi_out *mout) | 5444 | struct hda_multi_out *mout) |
@@ -5290,6 +5455,11 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_open); | |||
5290 | 5455 | ||
5291 | /** | 5456 | /** |
5292 | * snd_hda_multi_out_dig_prepare - prepare the digital out stream | 5457 | * snd_hda_multi_out_dig_prepare - prepare the digital out stream |
5458 | * @codec: the HDA codec | ||
5459 | * @mout: hda_multi_out object | ||
5460 | * @stream_tag: stream tag to assign | ||
5461 | * @format: format id to assign | ||
5462 | * @substream: PCM substream to assign | ||
5293 | */ | 5463 | */ |
5294 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | 5464 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, |
5295 | struct hda_multi_out *mout, | 5465 | struct hda_multi_out *mout, |
@@ -5306,6 +5476,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare); | |||
5306 | 5476 | ||
5307 | /** | 5477 | /** |
5308 | * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream | 5478 | * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream |
5479 | * @codec: the HDA codec | ||
5480 | * @mout: hda_multi_out object | ||
5309 | */ | 5481 | */ |
5310 | int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, | 5482 | int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, |
5311 | struct hda_multi_out *mout) | 5483 | struct hda_multi_out *mout) |
@@ -5319,6 +5491,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup); | |||
5319 | 5491 | ||
5320 | /** | 5492 | /** |
5321 | * snd_hda_multi_out_dig_close - release the digital out stream | 5493 | * snd_hda_multi_out_dig_close - release the digital out stream |
5494 | * @codec: the HDA codec | ||
5495 | * @mout: hda_multi_out object | ||
5322 | */ | 5496 | */ |
5323 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, | 5497 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, |
5324 | struct hda_multi_out *mout) | 5498 | struct hda_multi_out *mout) |
@@ -5332,6 +5506,10 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_close); | |||
5332 | 5506 | ||
5333 | /** | 5507 | /** |
5334 | * snd_hda_multi_out_analog_open - open analog outputs | 5508 | * snd_hda_multi_out_analog_open - open analog outputs |
5509 | * @codec: the HDA codec | ||
5510 | * @mout: hda_multi_out object | ||
5511 | * @substream: PCM substream to assign | ||
5512 | * @hinfo: PCM information to assign | ||
5335 | * | 5513 | * |
5336 | * Open analog outputs and set up the hw-constraints. | 5514 | * Open analog outputs and set up the hw-constraints. |
5337 | * If the digital outputs can be opened as slave, open the digital | 5515 | * If the digital outputs can be opened as slave, open the digital |
@@ -5382,6 +5560,11 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_open); | |||
5382 | 5560 | ||
5383 | /** | 5561 | /** |
5384 | * snd_hda_multi_out_analog_prepare - Preapre the analog outputs. | 5562 | * snd_hda_multi_out_analog_prepare - Preapre the analog outputs. |
5563 | * @codec: the HDA codec | ||
5564 | * @mout: hda_multi_out object | ||
5565 | * @stream_tag: stream tag to assign | ||
5566 | * @format: format id to assign | ||
5567 | * @substream: PCM substream to assign | ||
5385 | * | 5568 | * |
5386 | * Set up the i/o for analog out. | 5569 | * Set up the i/o for analog out. |
5387 | * When the digital out is available, copy the front out to digital out, too. | 5570 | * When the digital out is available, copy the front out to digital out, too. |
@@ -5459,6 +5642,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_prepare); | |||
5459 | 5642 | ||
5460 | /** | 5643 | /** |
5461 | * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out | 5644 | * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out |
5645 | * @codec: the HDA codec | ||
5646 | * @mout: hda_multi_out object | ||
5462 | */ | 5647 | */ |
5463 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | 5648 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, |
5464 | struct hda_multi_out *mout) | 5649 | struct hda_multi_out *mout) |
@@ -5490,6 +5675,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_cleanup); | |||
5490 | 5675 | ||
5491 | /** | 5676 | /** |
5492 | * snd_hda_get_default_vref - Get the default (mic) VREF pin bits | 5677 | * snd_hda_get_default_vref - Get the default (mic) VREF pin bits |
5678 | * @codec: the HDA codec | ||
5679 | * @pin: referred pin NID | ||
5493 | * | 5680 | * |
5494 | * Guess the suitable VREF pin bits to be set as the pin-control value. | 5681 | * Guess the suitable VREF pin bits to be set as the pin-control value. |
5495 | * Note: the function doesn't set the AC_PINCTL_IN_EN bit. | 5682 | * Note: the function doesn't set the AC_PINCTL_IN_EN bit. |
@@ -5515,7 +5702,12 @@ unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin) | |||
5515 | } | 5702 | } |
5516 | EXPORT_SYMBOL_GPL(snd_hda_get_default_vref); | 5703 | EXPORT_SYMBOL_GPL(snd_hda_get_default_vref); |
5517 | 5704 | ||
5518 | /* correct the pin ctl value for matching with the pin cap */ | 5705 | /** |
5706 | * snd_hda_correct_pin_ctl - correct the pin ctl value for matching with the pin cap | ||
5707 | * @codec: the HDA codec | ||
5708 | * @pin: referred pin NID | ||
5709 | * @val: pin ctl value to audit | ||
5710 | */ | ||
5519 | unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, | 5711 | unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, |
5520 | hda_nid_t pin, unsigned int val) | 5712 | hda_nid_t pin, unsigned int val) |
5521 | { | 5713 | { |
@@ -5566,6 +5758,19 @@ unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, | |||
5566 | } | 5758 | } |
5567 | EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl); | 5759 | EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl); |
5568 | 5760 | ||
5761 | /** | ||
5762 | * _snd_hda_pin_ctl - Helper to set pin ctl value | ||
5763 | * @codec: the HDA codec | ||
5764 | * @pin: referred pin NID | ||
5765 | * @val: pin control value to set | ||
5766 | * @cached: access over codec pinctl cache or direct write | ||
5767 | * | ||
5768 | * This function is a helper to set a pin ctl value more safely. | ||
5769 | * It corrects the pin ctl value via snd_hda_correct_pin_ctl(), stores the | ||
5770 | * value in pin target array via snd_hda_codec_set_pin_target(), then | ||
5771 | * actually writes the value via either snd_hda_codec_update_cache() or | ||
5772 | * snd_hda_codec_write() depending on @cached flag. | ||
5773 | */ | ||
5569 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, | 5774 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, |
5570 | unsigned int val, bool cached) | 5775 | unsigned int val, bool cached) |
5571 | { | 5776 | { |
@@ -5582,6 +5787,11 @@ EXPORT_SYMBOL_GPL(_snd_hda_set_pin_ctl); | |||
5582 | 5787 | ||
5583 | /** | 5788 | /** |
5584 | * snd_hda_add_imux_item - Add an item to input_mux | 5789 | * snd_hda_add_imux_item - Add an item to input_mux |
5790 | * @codec: the HDA codec | ||
5791 | * @imux: imux helper object | ||
5792 | * @label: the name of imux item to assign | ||
5793 | * @index: index number of imux item to assign | ||
5794 | * @type_idx: pointer to store the resultant label index | ||
5585 | * | 5795 | * |
5586 | * When the same label is used already in the existing items, the number | 5796 | * When the same label is used already in the existing items, the number |
5587 | * suffix is appended to the label. This label index number is stored | 5797 | * suffix is appended to the label. This label index number is stored |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index e1cd34d9011d..0e6d7534f491 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -371,7 +371,7 @@ error: | |||
371 | return ret; | 371 | return ret; |
372 | } | 372 | } |
373 | 373 | ||
374 | /** | 374 | /* |
375 | * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with | 375 | * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with |
376 | * hdmi-specific routine. | 376 | * hdmi-specific routine. |
377 | */ | 377 | */ |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 64220c08bd98..63b69f750d8e 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -40,7 +40,12 @@ | |||
40 | #include "hda_generic.h" | 40 | #include "hda_generic.h" |
41 | 41 | ||
42 | 42 | ||
43 | /* initialize hda_gen_spec struct */ | 43 | /** |
44 | * snd_hda_gen_spec_init - initialize hda_gen_spec struct | ||
45 | * @spec: hda_gen_spec object to initialize | ||
46 | * | ||
47 | * Initialize the given hda_gen_spec object. | ||
48 | */ | ||
44 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec) | 49 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec) |
45 | { | 50 | { |
46 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | 51 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); |
@@ -51,6 +56,17 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec) | |||
51 | } | 56 | } |
52 | EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); | 57 | EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); |
53 | 58 | ||
59 | /** | ||
60 | * snd_hda_gen_add_kctl - Add a new kctl_new struct from the template | ||
61 | * @spec: hda_gen_spec object | ||
62 | * @name: name string to override the template, NULL if unchanged | ||
63 | * @temp: template for the new kctl | ||
64 | * | ||
65 | * Add a new kctl (actually snd_kcontrol_new to be instantiated later) | ||
66 | * element based on the given snd_kcontrol_new template @temp and the | ||
67 | * name string @name to the list in @spec. | ||
68 | * Returns the newly created object or NULL as error. | ||
69 | */ | ||
54 | struct snd_kcontrol_new * | 70 | struct snd_kcontrol_new * |
55 | snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, | 71 | snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, |
56 | const struct snd_kcontrol_new *temp) | 72 | const struct snd_kcontrol_new *temp) |
@@ -259,8 +275,14 @@ static struct nid_path *get_nid_path(struct hda_codec *codec, | |||
259 | return NULL; | 275 | return NULL; |
260 | } | 276 | } |
261 | 277 | ||
262 | /* get the path between the given NIDs; | 278 | /** |
263 | * passing 0 to either @pin or @dac behaves as a wildcard | 279 | * snd_hda_get_nid_path - get the path between the given NIDs |
280 | * @codec: the HDA codec | ||
281 | * @from_nid: the NID where the path start from | ||
282 | * @to_nid: the NID where the path ends at | ||
283 | * | ||
284 | * Return the found nid_path object or NULL for error. | ||
285 | * Passing 0 to either @from_nid or @to_nid behaves as a wildcard. | ||
264 | */ | 286 | */ |
265 | struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, | 287 | struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, |
266 | hda_nid_t from_nid, hda_nid_t to_nid) | 288 | hda_nid_t from_nid, hda_nid_t to_nid) |
@@ -269,8 +291,14 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, | |||
269 | } | 291 | } |
270 | EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); | 292 | EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); |
271 | 293 | ||
272 | /* get the index number corresponding to the path instance; | 294 | /** |
273 | * the index starts from 1, for easier checking the invalid value | 295 | * snd_hda_get_path_idx - get the index number corresponding to the path |
296 | * instance | ||
297 | * @codec: the HDA codec | ||
298 | * @path: nid_path object | ||
299 | * | ||
300 | * The returned index starts from 1, i.e. the actual array index with offset 1, | ||
301 | * and zero is handled as an invalid path | ||
274 | */ | 302 | */ |
275 | int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) | 303 | int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) |
276 | { | 304 | { |
@@ -287,7 +315,12 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) | |||
287 | } | 315 | } |
288 | EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); | 316 | EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); |
289 | 317 | ||
290 | /* get the path instance corresponding to the given index number */ | 318 | /** |
319 | * snd_hda_get_path_from_idx - get the path instance corresponding to the | ||
320 | * given index number | ||
321 | * @codec: the HDA codec | ||
322 | * @idx: the path index | ||
323 | */ | ||
291 | struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) | 324 | struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) |
292 | { | 325 | { |
293 | struct hda_gen_spec *spec = codec->spec; | 326 | struct hda_gen_spec *spec = codec->spec; |
@@ -415,7 +448,18 @@ static bool __parse_nid_path(struct hda_codec *codec, | |||
415 | return true; | 448 | return true; |
416 | } | 449 | } |
417 | 450 | ||
418 | /* parse the widget path from the given nid to the target nid; | 451 | /** |
452 | * snd_hda_parse_nid_path - parse the widget path from the given nid to | ||
453 | * the target nid | ||
454 | * @codec: the HDA codec | ||
455 | * @from_nid: the NID where the path start from | ||
456 | * @to_nid: the NID where the path ends at | ||
457 | * @anchor_nid: the anchor indication | ||
458 | * @path: the path object to store the result | ||
459 | * | ||
460 | * Returns true if a matching path is found. | ||
461 | * | ||
462 | * The parsing behavior depends on parameters: | ||
419 | * when @from_nid is 0, try to find an empty DAC; | 463 | * when @from_nid is 0, try to find an empty DAC; |
420 | * when @anchor_nid is set to a positive value, only paths through the widget | 464 | * when @anchor_nid is set to a positive value, only paths through the widget |
421 | * with the given value are evaluated. | 465 | * with the given value are evaluated. |
@@ -436,9 +480,15 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, | |||
436 | } | 480 | } |
437 | EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); | 481 | EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); |
438 | 482 | ||
439 | /* | 483 | /** |
440 | * parse the path between the given NIDs and add to the path list. | 484 | * snd_hda_add_new_path - parse the path between the given NIDs and |
441 | * if no valid path is found, return NULL | 485 | * add to the path list |
486 | * @codec: the HDA codec | ||
487 | * @from_nid: the NID where the path start from | ||
488 | * @to_nid: the NID where the path ends at | ||
489 | * @anchor_nid: the anchor indication, see snd_hda_parse_nid_path() | ||
490 | * | ||
491 | * If no valid path is found, returns NULL. | ||
442 | */ | 492 | */ |
443 | struct nid_path * | 493 | struct nid_path * |
444 | snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, | 494 | snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, |
@@ -724,8 +774,14 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, | |||
724 | } | 774 | } |
725 | } | 775 | } |
726 | 776 | ||
727 | /* activate or deactivate the given path | 777 | /** |
728 | * if @add_aamix is set, enable the input from aa-mix NID as well (if any) | 778 | * snd_hda_activate_path - activate or deactivate the given path |
779 | * @codec: the HDA codec | ||
780 | * @path: the path to activate/deactivate | ||
781 | * @enable: flag to activate or not | ||
782 | * @add_aamix: enable the input from aamix NID | ||
783 | * | ||
784 | * If @add_aamix is set, enable the input from aa-mix NID as well (if any). | ||
729 | */ | 785 | */ |
730 | void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, | 786 | void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, |
731 | bool enable, bool add_aamix) | 787 | bool enable, bool add_aamix) |
@@ -1038,11 +1094,24 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch, | |||
1038 | break; | 1094 | break; |
1039 | *index = ch; | 1095 | *index = ch; |
1040 | return "Headphone"; | 1096 | return "Headphone"; |
1097 | case AUTO_PIN_LINE_OUT: | ||
1098 | /* This deals with the case where we have two DACs and | ||
1099 | * one LO, one HP and one Speaker */ | ||
1100 | if (!ch && cfg->speaker_outs && cfg->hp_outs) { | ||
1101 | bool hp_lo_shared = !path_has_mixer(codec, spec->hp_paths[0], ctl_type); | ||
1102 | bool spk_lo_shared = !path_has_mixer(codec, spec->speaker_paths[0], ctl_type); | ||
1103 | if (hp_lo_shared && spk_lo_shared) | ||
1104 | return spec->vmaster_mute.hook ? "PCM" : "Master"; | ||
1105 | if (hp_lo_shared) | ||
1106 | return "Headphone+LO"; | ||
1107 | if (spk_lo_shared) | ||
1108 | return "Speaker+LO"; | ||
1109 | } | ||
1041 | } | 1110 | } |
1042 | 1111 | ||
1043 | /* for a single channel output, we don't have to name the channel */ | 1112 | /* for a single channel output, we don't have to name the channel */ |
1044 | if (cfg->line_outs == 1 && !spec->multi_ios) | 1113 | if (cfg->line_outs == 1 && !spec->multi_ios) |
1045 | return "PCM"; | 1114 | return "Line Out"; |
1046 | 1115 | ||
1047 | if (ch >= ARRAY_SIZE(channel_name)) { | 1116 | if (ch >= ARRAY_SIZE(channel_name)) { |
1048 | snd_BUG(); | 1117 | snd_BUG(); |
@@ -3870,7 +3939,12 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
3870 | } | 3939 | } |
3871 | } | 3940 | } |
3872 | 3941 | ||
3873 | /* Toggle outputs muting */ | 3942 | /** |
3943 | * snd_hda_gen_update_outputs - Toggle outputs muting | ||
3944 | * @codec: the HDA codec | ||
3945 | * | ||
3946 | * Update the mute status of all outputs based on the current jack states. | ||
3947 | */ | ||
3874 | void snd_hda_gen_update_outputs(struct hda_codec *codec) | 3948 | void snd_hda_gen_update_outputs(struct hda_codec *codec) |
3875 | { | 3949 | { |
3876 | struct hda_gen_spec *spec = codec->spec; | 3950 | struct hda_gen_spec *spec = codec->spec; |
@@ -3931,7 +4005,11 @@ static void call_update_outputs(struct hda_codec *codec) | |||
3931 | snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false); | 4005 | snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false); |
3932 | } | 4006 | } |
3933 | 4007 | ||
3934 | /* standard HP-automute helper */ | 4008 | /** |
4009 | * snd_hda_gen_hp_automute - standard HP-automute helper | ||
4010 | * @codec: the HDA codec | ||
4011 | * @jack: jack object, NULL for the whole | ||
4012 | */ | ||
3935 | void snd_hda_gen_hp_automute(struct hda_codec *codec, | 4013 | void snd_hda_gen_hp_automute(struct hda_codec *codec, |
3936 | struct hda_jack_callback *jack) | 4014 | struct hda_jack_callback *jack) |
3937 | { | 4015 | { |
@@ -3952,7 +4030,11 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, | |||
3952 | } | 4030 | } |
3953 | EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); | 4031 | EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); |
3954 | 4032 | ||
3955 | /* standard line-out-automute helper */ | 4033 | /** |
4034 | * snd_hda_gen_line_automute - standard line-out-automute helper | ||
4035 | * @codec: the HDA codec | ||
4036 | * @jack: jack object, NULL for the whole | ||
4037 | */ | ||
3956 | void snd_hda_gen_line_automute(struct hda_codec *codec, | 4038 | void snd_hda_gen_line_automute(struct hda_codec *codec, |
3957 | struct hda_jack_callback *jack) | 4039 | struct hda_jack_callback *jack) |
3958 | { | 4040 | { |
@@ -3973,7 +4055,11 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, | |||
3973 | } | 4055 | } |
3974 | EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); | 4056 | EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); |
3975 | 4057 | ||
3976 | /* standard mic auto-switch helper */ | 4058 | /** |
4059 | * snd_hda_gen_mic_autoswitch - standard mic auto-switch helper | ||
4060 | * @codec: the HDA codec | ||
4061 | * @jack: jack object, NULL for the whole | ||
4062 | */ | ||
3977 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, | 4063 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, |
3978 | struct hda_jack_callback *jack) | 4064 | struct hda_jack_callback *jack) |
3979 | { | 4065 | { |
@@ -4305,7 +4391,13 @@ static int check_auto_mic_availability(struct hda_codec *codec) | |||
4305 | return 0; | 4391 | return 0; |
4306 | } | 4392 | } |
4307 | 4393 | ||
4308 | /* power_filter hook; make inactive widgets into power down */ | 4394 | /** |
4395 | * snd_hda_gen_path_power_filter - power_filter hook to make inactive widgets | ||
4396 | * into power down | ||
4397 | * @codec: the HDA codec | ||
4398 | * @nid: NID to evalute | ||
4399 | * @power_state: target power state | ||
4400 | */ | ||
4309 | unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | 4401 | unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, |
4310 | hda_nid_t nid, | 4402 | hda_nid_t nid, |
4311 | unsigned int power_state) | 4403 | unsigned int power_state) |
@@ -4341,8 +4433,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) | |||
4341 | } | 4433 | } |
4342 | } | 4434 | } |
4343 | 4435 | ||
4344 | /* | 4436 | /** |
4345 | * Parse the given BIOS configuration and set up the hda_gen_spec | 4437 | * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and |
4438 | * set up the hda_gen_spec | ||
4439 | * @codec: the HDA codec | ||
4440 | * @cfg: Parsed pin configuration | ||
4346 | * | 4441 | * |
4347 | * return 1 if successful, 0 if the proper config is not found, | 4442 | * return 1 if successful, 0 if the proper config is not found, |
4348 | * or a negative error code | 4443 | * or a negative error code |
@@ -4524,10 +4619,16 @@ static const char * const slave_pfxs[] = { | |||
4524 | "CLFE", "Bass Speaker", "PCM", | 4619 | "CLFE", "Bass Speaker", "PCM", |
4525 | "Speaker Front", "Speaker Surround", "Speaker CLFE", "Speaker Side", | 4620 | "Speaker Front", "Speaker Surround", "Speaker CLFE", "Speaker Side", |
4526 | "Headphone Front", "Headphone Surround", "Headphone CLFE", | 4621 | "Headphone Front", "Headphone Surround", "Headphone CLFE", |
4527 | "Headphone Side", | 4622 | "Headphone Side", "Headphone+LO", "Speaker+LO", |
4528 | NULL, | 4623 | NULL, |
4529 | }; | 4624 | }; |
4530 | 4625 | ||
4626 | /** | ||
4627 | * snd_hda_gen_build_controls - Build controls from the parsed results | ||
4628 | * @codec: the HDA codec | ||
4629 | * | ||
4630 | * Pass this to build_controls patch_ops. | ||
4631 | */ | ||
4531 | int snd_hda_gen_build_controls(struct hda_codec *codec) | 4632 | int snd_hda_gen_build_controls(struct hda_codec *codec) |
4532 | { | 4633 | { |
4533 | struct hda_gen_spec *spec = codec->spec; | 4634 | struct hda_gen_spec *spec = codec->spec; |
@@ -5005,7 +5106,12 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, | |||
5005 | strlcat(str, sfx, len); | 5106 | strlcat(str, sfx, len); |
5006 | } | 5107 | } |
5007 | 5108 | ||
5008 | /* build PCM streams based on the parsed results */ | 5109 | /** |
5110 | * snd_hda_gen_build_pcms - build PCM streams based on the parsed results | ||
5111 | * @codec: the HDA codec | ||
5112 | * | ||
5113 | * Pass this to build_pcms patch_ops. | ||
5114 | */ | ||
5009 | int snd_hda_gen_build_pcms(struct hda_codec *codec) | 5115 | int snd_hda_gen_build_pcms(struct hda_codec *codec) |
5010 | { | 5116 | { |
5011 | struct hda_gen_spec *spec = codec->spec; | 5117 | struct hda_gen_spec *spec = codec->spec; |
@@ -5300,9 +5406,11 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec) | |||
5300 | } | 5406 | } |
5301 | } | 5407 | } |
5302 | 5408 | ||
5303 | /* | 5409 | /** |
5304 | * initialize the generic spec; | 5410 | * snd_hda_gen_init - initialize the generic spec |
5305 | * this can be put as patch_ops.init function | 5411 | * @codec: the HDA codec |
5412 | * | ||
5413 | * This can be put as patch_ops init function. | ||
5306 | */ | 5414 | */ |
5307 | int snd_hda_gen_init(struct hda_codec *codec) | 5415 | int snd_hda_gen_init(struct hda_codec *codec) |
5308 | { | 5416 | { |
@@ -5338,9 +5446,11 @@ int snd_hda_gen_init(struct hda_codec *codec) | |||
5338 | } | 5446 | } |
5339 | EXPORT_SYMBOL_GPL(snd_hda_gen_init); | 5447 | EXPORT_SYMBOL_GPL(snd_hda_gen_init); |
5340 | 5448 | ||
5341 | /* | 5449 | /** |
5342 | * free the generic spec; | 5450 | * snd_hda_gen_free - free the generic spec |
5343 | * this can be put as patch_ops.free function | 5451 | * @codec: the HDA codec |
5452 | * | ||
5453 | * This can be put as patch_ops free function. | ||
5344 | */ | 5454 | */ |
5345 | void snd_hda_gen_free(struct hda_codec *codec) | 5455 | void snd_hda_gen_free(struct hda_codec *codec) |
5346 | { | 5456 | { |
@@ -5352,9 +5462,12 @@ void snd_hda_gen_free(struct hda_codec *codec) | |||
5352 | EXPORT_SYMBOL_GPL(snd_hda_gen_free); | 5462 | EXPORT_SYMBOL_GPL(snd_hda_gen_free); |
5353 | 5463 | ||
5354 | #ifdef CONFIG_PM | 5464 | #ifdef CONFIG_PM |
5355 | /* | 5465 | /** |
5356 | * check the loopback power save state; | 5466 | * snd_hda_gen_check_power_status - check the loopback power save state |
5357 | * this can be put as patch_ops.check_power_status function | 5467 | * @codec: the HDA codec |
5468 | * @nid: NID to inspect | ||
5469 | * | ||
5470 | * This can be put as patch_ops check_power_status function. | ||
5358 | */ | 5471 | */ |
5359 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 5472 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
5360 | { | 5473 | { |
@@ -5380,6 +5493,12 @@ static const struct hda_codec_ops generic_patch_ops = { | |||
5380 | #endif | 5493 | #endif |
5381 | }; | 5494 | }; |
5382 | 5495 | ||
5496 | /** | ||
5497 | * snd_hda_parse_generic_codec - Generic codec parser | ||
5498 | * @codec: the HDA codec | ||
5499 | * | ||
5500 | * This should be called from the HDA codec core. | ||
5501 | */ | ||
5383 | int snd_hda_parse_generic_codec(struct hda_codec *codec) | 5502 | int snd_hda_parse_generic_codec(struct hda_codec *codec) |
5384 | { | 5503 | { |
5385 | struct hda_gen_spec *spec; | 5504 | struct hda_gen_spec *spec; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 16660f312043..5ac0d39d59bc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -196,8 +196,8 @@ MODULE_PARM_DESC(align_buffer_size, | |||
196 | "Force buffer and period sizes to be multiple of 128 bytes."); | 196 | "Force buffer and period sizes to be multiple of 128 bytes."); |
197 | 197 | ||
198 | #ifdef CONFIG_X86 | 198 | #ifdef CONFIG_X86 |
199 | static bool hda_snoop = true; | 199 | static int hda_snoop = -1; |
200 | module_param_named(snoop, hda_snoop, bool, 0444); | 200 | module_param_named(snoop, hda_snoop, bint, 0444); |
201 | MODULE_PARM_DESC(snoop, "Enable/disable snooping"); | 201 | MODULE_PARM_DESC(snoop, "Enable/disable snooping"); |
202 | #else | 202 | #else |
203 | #define hda_snoop true | 203 | #define hda_snoop true |
@@ -272,42 +272,56 @@ enum { | |||
272 | AZX_NUM_DRIVERS, /* keep this as last entry */ | 272 | AZX_NUM_DRIVERS, /* keep this as last entry */ |
273 | }; | 273 | }; |
274 | 274 | ||
275 | #define azx_get_snoop_type(chip) \ | ||
276 | (((chip)->driver_caps & AZX_DCAPS_SNOOP_MASK) >> 10) | ||
277 | #define AZX_DCAPS_SNOOP_TYPE(type) ((AZX_SNOOP_TYPE_ ## type) << 10) | ||
278 | |||
279 | /* quirks for old Intel chipsets */ | ||
280 | #define AZX_DCAPS_INTEL_ICH \ | ||
281 | (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE) | ||
282 | |||
275 | /* quirks for Intel PCH */ | 283 | /* quirks for Intel PCH */ |
276 | #define AZX_DCAPS_INTEL_PCH_NOPM \ | 284 | #define AZX_DCAPS_INTEL_PCH_NOPM \ |
277 | (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ | 285 | (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ |
278 | AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_REVERSE_ASSIGN) | 286 | AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH)) |
279 | 287 | ||
280 | #define AZX_DCAPS_INTEL_PCH \ | 288 | #define AZX_DCAPS_INTEL_PCH \ |
281 | (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME) | 289 | (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME) |
282 | 290 | ||
283 | #define AZX_DCAPS_INTEL_HASWELL \ | 291 | #define AZX_DCAPS_INTEL_HASWELL \ |
284 | (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_ALIGN_BUFSIZE | \ | 292 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ |
285 | AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME | \ | 293 | AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\ |
286 | AZX_DCAPS_I915_POWERWELL) | 294 | AZX_DCAPS_SNOOP_TYPE(SCH)) |
287 | 295 | ||
288 | /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */ | 296 | /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */ |
289 | #define AZX_DCAPS_INTEL_BROADWELL \ | 297 | #define AZX_DCAPS_INTEL_BROADWELL \ |
290 | (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_ALIGN_BUFSIZE | \ | 298 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\ |
291 | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_PM_RUNTIME | \ | 299 | AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\ |
292 | AZX_DCAPS_I915_POWERWELL) | 300 | AZX_DCAPS_SNOOP_TYPE(SCH)) |
293 | 301 | ||
294 | /* quirks for ATI SB / AMD Hudson */ | 302 | /* quirks for ATI SB / AMD Hudson */ |
295 | #define AZX_DCAPS_PRESET_ATI_SB \ | 303 | #define AZX_DCAPS_PRESET_ATI_SB \ |
296 | (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \ | 304 | (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\ |
297 | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB) | 305 | AZX_DCAPS_SNOOP_TYPE(ATI)) |
298 | 306 | ||
299 | /* quirks for ATI/AMD HDMI */ | 307 | /* quirks for ATI/AMD HDMI */ |
300 | #define AZX_DCAPS_PRESET_ATI_HDMI \ | 308 | #define AZX_DCAPS_PRESET_ATI_HDMI \ |
301 | (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB) | 309 | (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB|\ |
310 | AZX_DCAPS_NO_MSI64) | ||
311 | |||
312 | /* quirks for ATI HDMI with snoop off */ | ||
313 | #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ | ||
314 | (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) | ||
302 | 315 | ||
303 | /* quirks for Nvidia */ | 316 | /* quirks for Nvidia */ |
304 | #define AZX_DCAPS_PRESET_NVIDIA \ | 317 | #define AZX_DCAPS_PRESET_NVIDIA \ |
305 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ | 318 | (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \ |
306 | AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT |\ | 319 | AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\ |
307 | AZX_DCAPS_CORBRP_SELF_CLEAR) | 320 | AZX_DCAPS_SNOOP_TYPE(NVIDIA)) |
308 | 321 | ||
309 | #define AZX_DCAPS_PRESET_CTHDA \ | 322 | #define AZX_DCAPS_PRESET_CTHDA \ |
310 | (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY) | 323 | (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\ |
324 | AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF) | ||
311 | 325 | ||
312 | /* | 326 | /* |
313 | * VGA-switcher support | 327 | * VGA-switcher support |
@@ -436,6 +450,8 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, | |||
436 | 450 | ||
437 | static void azx_init_pci(struct azx *chip) | 451 | static void azx_init_pci(struct azx *chip) |
438 | { | 452 | { |
453 | int snoop_type = azx_get_snoop_type(chip); | ||
454 | |||
439 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 455 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
440 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 456 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
441 | * Ensuring these bits are 0 clears playback static on some HD Audio | 457 | * Ensuring these bits are 0 clears playback static on some HD Audio |
@@ -450,7 +466,7 @@ static void azx_init_pci(struct azx *chip) | |||
450 | /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, | 466 | /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, |
451 | * we need to enable snoop. | 467 | * we need to enable snoop. |
452 | */ | 468 | */ |
453 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { | 469 | if (snoop_type == AZX_SNOOP_TYPE_ATI) { |
454 | dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n", | 470 | dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n", |
455 | azx_snoop(chip)); | 471 | azx_snoop(chip)); |
456 | update_pci_byte(chip->pci, | 472 | update_pci_byte(chip->pci, |
@@ -459,7 +475,7 @@ static void azx_init_pci(struct azx *chip) | |||
459 | } | 475 | } |
460 | 476 | ||
461 | /* For NVIDIA HDA, enable snoop */ | 477 | /* For NVIDIA HDA, enable snoop */ |
462 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { | 478 | if (snoop_type == AZX_SNOOP_TYPE_NVIDIA) { |
463 | dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n", | 479 | dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n", |
464 | azx_snoop(chip)); | 480 | azx_snoop(chip)); |
465 | update_pci_byte(chip->pci, | 481 | update_pci_byte(chip->pci, |
@@ -474,7 +490,7 @@ static void azx_init_pci(struct azx *chip) | |||
474 | } | 490 | } |
475 | 491 | ||
476 | /* Enable SCH/PCH snoop if needed */ | 492 | /* Enable SCH/PCH snoop if needed */ |
477 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { | 493 | if (snoop_type == AZX_SNOOP_TYPE_SCH) { |
478 | unsigned short snoop; | 494 | unsigned short snoop; |
479 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 495 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
480 | if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || | 496 | if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || |
@@ -1131,8 +1147,7 @@ static int azx_free(struct azx *chip) | |||
1131 | pci_disable_device(chip->pci); | 1147 | pci_disable_device(chip->pci); |
1132 | kfree(chip->azx_dev); | 1148 | kfree(chip->azx_dev); |
1133 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 1149 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
1134 | if (chip->fw) | 1150 | release_firmware(chip->fw); |
1135 | release_firmware(chip->fw); | ||
1136 | #endif | 1151 | #endif |
1137 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | 1152 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
1138 | hda_display_power(false); | 1153 | hda_display_power(false); |
@@ -1360,35 +1375,33 @@ static void check_msi(struct azx *chip) | |||
1360 | /* check the snoop mode availability */ | 1375 | /* check the snoop mode availability */ |
1361 | static void azx_check_snoop_available(struct azx *chip) | 1376 | static void azx_check_snoop_available(struct azx *chip) |
1362 | { | 1377 | { |
1363 | bool snoop = chip->snoop; | 1378 | int snoop = hda_snoop; |
1379 | |||
1380 | if (snoop >= 0) { | ||
1381 | dev_info(chip->card->dev, "Force to %s mode by module option\n", | ||
1382 | snoop ? "snoop" : "non-snoop"); | ||
1383 | chip->snoop = snoop; | ||
1384 | return; | ||
1385 | } | ||
1364 | 1386 | ||
1365 | switch (chip->driver_type) { | 1387 | snoop = true; |
1366 | case AZX_DRIVER_VIA: | 1388 | if (azx_get_snoop_type(chip) == AZX_SNOOP_TYPE_NONE && |
1389 | chip->driver_type == AZX_DRIVER_VIA) { | ||
1367 | /* force to non-snoop mode for a new VIA controller | 1390 | /* force to non-snoop mode for a new VIA controller |
1368 | * when BIOS is set | 1391 | * when BIOS is set |
1369 | */ | 1392 | */ |
1370 | if (snoop) { | 1393 | u8 val; |
1371 | u8 val; | 1394 | pci_read_config_byte(chip->pci, 0x42, &val); |
1372 | pci_read_config_byte(chip->pci, 0x42, &val); | 1395 | if (!(val & 0x80) && chip->pci->revision == 0x30) |
1373 | if (!(val & 0x80) && chip->pci->revision == 0x30) | 1396 | snoop = false; |
1374 | snoop = false; | ||
1375 | } | ||
1376 | break; | ||
1377 | case AZX_DRIVER_ATIHDMI_NS: | ||
1378 | /* new ATI HDMI requires non-snoop */ | ||
1379 | snoop = false; | ||
1380 | break; | ||
1381 | case AZX_DRIVER_CTHDA: | ||
1382 | case AZX_DRIVER_CMEDIA: | ||
1383 | snoop = false; | ||
1384 | break; | ||
1385 | } | 1397 | } |
1386 | 1398 | ||
1387 | if (snoop != chip->snoop) { | 1399 | if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF) |
1388 | dev_info(chip->card->dev, "Force to %s mode\n", | 1400 | snoop = false; |
1389 | snoop ? "snoop" : "non-snoop"); | 1401 | |
1390 | chip->snoop = snoop; | 1402 | chip->snoop = snoop; |
1391 | } | 1403 | if (!snoop) |
1404 | dev_info(chip->card->dev, "Force to non-snoop mode\n"); | ||
1392 | } | 1405 | } |
1393 | 1406 | ||
1394 | static void azx_probe_work(struct work_struct *work) | 1407 | static void azx_probe_work(struct work_struct *work) |
@@ -1448,7 +1461,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1448 | check_probe_mask(chip, dev); | 1461 | check_probe_mask(chip, dev); |
1449 | 1462 | ||
1450 | chip->single_cmd = single_cmd; | 1463 | chip->single_cmd = single_cmd; |
1451 | chip->snoop = hda_snoop; | ||
1452 | azx_check_snoop_available(chip); | 1464 | azx_check_snoop_available(chip); |
1453 | 1465 | ||
1454 | if (bdl_pos_adj[dev] < 0) { | 1466 | if (bdl_pos_adj[dev] < 0) { |
@@ -1486,6 +1498,7 @@ static int azx_first_init(struct azx *chip) | |||
1486 | struct snd_card *card = chip->card; | 1498 | struct snd_card *card = chip->card; |
1487 | int err; | 1499 | int err; |
1488 | unsigned short gcap; | 1500 | unsigned short gcap; |
1501 | unsigned int dma_bits = 64; | ||
1489 | 1502 | ||
1490 | #if BITS_PER_LONG != 64 | 1503 | #if BITS_PER_LONG != 64 |
1491 | /* Fix up base address on ULI M5461 */ | 1504 | /* Fix up base address on ULI M5461 */ |
@@ -1509,9 +1522,14 @@ static int azx_first_init(struct azx *chip) | |||
1509 | return -ENXIO; | 1522 | return -ENXIO; |
1510 | } | 1523 | } |
1511 | 1524 | ||
1512 | if (chip->msi) | 1525 | if (chip->msi) { |
1526 | if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { | ||
1527 | dev_dbg(card->dev, "Disabling 64bit MSI\n"); | ||
1528 | pci->no_64bit_msi = true; | ||
1529 | } | ||
1513 | if (pci_enable_msi(pci) < 0) | 1530 | if (pci_enable_msi(pci) < 0) |
1514 | chip->msi = 0; | 1531 | chip->msi = 0; |
1532 | } | ||
1515 | 1533 | ||
1516 | if (azx_acquire_irq(chip, 0) < 0) | 1534 | if (azx_acquire_irq(chip, 0) < 0) |
1517 | return -EBUSY; | 1535 | return -EBUSY; |
@@ -1522,9 +1540,14 @@ static int azx_first_init(struct azx *chip) | |||
1522 | gcap = azx_readw(chip, GCAP); | 1540 | gcap = azx_readw(chip, GCAP); |
1523 | dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap); | 1541 | dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap); |
1524 | 1542 | ||
1543 | /* AMD devices support 40 or 48bit DMA, take the safe one */ | ||
1544 | if (chip->pci->vendor == PCI_VENDOR_ID_AMD) | ||
1545 | dma_bits = 40; | ||
1546 | |||
1525 | /* disable SB600 64bit support for safety */ | 1547 | /* disable SB600 64bit support for safety */ |
1526 | if (chip->pci->vendor == PCI_VENDOR_ID_ATI) { | 1548 | if (chip->pci->vendor == PCI_VENDOR_ID_ATI) { |
1527 | struct pci_dev *p_smbus; | 1549 | struct pci_dev *p_smbus; |
1550 | dma_bits = 40; | ||
1528 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, | 1551 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, |
1529 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, | 1552 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, |
1530 | NULL); | 1553 | NULL); |
@@ -1545,18 +1568,18 @@ static int azx_first_init(struct azx *chip) | |||
1545 | if (align_buffer_size >= 0) | 1568 | if (align_buffer_size >= 0) |
1546 | chip->align_buffer_size = !!align_buffer_size; | 1569 | chip->align_buffer_size = !!align_buffer_size; |
1547 | else { | 1570 | else { |
1548 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | 1571 | if (chip->driver_caps & AZX_DCAPS_NO_ALIGN_BUFSIZE) |
1549 | chip->align_buffer_size = 0; | 1572 | chip->align_buffer_size = 0; |
1550 | else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE) | ||
1551 | chip->align_buffer_size = 1; | ||
1552 | else | 1573 | else |
1553 | chip->align_buffer_size = 1; | 1574 | chip->align_buffer_size = 1; |
1554 | } | 1575 | } |
1555 | 1576 | ||
1556 | /* allow 64bit DMA address if supported by H/W */ | 1577 | /* allow 64bit DMA address if supported by H/W */ |
1557 | if ((gcap & AZX_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 1578 | if (!(gcap & AZX_GCAP_64OK)) |
1558 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); | 1579 | dma_bits = 32; |
1559 | else { | 1580 | if (!pci_set_dma_mask(pci, DMA_BIT_MASK(dma_bits))) { |
1581 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(dma_bits)); | ||
1582 | } else { | ||
1560 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); | 1583 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); |
1561 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); | 1584 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); |
1562 | } | 1585 | } |
@@ -2033,36 +2056,35 @@ static const struct pci_device_id azx_ids[] = { | |||
2033 | /* Braswell */ | 2056 | /* Braswell */ |
2034 | { PCI_DEVICE(0x8086, 0x2284), | 2057 | { PCI_DEVICE(0x8086, 0x2284), |
2035 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 2058 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
2036 | /* ICH */ | 2059 | /* ICH6 */ |
2037 | { PCI_DEVICE(0x8086, 0x2668), | 2060 | { PCI_DEVICE(0x8086, 0x2668), |
2038 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2061 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2039 | AZX_DCAPS_BUFSIZE }, /* ICH6 */ | 2062 | /* ICH7 */ |
2040 | { PCI_DEVICE(0x8086, 0x27d8), | 2063 | { PCI_DEVICE(0x8086, 0x27d8), |
2041 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2064 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2042 | AZX_DCAPS_BUFSIZE }, /* ICH7 */ | 2065 | /* ESB2 */ |
2043 | { PCI_DEVICE(0x8086, 0x269a), | 2066 | { PCI_DEVICE(0x8086, 0x269a), |
2044 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2067 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2045 | AZX_DCAPS_BUFSIZE }, /* ESB2 */ | 2068 | /* ICH8 */ |
2046 | { PCI_DEVICE(0x8086, 0x284b), | 2069 | { PCI_DEVICE(0x8086, 0x284b), |
2047 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2070 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2048 | AZX_DCAPS_BUFSIZE }, /* ICH8 */ | 2071 | /* ICH9 */ |
2049 | { PCI_DEVICE(0x8086, 0x293e), | 2072 | { PCI_DEVICE(0x8086, 0x293e), |
2050 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2073 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2051 | AZX_DCAPS_BUFSIZE }, /* ICH9 */ | 2074 | /* ICH9 */ |
2052 | { PCI_DEVICE(0x8086, 0x293f), | 2075 | { PCI_DEVICE(0x8086, 0x293f), |
2053 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2076 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2054 | AZX_DCAPS_BUFSIZE }, /* ICH9 */ | 2077 | /* ICH10 */ |
2055 | { PCI_DEVICE(0x8086, 0x3a3e), | 2078 | { PCI_DEVICE(0x8086, 0x3a3e), |
2056 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2079 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2057 | AZX_DCAPS_BUFSIZE }, /* ICH10 */ | 2080 | /* ICH10 */ |
2058 | { PCI_DEVICE(0x8086, 0x3a6e), | 2081 | { PCI_DEVICE(0x8086, 0x3a6e), |
2059 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 2082 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH }, |
2060 | AZX_DCAPS_BUFSIZE }, /* ICH10 */ | ||
2061 | /* Generic Intel */ | 2083 | /* Generic Intel */ |
2062 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), | 2084 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), |
2063 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2085 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2064 | .class_mask = 0xffffff, | 2086 | .class_mask = 0xffffff, |
2065 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE }, | 2087 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE }, |
2066 | /* ATI SB 450/600/700/800/900 */ | 2088 | /* ATI SB 450/600/700/800/900 */ |
2067 | { PCI_DEVICE(0x1002, 0x437b), | 2089 | { PCI_DEVICE(0x1002, 0x437b), |
2068 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, | 2090 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, |
@@ -2117,13 +2139,13 @@ static const struct pci_device_id azx_ids[] = { | |||
2117 | { PCI_DEVICE(0x1002, 0xaa98), | 2139 | { PCI_DEVICE(0x1002, 0xaa98), |
2118 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | 2140 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2119 | { PCI_DEVICE(0x1002, 0x9902), | 2141 | { PCI_DEVICE(0x1002, 0x9902), |
2120 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | 2142 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, |
2121 | { PCI_DEVICE(0x1002, 0xaaa0), | 2143 | { PCI_DEVICE(0x1002, 0xaaa0), |
2122 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | 2144 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, |
2123 | { PCI_DEVICE(0x1002, 0xaaa8), | 2145 | { PCI_DEVICE(0x1002, 0xaaa8), |
2124 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | 2146 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, |
2125 | { PCI_DEVICE(0x1002, 0xaab0), | 2147 | { PCI_DEVICE(0x1002, 0xaab0), |
2126 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | 2148 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, |
2127 | /* VIA VT8251/VT8237A */ | 2149 | /* VIA VT8251/VT8237A */ |
2128 | { PCI_DEVICE(0x1106, 0x3288), | 2150 | { PCI_DEVICE(0x1106, 0x3288), |
2129 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, | 2151 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, |
@@ -2170,7 +2192,7 @@ static const struct pci_device_id azx_ids[] = { | |||
2170 | /* CM8888 */ | 2192 | /* CM8888 */ |
2171 | { PCI_DEVICE(0x13f6, 0x5011), | 2193 | { PCI_DEVICE(0x13f6, 0x5011), |
2172 | .driver_data = AZX_DRIVER_CMEDIA | | 2194 | .driver_data = AZX_DRIVER_CMEDIA | |
2173 | AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB }, | 2195 | AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF }, |
2174 | /* Vortex86MX */ | 2196 | /* Vortex86MX */ |
2175 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | 2197 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, |
2176 | /* VMware HDAudio */ | 2198 | /* VMware HDAudio */ |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index f56765ae73a7..e664307617bd 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -20,6 +20,16 @@ | |||
20 | #include "hda_auto_parser.h" | 20 | #include "hda_auto_parser.h" |
21 | #include "hda_jack.h" | 21 | #include "hda_jack.h" |
22 | 22 | ||
23 | /** | ||
24 | * is_jack_detectable - Check whether the given pin is jack-detectable | ||
25 | * @codec: the HDA codec | ||
26 | * @nid: pin NID | ||
27 | * | ||
28 | * Check whether the given pin is capable to report the jack detection. | ||
29 | * The jack detection might not work by various reasons, e.g. the jack | ||
30 | * detection is prohibited in the codec level, the pin config has | ||
31 | * AC_DEFCFG_MISC_NO_PRESENCE bit, no unsol support, etc. | ||
32 | */ | ||
23 | bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 33 | bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
24 | { | 34 | { |
25 | if (codec->no_jack_detect) | 35 | if (codec->no_jack_detect) |
@@ -57,6 +67,8 @@ static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) | |||
57 | 67 | ||
58 | /** | 68 | /** |
59 | * snd_hda_jack_tbl_get - query the jack-table entry for the given NID | 69 | * snd_hda_jack_tbl_get - query the jack-table entry for the given NID |
70 | * @codec: the HDA codec | ||
71 | * @nid: pin NID to refer to | ||
60 | */ | 72 | */ |
61 | struct hda_jack_tbl * | 73 | struct hda_jack_tbl * |
62 | snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) | 74 | snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) |
@@ -75,6 +87,8 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get); | |||
75 | 87 | ||
76 | /** | 88 | /** |
77 | * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag | 89 | * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag |
90 | * @codec: the HDA codec | ||
91 | * @tag: tag value to refer to | ||
78 | */ | 92 | */ |
79 | struct hda_jack_tbl * | 93 | struct hda_jack_tbl * |
80 | snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) | 94 | snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) |
@@ -93,6 +107,8 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag); | |||
93 | 107 | ||
94 | /** | 108 | /** |
95 | * snd_hda_jack_tbl_new - create a jack-table entry for the given NID | 109 | * snd_hda_jack_tbl_new - create a jack-table entry for the given NID |
110 | * @codec: the HDA codec | ||
111 | * @nid: pin NID to assign | ||
96 | */ | 112 | */ |
97 | static struct hda_jack_tbl * | 113 | static struct hda_jack_tbl * |
98 | snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) | 114 | snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) |
@@ -162,6 +178,7 @@ static void jack_detect_update(struct hda_codec *codec, | |||
162 | 178 | ||
163 | /** | 179 | /** |
164 | * snd_hda_set_dirty_all - Mark all the cached as dirty | 180 | * snd_hda_set_dirty_all - Mark all the cached as dirty |
181 | * @codec: the HDA codec | ||
165 | * | 182 | * |
166 | * This function sets the dirty flag to all entries of jack table. | 183 | * This function sets the dirty flag to all entries of jack table. |
167 | * It's called from the resume path in hda_codec.c. | 184 | * It's called from the resume path in hda_codec.c. |
@@ -218,6 +235,9 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state); | |||
218 | 235 | ||
219 | /** | 236 | /** |
220 | * snd_hda_jack_detect_enable - enable the jack-detection | 237 | * snd_hda_jack_detect_enable - enable the jack-detection |
238 | * @codec: the HDA codec | ||
239 | * @nid: pin NID to enable | ||
240 | * @func: callback function to register | ||
221 | * | 241 | * |
222 | * In the case of error, the return value will be a pointer embedded with | 242 | * In the case of error, the return value will be a pointer embedded with |
223 | * errno. Check and handle the return value appropriately with standard | 243 | * errno. Check and handle the return value appropriately with standard |
@@ -258,6 +278,14 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, | |||
258 | } | 278 | } |
259 | EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); | 279 | EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); |
260 | 280 | ||
281 | /** | ||
282 | * snd_hda_jack_detect_enable - Enable the jack detection on the given pin | ||
283 | * @codec: the HDA codec | ||
284 | * @nid: pin NID to enable jack detection | ||
285 | * | ||
286 | * Enable the jack detection with the default callback. Returns zero if | ||
287 | * successful or a negative error code. | ||
288 | */ | ||
261 | int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid) | 289 | int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid) |
262 | { | 290 | { |
263 | return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL)); | 291 | return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL)); |
@@ -266,6 +294,9 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); | |||
266 | 294 | ||
267 | /** | 295 | /** |
268 | * snd_hda_jack_set_gating_jack - Set gating jack. | 296 | * snd_hda_jack_set_gating_jack - Set gating jack. |
297 | * @codec: the HDA codec | ||
298 | * @gated_nid: gated pin NID | ||
299 | * @gating_nid: gating pin NID | ||
269 | * | 300 | * |
270 | * Indicates the gated jack is only valid when the gating jack is plugged. | 301 | * Indicates the gated jack is only valid when the gating jack is plugged. |
271 | */ | 302 | */ |
@@ -287,6 +318,7 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack); | |||
287 | 318 | ||
288 | /** | 319 | /** |
289 | * snd_hda_jack_report_sync - sync the states of all jacks and report if changed | 320 | * snd_hda_jack_report_sync - sync the states of all jacks and report if changed |
321 | * @codec: the HDA codec | ||
290 | */ | 322 | */ |
291 | void snd_hda_jack_report_sync(struct hda_codec *codec) | 323 | void snd_hda_jack_report_sync(struct hda_codec *codec) |
292 | { | 324 | { |
@@ -349,6 +381,11 @@ static void hda_free_jack_priv(struct snd_jack *jack) | |||
349 | 381 | ||
350 | /** | 382 | /** |
351 | * snd_hda_jack_add_kctl - Add a kctl for the given pin | 383 | * snd_hda_jack_add_kctl - Add a kctl for the given pin |
384 | * @codec: the HDA codec | ||
385 | * @nid: pin NID to assign | ||
386 | * @name: string name for the jack | ||
387 | * @idx: index number for the jack | ||
388 | * @phantom_jack: flag to deal as a phantom jack | ||
352 | * | 389 | * |
353 | * This assigns a jack-detection kctl to the given pin. The kcontrol | 390 | * This assigns a jack-detection kctl to the given pin. The kcontrol |
354 | * will have the given name and index. | 391 | * will have the given name and index. |
@@ -391,6 +428,15 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
391 | return 0; | 428 | return 0; |
392 | } | 429 | } |
393 | 430 | ||
431 | /** | ||
432 | * snd_hda_jack_add_kctl - Add a jack kctl for the given pin | ||
433 | * @codec: the HDA codec | ||
434 | * @nid: pin NID | ||
435 | * @name: the name string for the jack ctl | ||
436 | * @idx: the ctl index for the jack ctl | ||
437 | * | ||
438 | * This is a simple helper calling __snd_hda_jack_add_kctl(). | ||
439 | */ | ||
394 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | 440 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, |
395 | const char *name, int idx) | 441 | const char *name, int idx) |
396 | { | 442 | { |
@@ -456,6 +502,8 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
456 | 502 | ||
457 | /** | 503 | /** |
458 | * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg | 504 | * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg |
505 | * @codec: the HDA codec | ||
506 | * @cfg: pin config table to parse | ||
459 | */ | 507 | */ |
460 | int snd_hda_jack_add_kctls(struct hda_codec *codec, | 508 | int snd_hda_jack_add_kctls(struct hda_codec *codec, |
461 | const struct auto_pin_cfg *cfg) | 509 | const struct auto_pin_cfg *cfg) |
@@ -531,6 +579,11 @@ static void call_jack_callback(struct hda_codec *codec, | |||
531 | } | 579 | } |
532 | } | 580 | } |
533 | 581 | ||
582 | /** | ||
583 | * snd_hda_jack_unsol_event - Handle an unsolicited event | ||
584 | * @codec: the HDA codec | ||
585 | * @res: the unsolicited event data | ||
586 | */ | ||
534 | void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) | 587 | void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) |
535 | { | 588 | { |
536 | struct hda_jack_tbl *event; | 589 | struct hda_jack_tbl *event; |
@@ -546,6 +599,13 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) | |||
546 | } | 599 | } |
547 | EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event); | 600 | EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event); |
548 | 601 | ||
602 | /** | ||
603 | * snd_hda_jack_poll_all - Poll all jacks | ||
604 | * @codec: the HDA codec | ||
605 | * | ||
606 | * Poll all detectable jacks with dirty flag, update the status, call | ||
607 | * callbacks and call snd_hda_jack_report_sync() if any changes are found. | ||
608 | */ | ||
549 | void snd_hda_jack_poll_all(struct hda_codec *codec) | 609 | void snd_hda_jack_poll_all(struct hda_codec *codec) |
550 | { | 610 | { |
551 | struct hda_jack_tbl *jack = codec->jacktbl.list; | 611 | struct hda_jack_tbl *jack = codec->jacktbl.list; |
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 13cb375454f6..b279e327a23b 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h | |||
@@ -72,6 +72,11 @@ enum { | |||
72 | 72 | ||
73 | int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid); | 73 | int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid); |
74 | 74 | ||
75 | /** | ||
76 | * snd_hda_jack_detect - Detect the jack | ||
77 | * @codec: the HDA codec | ||
78 | * @nid: pin NID to check jack detection | ||
79 | */ | ||
75 | static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) | 80 | static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) |
76 | { | 81 | { |
77 | return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT; | 82 | return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT; |
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h index 949cd437eeb2..aa484fdf4338 100644 --- a/sound/pci/hda/hda_priv.h +++ b/sound/pci/hda/hda_priv.h | |||
@@ -152,9 +152,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
152 | /* bits 0-7 are used for indicating driver type */ | 152 | /* bits 0-7 are used for indicating driver type */ |
153 | #define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */ | 153 | #define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */ |
154 | #define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ | 154 | #define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ |
155 | #define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */ | 155 | #define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */ |
156 | #define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */ | 156 | #define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */ |
157 | #define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */ | ||
158 | #define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ | 157 | #define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ |
159 | #define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ | 158 | #define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ |
160 | #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ | 159 | #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ |
@@ -163,14 +162,22 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
163 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ | 162 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ |
164 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | 163 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
165 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | 164 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
166 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 165 | #define AZX_DCAPS_NO_ALIGN_BUFSIZE (1 << 21) /* no buffer size alignment */ |
167 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | 166 | /* 22 unused */ |
168 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ | 167 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ |
169 | #define AZX_DCAPS_REVERSE_ASSIGN (1 << 24) /* Assign devices in reverse order */ | 168 | #define AZX_DCAPS_REVERSE_ASSIGN (1 << 24) /* Assign devices in reverse order */ |
170 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ | 169 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ |
171 | #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ | 170 | #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ |
172 | #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ | 171 | #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ |
173 | #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ | 172 | #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ |
173 | #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ | ||
174 | |||
175 | enum { | ||
176 | AZX_SNOOP_TYPE_NONE , | ||
177 | AZX_SNOOP_TYPE_SCH, | ||
178 | AZX_SNOOP_TYPE_ATI, | ||
179 | AZX_SNOOP_TYPE_NVIDIA, | ||
180 | }; | ||
174 | 181 | ||
175 | /* HD Audio class code */ | 182 | /* HD Audio class code */ |
176 | #define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403 | 183 | #define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403 |
diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c index 9b49f156a12e..bef721592c3a 100644 --- a/sound/pci/hda/hda_sysfs.c +++ b/sound/pci/hda/hda_sysfs.c | |||
@@ -417,8 +417,13 @@ static DEVICE_ATTR_RW(user_pin_configs); | |||
417 | static DEVICE_ATTR_WO(reconfig); | 417 | static DEVICE_ATTR_WO(reconfig); |
418 | static DEVICE_ATTR_WO(clear); | 418 | static DEVICE_ATTR_WO(clear); |
419 | 419 | ||
420 | /* | 420 | /** |
421 | * Look for hint string | 421 | * snd_hda_get_hint - Look for hint string |
422 | * @codec: the HDA codec | ||
423 | * @key: the hint key string | ||
424 | * | ||
425 | * Look for a hint key/value pair matching with the given key string | ||
426 | * and returns the value string. If nothing found, returns NULL. | ||
422 | */ | 427 | */ |
423 | const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) | 428 | const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) |
424 | { | 429 | { |
@@ -427,6 +432,15 @@ const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) | |||
427 | } | 432 | } |
428 | EXPORT_SYMBOL_GPL(snd_hda_get_hint); | 433 | EXPORT_SYMBOL_GPL(snd_hda_get_hint); |
429 | 434 | ||
435 | /** | ||
436 | * snd_hda_get_bool_hint - Get a boolean hint value | ||
437 | * @codec: the HDA codec | ||
438 | * @key: the hint key string | ||
439 | * | ||
440 | * Look for a hint key/value pair matching with the given key string | ||
441 | * and returns a boolean value parsed from the value. If no matching | ||
442 | * key is found, return a negative value. | ||
443 | */ | ||
430 | int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) | 444 | int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) |
431 | { | 445 | { |
432 | const char *p; | 446 | const char *p; |
@@ -453,6 +467,16 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) | |||
453 | } | 467 | } |
454 | EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint); | 468 | EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint); |
455 | 469 | ||
470 | /** | ||
471 | * snd_hda_get_bool_hint - Get a boolean hint value | ||
472 | * @codec: the HDA codec | ||
473 | * @key: the hint key string | ||
474 | * @valp: pointer to store a value | ||
475 | * | ||
476 | * Look for a hint key/value pair matching with the given key string | ||
477 | * and stores the integer value to @valp. If no matching key is found, | ||
478 | * return a negative error code. Otherwise it returns zero. | ||
479 | */ | ||
456 | int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) | 480 | int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) |
457 | { | 481 | { |
458 | const char *p; | 482 | const char *p; |
@@ -690,8 +714,11 @@ static int get_line_from_fw(char *buf, int size, size_t *fw_size_p, | |||
690 | return 1; | 714 | return 1; |
691 | } | 715 | } |
692 | 716 | ||
693 | /* | 717 | /** |
694 | * load a "patch" firmware file and parse it | 718 | * snd_hda_load_patch - load a "patch" firmware file and parse it |
719 | * @bus: HD-audio bus | ||
720 | * @fw_size: the firmware byte size | ||
721 | * @fw_buf: the firmware data | ||
695 | */ | 722 | */ |
696 | int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf) | 723 | int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf) |
697 | { | 724 | { |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 4f7ffa8c4a0d..e0383eea9880 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -2417,7 +2417,7 @@ static int dspxfr_one_seg(struct hda_codec *codec, | |||
2417 | * @reloc: Relocation address for loading single-segment overlays, or 0 for | 2417 | * @reloc: Relocation address for loading single-segment overlays, or 0 for |
2418 | * no relocation | 2418 | * no relocation |
2419 | * @sample_rate: sampling rate of the stream used for DSP download | 2419 | * @sample_rate: sampling rate of the stream used for DSP download |
2420 | * @number_channels: channels of the stream used for DSP download | 2420 | * @channels: channels of the stream used for DSP download |
2421 | * @ovly: TRUE if overlay format is required | 2421 | * @ovly: TRUE if overlay format is required |
2422 | * | 2422 | * |
2423 | * Returns zero or a negative error code. | 2423 | * Returns zero or a negative error code. |
@@ -2556,10 +2556,7 @@ static void dspload_post_setup(struct hda_codec *codec) | |||
2556 | } | 2556 | } |
2557 | 2557 | ||
2558 | /** | 2558 | /** |
2559 | * Download DSP from a DSP Image Fast Load structure. This structure is a | 2559 | * dspload_image - Download DSP from a DSP Image Fast Load structure. |
2560 | * linear, non-constant sized element array of structures, each of which | ||
2561 | * contain the count of the data to be loaded, the data itself, and the | ||
2562 | * corresponding starting chip address of the starting data location. | ||
2563 | * | 2560 | * |
2564 | * @codec: the HDA codec | 2561 | * @codec: the HDA codec |
2565 | * @fls: pointer to a fast load image | 2562 | * @fls: pointer to a fast load image |
@@ -2570,6 +2567,10 @@ static void dspload_post_setup(struct hda_codec *codec) | |||
2570 | * @router_chans: number of audio router channels to be allocated (0 means use | 2567 | * @router_chans: number of audio router channels to be allocated (0 means use |
2571 | * internal defaults; max is 32) | 2568 | * internal defaults; max is 32) |
2572 | * | 2569 | * |
2570 | * Download DSP from a DSP Image Fast Load structure. This structure is a | ||
2571 | * linear, non-constant sized element array of structures, each of which | ||
2572 | * contain the count of the data to be loaded, the data itself, and the | ||
2573 | * corresponding starting chip address of the starting data location. | ||
2573 | * Returns zero or a negative error code. | 2574 | * Returns zero or a negative error code. |
2574 | */ | 2575 | */ |
2575 | static int dspload_image(struct hda_codec *codec, | 2576 | static int dspload_image(struct hda_codec *codec, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c5ad83e4e0c7..a722067c491c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -96,6 +96,8 @@ struct alc_spec { | |||
96 | hda_nid_t cap_mute_led_nid; | 96 | hda_nid_t cap_mute_led_nid; |
97 | 97 | ||
98 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | 98 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ |
99 | unsigned int gpio_mute_led_mask; | ||
100 | unsigned int gpio_mic_led_mask; | ||
99 | 101 | ||
100 | hda_nid_t headset_mic_pin; | 102 | hda_nid_t headset_mic_pin; |
101 | hda_nid_t headphone_mic_pin; | 103 | hda_nid_t headphone_mic_pin; |
@@ -3310,41 +3312,45 @@ static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | |||
3310 | } | 3312 | } |
3311 | } | 3313 | } |
3312 | 3314 | ||
3313 | /* turn on/off mute LED per vmaster hook */ | 3315 | /* update LED status via GPIO */ |
3314 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | 3316 | static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, |
3317 | bool enabled) | ||
3315 | { | 3318 | { |
3316 | struct hda_codec *codec = private_data; | ||
3317 | struct alc_spec *spec = codec->spec; | 3319 | struct alc_spec *spec = codec->spec; |
3318 | unsigned int oldval = spec->gpio_led; | 3320 | unsigned int oldval = spec->gpio_led; |
3319 | 3321 | ||
3322 | if (spec->mute_led_polarity) | ||
3323 | enabled = !enabled; | ||
3324 | |||
3320 | if (enabled) | 3325 | if (enabled) |
3321 | spec->gpio_led &= ~0x08; | 3326 | spec->gpio_led &= ~mask; |
3322 | else | 3327 | else |
3323 | spec->gpio_led |= 0x08; | 3328 | spec->gpio_led |= mask; |
3324 | if (spec->gpio_led != oldval) | 3329 | if (spec->gpio_led != oldval) |
3325 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3330 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3326 | spec->gpio_led); | 3331 | spec->gpio_led); |
3327 | } | 3332 | } |
3328 | 3333 | ||
3329 | /* turn on/off mic-mute LED per capture hook */ | 3334 | /* turn on/off mute LED via GPIO per vmaster hook */ |
3330 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | 3335 | static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) |
3331 | struct snd_kcontrol *kcontrol, | ||
3332 | struct snd_ctl_elem_value *ucontrol) | ||
3333 | { | 3336 | { |
3337 | struct hda_codec *codec = private_data; | ||
3334 | struct alc_spec *spec = codec->spec; | 3338 | struct alc_spec *spec = codec->spec; |
3335 | unsigned int oldval = spec->gpio_led; | ||
3336 | 3339 | ||
3337 | if (!ucontrol) | 3340 | alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); |
3338 | return; | 3341 | } |
3339 | 3342 | ||
3340 | if (ucontrol->value.integer.value[0] || | 3343 | /* turn on/off mic-mute LED via GPIO per capture hook */ |
3341 | ucontrol->value.integer.value[1]) | 3344 | static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec, |
3342 | spec->gpio_led &= ~0x10; | 3345 | struct snd_kcontrol *kcontrol, |
3343 | else | 3346 | struct snd_ctl_elem_value *ucontrol) |
3344 | spec->gpio_led |= 0x10; | 3347 | { |
3345 | if (spec->gpio_led != oldval) | 3348 | struct alc_spec *spec = codec->spec; |
3346 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3349 | |
3347 | spec->gpio_led); | 3350 | if (ucontrol) |
3351 | alc_update_gpio_led(codec, spec->gpio_mic_led_mask, | ||
3352 | ucontrol->value.integer.value[0] || | ||
3353 | ucontrol->value.integer.value[1]); | ||
3348 | } | 3354 | } |
3349 | 3355 | ||
3350 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | 3356 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, |
@@ -3358,9 +3364,33 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | |||
3358 | }; | 3364 | }; |
3359 | 3365 | ||
3360 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3366 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3361 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3367 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
3362 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | 3368 | spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; |
3369 | spec->gpio_led = 0; | ||
3370 | spec->mute_led_polarity = 0; | ||
3371 | spec->gpio_mute_led_mask = 0x08; | ||
3372 | spec->gpio_mic_led_mask = 0x10; | ||
3373 | snd_hda_add_verbs(codec, gpio_init); | ||
3374 | } | ||
3375 | } | ||
3376 | |||
3377 | static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, | ||
3378 | const struct hda_fixup *fix, int action) | ||
3379 | { | ||
3380 | struct alc_spec *spec = codec->spec; | ||
3381 | static const struct hda_verb gpio_init[] = { | ||
3382 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 }, | ||
3383 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 }, | ||
3384 | {} | ||
3385 | }; | ||
3386 | |||
3387 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3388 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; | ||
3389 | spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; | ||
3363 | spec->gpio_led = 0; | 3390 | spec->gpio_led = 0; |
3391 | spec->mute_led_polarity = 0; | ||
3392 | spec->gpio_mute_led_mask = 0x02; | ||
3393 | spec->gpio_mic_led_mask = 0x20; | ||
3364 | snd_hda_add_verbs(codec, gpio_init); | 3394 | snd_hda_add_verbs(codec, gpio_init); |
3365 | } | 3395 | } |
3366 | } | 3396 | } |
@@ -3402,9 +3432,11 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, | |||
3402 | }; | 3432 | }; |
3403 | 3433 | ||
3404 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3434 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3405 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3435 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
3406 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; | 3436 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; |
3407 | spec->gpio_led = 0; | 3437 | spec->gpio_led = 0; |
3438 | spec->mute_led_polarity = 0; | ||
3439 | spec->gpio_mute_led_mask = 0x08; | ||
3408 | spec->cap_mute_led_nid = 0x18; | 3440 | spec->cap_mute_led_nid = 0x18; |
3409 | snd_hda_add_verbs(codec, gpio_init); | 3441 | snd_hda_add_verbs(codec, gpio_init); |
3410 | codec->power_filter = led_power_filter; | 3442 | codec->power_filter = led_power_filter; |
@@ -3423,9 +3455,11 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, | |||
3423 | }; | 3455 | }; |
3424 | 3456 | ||
3425 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3457 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3426 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3458 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
3427 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; | 3459 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; |
3428 | spec->gpio_led = 0; | 3460 | spec->gpio_led = 0; |
3461 | spec->mute_led_polarity = 0; | ||
3462 | spec->gpio_mute_led_mask = 0x08; | ||
3429 | spec->cap_mute_led_nid = 0x18; | 3463 | spec->cap_mute_led_nid = 0x18; |
3430 | snd_hda_add_verbs(codec, gpio_init); | 3464 | snd_hda_add_verbs(codec, gpio_init); |
3431 | codec->power_filter = led_power_filter; | 3465 | codec->power_filter = led_power_filter; |
@@ -4300,6 +4334,7 @@ enum { | |||
4300 | ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, | 4334 | ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, |
4301 | ALC282_FIXUP_ASPIRE_V5_PINS, | 4335 | ALC282_FIXUP_ASPIRE_V5_PINS, |
4302 | ALC280_FIXUP_HP_GPIO4, | 4336 | ALC280_FIXUP_HP_GPIO4, |
4337 | ALC286_FIXUP_HP_GPIO_LED, | ||
4303 | }; | 4338 | }; |
4304 | 4339 | ||
4305 | static const struct hda_fixup alc269_fixups[] = { | 4340 | static const struct hda_fixup alc269_fixups[] = { |
@@ -4769,6 +4804,10 @@ static const struct hda_fixup alc269_fixups[] = { | |||
4769 | .type = HDA_FIXUP_FUNC, | 4804 | .type = HDA_FIXUP_FUNC, |
4770 | .v.func = alc280_fixup_hp_gpio4, | 4805 | .v.func = alc280_fixup_hp_gpio4, |
4771 | }, | 4806 | }, |
4807 | [ALC286_FIXUP_HP_GPIO_LED] = { | ||
4808 | .type = HDA_FIXUP_FUNC, | ||
4809 | .v.func = alc286_fixup_hp_gpio_led, | ||
4810 | }, | ||
4772 | }; | 4811 | }; |
4773 | 4812 | ||
4774 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4813 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -4809,6 +4848,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4809 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4848 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4810 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4849 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4811 | SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4850 | SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4851 | SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), | ||
4812 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4852 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4813 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4853 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4814 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4854 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
@@ -5698,22 +5738,6 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec, | |||
5698 | } | 5738 | } |
5699 | } | 5739 | } |
5700 | 5740 | ||
5701 | /* turn on/off mute LED per vmaster hook */ | ||
5702 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) | ||
5703 | { | ||
5704 | struct hda_codec *codec = private_data; | ||
5705 | struct alc_spec *spec = codec->spec; | ||
5706 | unsigned int oldval = spec->gpio_led; | ||
5707 | |||
5708 | if (enabled) | ||
5709 | spec->gpio_led |= 0x01; | ||
5710 | else | ||
5711 | spec->gpio_led &= ~0x01; | ||
5712 | if (spec->gpio_led != oldval) | ||
5713 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
5714 | spec->gpio_led); | ||
5715 | } | ||
5716 | |||
5717 | /* avoid D3 for keeping GPIO up */ | 5741 | /* avoid D3 for keeping GPIO up */ |
5718 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, | 5742 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, |
5719 | hda_nid_t nid, | 5743 | hda_nid_t nid, |
@@ -5736,8 +5760,10 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec, | |||
5736 | }; | 5760 | }; |
5737 | 5761 | ||
5738 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5762 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5739 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; | 5763 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
5740 | spec->gpio_led = 0; | 5764 | spec->gpio_led = 0; |
5765 | spec->mute_led_polarity = 1; | ||
5766 | spec->gpio_mute_led_mask = 0x01; | ||
5741 | snd_hda_add_verbs(codec, gpio_init); | 5767 | snd_hda_add_verbs(codec, gpio_init); |
5742 | codec->power_filter = gpio_led_power_filter; | 5768 | codec->power_filter = gpio_led_power_filter; |
5743 | } | 5769 | } |
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 3b3cf4ac9060..c9411dfff5a4 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c | |||
@@ -205,13 +205,7 @@ static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol, | |||
205 | static const char * const texts[3] = | 205 | static const char * const texts[3] = |
206 | {"Internal Aux", "Wavetable", "Rear Line-In"}; | 206 | {"Internal Aux", "Wavetable", "Rear Line-In"}; |
207 | 207 | ||
208 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 208 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
209 | uinfo->count = 1; | ||
210 | uinfo->value.enumerated.items = 3; | ||
211 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
212 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
213 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
214 | return 0; | ||
215 | } | 209 | } |
216 | 210 | ||
217 | static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, | 211 | static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, |
@@ -1106,20 +1100,10 @@ static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in | |||
1106 | }; | 1100 | }; |
1107 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 1101 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
1108 | 1102 | ||
1109 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1103 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) |
1110 | uinfo->count = 2; | 1104 | return snd_ctl_enum_info(uinfo, 2, 8, universe_texts); |
1111 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) { | 1105 | else |
1112 | uinfo->value.enumerated.items = 8; | 1106 | return snd_ctl_enum_info(uinfo, 2, 5, texts); |
1113 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1114 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1115 | strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]); | ||
1116 | } else { | ||
1117 | uinfo->value.enumerated.items = 5; | ||
1118 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1119 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1120 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1121 | } | ||
1122 | return 0; | ||
1123 | } | 1107 | } |
1124 | 1108 | ||
1125 | static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1109 | static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1167,16 +1151,10 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1167 | "CD", | 1151 | "CD", |
1168 | "Coax" | 1152 | "Coax" |
1169 | }; | 1153 | }; |
1170 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1171 | uinfo->count = 1; | ||
1172 | uinfo->value.enumerated.items = 2; | ||
1173 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1174 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1175 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) | 1154 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) |
1176 | strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]); | 1155 | return snd_ctl_enum_info(uinfo, 1, 2, prodigy_texts); |
1177 | else | 1156 | else |
1178 | strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]); | 1157 | return snd_ctl_enum_info(uinfo, 1, 2, aureon_texts); |
1179 | return 0; | ||
1180 | } | 1158 | } |
1181 | 1159 | ||
1182 | static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1160 | static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1392,15 +1370,7 @@ static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_ | |||
1392 | { | 1370 | { |
1393 | static const char * const texts[2] = { "128x", "64x" }; | 1371 | static const char * const texts[2] = { "128x", "64x" }; |
1394 | 1372 | ||
1395 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1373 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
1396 | uinfo->count = 1; | ||
1397 | uinfo->value.enumerated.items = 2; | ||
1398 | |||
1399 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1400 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1401 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1402 | |||
1403 | return 0; | ||
1404 | } | 1374 | } |
1405 | 1375 | ||
1406 | static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1376 | static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 817a1bc50a60..5cb587cf360e 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c | |||
@@ -580,13 +580,7 @@ static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct s | |||
580 | static const char * const texts[2] = { | 580 | static const char * const texts[2] = { |
581 | "+4dBu", "-10dBV", | 581 | "+4dBu", "-10dBV", |
582 | }; | 582 | }; |
583 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 583 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
584 | uinfo->count = 1; | ||
585 | uinfo->value.enumerated.items = 2; | ||
586 | if (uinfo->value.enumerated.item >= 2) | ||
587 | uinfo->value.enumerated.item = 1; | ||
588 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
589 | return 0; | ||
590 | } | 584 | } |
591 | 585 | ||
592 | static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 586 | static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -903,13 +897,7 @@ static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, st | |||
903 | static const char * const texts[4] = { | 897 | static const char * const texts[4] = { |
904 | "Internal", "Front Input", "Rear Input", "Wave Table" | 898 | "Internal", "Front Input", "Rear Input", "Wave Table" |
905 | }; | 899 | }; |
906 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 900 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
907 | uinfo->count = 1; | ||
908 | uinfo->value.enumerated.items = 4; | ||
909 | if (uinfo->value.enumerated.item >= 4) | ||
910 | uinfo->value.enumerated.item = 1; | ||
911 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
912 | return 0; | ||
913 | } | 901 | } |
914 | 902 | ||
915 | static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 903 | static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 59e37c581691..a40001c1d9e8 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c | |||
@@ -309,11 +309,7 @@ static int snd_ice1712_value_init(struct snd_ice1712 *ice) | |||
309 | return err; | 309 | return err; |
310 | 310 | ||
311 | /* ak4524 controls */ | 311 | /* ak4524 controls */ |
312 | err = snd_ice1712_akm4xxx_build_controls(ice); | 312 | return snd_ice1712_akm4xxx_build_controls(ice); |
313 | if (err < 0) | ||
314 | return err; | ||
315 | |||
316 | return 0; | ||
317 | } | 313 | } |
318 | 314 | ||
319 | static int snd_ice1712_ez8_init(struct snd_ice1712 *ice) | 315 | static int snd_ice1712_ez8_init(struct snd_ice1712 *ice) |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 206ed2cbcef9..b039b46152c6 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -620,10 +620,9 @@ static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream) | |||
620 | { | 620 | { |
621 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); | 621 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); |
622 | struct snd_pcm_runtime *runtime = substream->runtime; | 622 | struct snd_pcm_runtime *runtime = substream->runtime; |
623 | u32 period_size, buf_size, rate, tmp, chn; | 623 | u32 period_size, rate, tmp, chn; |
624 | 624 | ||
625 | period_size = snd_pcm_lib_period_bytes(substream) - 1; | 625 | period_size = snd_pcm_lib_period_bytes(substream) - 1; |
626 | buf_size = snd_pcm_lib_buffer_bytes(substream) - 1; | ||
627 | tmp = 0x0064; | 626 | tmp = 0x0064; |
628 | if (snd_pcm_format_width(runtime->format) == 16) | 627 | if (snd_pcm_format_width(runtime->format) == 16) |
629 | tmp &= ~0x04; | 628 | tmp &= ~0x04; |
@@ -1295,10 +1294,7 @@ static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd | |||
1295 | return err; | 1294 | return err; |
1296 | } | 1295 | } |
1297 | 1296 | ||
1298 | err = snd_ice1712_build_pro_mixer(ice); | 1297 | return snd_ice1712_build_pro_mixer(ice); |
1299 | if (err < 0) | ||
1300 | return err; | ||
1301 | return 0; | ||
1302 | } | 1298 | } |
1303 | 1299 | ||
1304 | /* | 1300 | /* |
@@ -1545,10 +1541,9 @@ static int snd_ice1712_ac97_mixer(struct snd_ice1712 *ice) | |||
1545 | dev_warn(ice->card->dev, | 1541 | dev_warn(ice->card->dev, |
1546 | "cannot initialize ac97 for consumer, skipped\n"); | 1542 | "cannot initialize ac97 for consumer, skipped\n"); |
1547 | else { | 1543 | else { |
1548 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice)); | 1544 | return snd_ctl_add(ice->card, |
1549 | if (err < 0) | 1545 | snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, |
1550 | return err; | 1546 | ice)); |
1551 | return 0; | ||
1552 | } | 1547 | } |
1553 | } | 1548 | } |
1554 | 1549 | ||
@@ -1839,13 +1834,7 @@ static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol, | |||
1839 | "96000", /* 12: 7 */ | 1834 | "96000", /* 12: 7 */ |
1840 | "IEC958 Input", /* 13: -- */ | 1835 | "IEC958 Input", /* 13: -- */ |
1841 | }; | 1836 | }; |
1842 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1837 | return snd_ctl_enum_info(uinfo, 1, 14, texts); |
1843 | uinfo->count = 1; | ||
1844 | uinfo->value.enumerated.items = 14; | ||
1845 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1846 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1847 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1848 | return 0; | ||
1849 | } | 1838 | } |
1850 | 1839 | ||
1851 | static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, | 1840 | static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, |
@@ -1930,13 +1919,7 @@ static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcon | |||
1930 | "96000", /* 12: 7 */ | 1919 | "96000", /* 12: 7 */ |
1931 | /* "IEC958 Input", 13: -- */ | 1920 | /* "IEC958 Input", 13: -- */ |
1932 | }; | 1921 | }; |
1933 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1922 | return snd_ctl_enum_info(uinfo, 1, 13, texts); |
1934 | uinfo->count = 1; | ||
1935 | uinfo->value.enumerated.items = 13; | ||
1936 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1937 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1938 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1939 | return 0; | ||
1940 | } | 1923 | } |
1941 | 1924 | ||
1942 | static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol, | 1925 | static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol, |
@@ -2057,15 +2040,8 @@ static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, | |||
2057 | "IEC958 In L", "IEC958 In R", /* 9-10 */ | 2040 | "IEC958 In L", "IEC958 In R", /* 9-10 */ |
2058 | "Digital Mixer", /* 11 - optional */ | 2041 | "Digital Mixer", /* 11 - optional */ |
2059 | }; | 2042 | }; |
2060 | 2043 | int num_items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; | |
2061 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2044 | return snd_ctl_enum_info(uinfo, 1, num_items, texts); |
2062 | uinfo->count = 1; | ||
2063 | uinfo->value.enumerated.items = | ||
2064 | snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; | ||
2065 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2066 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2067 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2068 | return 0; | ||
2069 | } | 2045 | } |
2070 | 2046 | ||
2071 | static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol, | 2047 | static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol, |
@@ -2516,11 +2492,8 @@ static int snd_ice1712_build_controls(struct snd_ice1712 *ice) | |||
2516 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice)); | 2492 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice)); |
2517 | if (err < 0) | 2493 | if (err < 0) |
2518 | return err; | 2494 | return err; |
2519 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); | 2495 | return snd_ctl_add(ice->card, |
2520 | if (err < 0) | 2496 | snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); |
2521 | return err; | ||
2522 | |||
2523 | return 0; | ||
2524 | } | 2497 | } |
2525 | 2498 | ||
2526 | static int snd_ice1712_free(struct snd_ice1712 *ice) | 2499 | static int snd_ice1712_free(struct snd_ice1712 *ice) |
@@ -2905,8 +2878,7 @@ static int snd_ice1712_resume(struct device *dev) | |||
2905 | outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); | 2878 | outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); |
2906 | outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); | 2879 | outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); |
2907 | 2880 | ||
2908 | if (ice->ac97) | 2881 | snd_ac97_resume(ice->ac97); |
2909 | snd_ac97_resume(ice->ac97); | ||
2910 | 2882 | ||
2911 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 2883 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
2912 | return 0; | 2884 | return 0; |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 08cb08ac85e6..d73da157ea14 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -2049,13 +2049,7 @@ static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol, | |||
2049 | "IEC958 In L", "IEC958 In R", /* 3-4 */ | 2049 | "IEC958 In L", "IEC958 In R", /* 3-4 */ |
2050 | }; | 2050 | }; |
2051 | 2051 | ||
2052 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2052 | return snd_ctl_enum_info(uinfo, 1, 5, texts); |
2053 | uinfo->count = 1; | ||
2054 | uinfo->value.enumerated.items = 5; | ||
2055 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2056 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2057 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2058 | return 0; | ||
2059 | } | 2053 | } |
2060 | 2054 | ||
2061 | static inline int analog_route_shift(int idx) | 2055 | static inline int analog_route_shift(int idx) |
@@ -2503,11 +2497,8 @@ static int snd_vt1724_build_controls(struct snd_ice1712 *ice) | |||
2503 | return err; | 2497 | return err; |
2504 | } | 2498 | } |
2505 | 2499 | ||
2506 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice)); | 2500 | return snd_ctl_add(ice->card, |
2507 | if (err < 0) | 2501 | snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice)); |
2508 | return err; | ||
2509 | |||
2510 | return 0; | ||
2511 | } | 2502 | } |
2512 | 2503 | ||
2513 | static int snd_vt1724_free(struct snd_ice1712 *ice) | 2504 | static int snd_vt1724_free(struct snd_ice1712 *ice) |
@@ -2884,8 +2875,7 @@ static int snd_vt1724_resume(struct device *dev) | |||
2884 | outb(ice->pm_saved_spdif_cfg, ICEREG1724(ice, SPDIF_CFG)); | 2875 | outb(ice->pm_saved_spdif_cfg, ICEREG1724(ice, SPDIF_CFG)); |
2885 | outl(ice->pm_saved_route, ICEMT1724(ice, ROUTE_PLAYBACK)); | 2876 | outl(ice->pm_saved_route, ICEMT1724(ice, ROUTE_PLAYBACK)); |
2886 | 2877 | ||
2887 | if (ice->ac97) | 2878 | snd_ac97_resume(ice->ac97); |
2888 | snd_ac97_resume(ice->ac97); | ||
2889 | 2879 | ||
2890 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 2880 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
2891 | return 0; | 2881 | return 0; |
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 7a6c0786c55c..a1536c1a7ed4 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c | |||
@@ -475,11 +475,8 @@ static int juli_add_controls(struct snd_ice1712 *ice) | |||
475 | return err; | 475 | return err; |
476 | 476 | ||
477 | /* only capture SPDIF over AK4114 */ | 477 | /* only capture SPDIF over AK4114 */ |
478 | err = snd_ak4114_build(spec->ak4114, NULL, | 478 | return snd_ak4114_build(spec->ak4114, NULL, |
479 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); | 479 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); |
480 | if (err < 0) | ||
481 | return err; | ||
482 | return 0; | ||
483 | } | 480 | } |
484 | 481 | ||
485 | /* | 482 | /* |
diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 63aa39f06f02..7de25c4807fd 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c | |||
@@ -359,15 +359,7 @@ static int maya_rec_src_info(struct snd_kcontrol *kcontrol, | |||
359 | { | 359 | { |
360 | static const char * const texts[] = { "Line", "Mic" }; | 360 | static const char * const texts[] = { "Line", "Mic" }; |
361 | 361 | ||
362 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 362 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); |
363 | uinfo->count = 1; | ||
364 | uinfo->value.enumerated.items = ARRAY_SIZE(texts); | ||
365 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
366 | uinfo->value.enumerated.item = | ||
367 | uinfo->value.enumerated.items - 1; | ||
368 | strcpy(uinfo->value.enumerated.name, | ||
369 | texts[uinfo->value.enumerated.item]); | ||
370 | return 0; | ||
371 | } | 363 | } |
372 | 364 | ||
373 | static int maya_rec_src_get(struct snd_kcontrol *kcontrol, | 365 | static int maya_rec_src_get(struct snd_kcontrol *kcontrol, |
@@ -411,15 +403,7 @@ static int maya_pb_route_info(struct snd_kcontrol *kcontrol, | |||
411 | "Input 1", "Input 2", "Input 3", "Input 4" | 403 | "Input 1", "Input 2", "Input 3", "Input 4" |
412 | }; | 404 | }; |
413 | 405 | ||
414 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 406 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); |
415 | uinfo->count = 1; | ||
416 | uinfo->value.enumerated.items = ARRAY_SIZE(texts); | ||
417 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
418 | uinfo->value.enumerated.item = | ||
419 | uinfo->value.enumerated.items - 1; | ||
420 | strcpy(uinfo->value.enumerated.name, | ||
421 | texts[uinfo->value.enumerated.item]); | ||
422 | return 0; | ||
423 | } | 407 | } |
424 | 408 | ||
425 | static int maya_pb_route_shift(int idx) | 409 | static int maya_pb_route_shift(int idx) |
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 0011e04f36a2..e9ca89c9174b 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c | |||
@@ -723,17 +723,7 @@ static int phase28_oversampling_info(struct snd_kcontrol *k, | |||
723 | { | 723 | { |
724 | static const char * const texts[2] = { "128x", "64x" }; | 724 | static const char * const texts[2] = { "128x", "64x" }; |
725 | 725 | ||
726 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 726 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
727 | uinfo->count = 1; | ||
728 | uinfo->value.enumerated.items = 2; | ||
729 | |||
730 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
731 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - | ||
732 | 1; | ||
733 | strcpy(uinfo->value.enumerated.name, | ||
734 | texts[uinfo->value.enumerated.item]); | ||
735 | |||
736 | return 0; | ||
737 | } | 727 | } |
738 | 728 | ||
739 | static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, | 729 | static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 5555eb4b2400..5101f40f6fbd 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c | |||
@@ -417,13 +417,7 @@ static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_inf | |||
417 | "Optical", /* RXP1 */ | 417 | "Optical", /* RXP1 */ |
418 | "CD", /* RXP2 */ | 418 | "CD", /* RXP2 */ |
419 | }; | 419 | }; |
420 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 420 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
421 | uinfo->count = 1; | ||
422 | uinfo->value.enumerated.items = 3; | ||
423 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
424 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
425 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
426 | return 0; | ||
427 | } | 421 | } |
428 | 422 | ||
429 | static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 423 | static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index f3b491aa3e22..3919aed39ca0 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c | |||
@@ -284,15 +284,7 @@ static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, | |||
284 | { | 284 | { |
285 | static const char * const texts[2] = { "Line In", "Mic" }; | 285 | static const char * const texts[2] = { "Line In", "Mic" }; |
286 | 286 | ||
287 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 287 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
288 | uinfo->count = 1; | ||
289 | uinfo->value.enumerated.items = 2; | ||
290 | |||
291 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
292 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
293 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
294 | |||
295 | return 0; | ||
296 | } | 288 | } |
297 | 289 | ||
298 | 290 | ||
@@ -563,13 +555,7 @@ static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, | |||
563 | { | 555 | { |
564 | static const char * const texts[2] = { "Toslink", "Coax" }; | 556 | static const char * const texts[2] = { "Toslink", "Coax" }; |
565 | 557 | ||
566 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 558 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
567 | uinfo->count = 1; | ||
568 | uinfo->value.enumerated.items = 2; | ||
569 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
570 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
571 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
572 | return 0; | ||
573 | } | 559 | } |
574 | 560 | ||
575 | 561 | ||
@@ -772,10 +758,8 @@ static int prodigy192_init(struct snd_ice1712 *ice) | |||
772 | "AK4114 initialized with status %d\n", err); | 758 | "AK4114 initialized with status %d\n", err); |
773 | } else | 759 | } else |
774 | dev_dbg(ice->card->dev, "AK4114 not found\n"); | 760 | dev_dbg(ice->card->dev, "AK4114 not found\n"); |
775 | if (err < 0) | ||
776 | return err; | ||
777 | 761 | ||
778 | return 0; | 762 | return err; |
779 | } | 763 | } |
780 | 764 | ||
781 | 765 | ||
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 2261d1e49150..2697402b5195 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c | |||
@@ -537,7 +537,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, | |||
537 | static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, | 537 | static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, |
538 | struct snd_ctl_elem_info *uinfo) | 538 | struct snd_ctl_elem_info *uinfo) |
539 | { | 539 | { |
540 | static char* texts[32] = { | 540 | static const char * const texts[32] = { |
541 | "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2, | 541 | "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2, |
542 | WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3, | 542 | WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3, |
543 | WM_AIN1 "+" WM_AIN2 "+" WM_AIN3, | 543 | WM_AIN1 "+" WM_AIN2 "+" WM_AIN3, |
@@ -560,14 +560,7 @@ static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, | |||
560 | WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5 | 560 | WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5 |
561 | }; | 561 | }; |
562 | 562 | ||
563 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 563 | return snd_ctl_enum_info(uinfo, 1, 32, texts); |
564 | uinfo->count = 1; | ||
565 | uinfo->value.enumerated.items = 32; | ||
566 | if (uinfo->value.enumerated.item > 31) | ||
567 | uinfo->value.enumerated.item = 31; | ||
568 | strcpy(uinfo->value.enumerated.name, | ||
569 | texts[uinfo->value.enumerated.item]); | ||
570 | return 0; | ||
571 | } | 564 | } |
572 | 565 | ||
573 | static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, | 566 | static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index 2c2df4b74e01..6f55e02e5c84 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c | |||
@@ -46,7 +46,7 @@ struct qtet_kcontrol_private { | |||
46 | unsigned int bit; | 46 | unsigned int bit; |
47 | void (*set_register)(struct snd_ice1712 *ice, unsigned int val); | 47 | void (*set_register)(struct snd_ice1712 *ice, unsigned int val); |
48 | unsigned int (*get_register)(struct snd_ice1712 *ice); | 48 | unsigned int (*get_register)(struct snd_ice1712 *ice); |
49 | unsigned char * const texts[2]; | 49 | const char * const texts[2]; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | enum { | 52 | enum { |
@@ -554,17 +554,7 @@ static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol, | |||
554 | { | 554 | { |
555 | static const char * const texts[3] = | 555 | static const char * const texts[3] = |
556 | {"Line In 1/2", "Mic", "Mic + Low-cut"}; | 556 | {"Line In 1/2", "Mic", "Mic + Low-cut"}; |
557 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 557 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); |
558 | uinfo->count = 1; | ||
559 | uinfo->value.enumerated.items = ARRAY_SIZE(texts); | ||
560 | |||
561 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
562 | uinfo->value.enumerated.item = | ||
563 | uinfo->value.enumerated.items - 1; | ||
564 | strcpy(uinfo->value.enumerated.name, | ||
565 | texts[uinfo->value.enumerated.item]); | ||
566 | |||
567 | return 0; | ||
568 | } | 558 | } |
569 | 559 | ||
570 | static int qtet_ain12_sw_get(struct snd_kcontrol *kcontrol, | 560 | static int qtet_ain12_sw_get(struct snd_kcontrol *kcontrol, |
@@ -706,17 +696,8 @@ static int qtet_enum_info(struct snd_kcontrol *kcontrol, | |||
706 | { | 696 | { |
707 | struct qtet_kcontrol_private private = | 697 | struct qtet_kcontrol_private private = |
708 | qtet_privates[kcontrol->private_value]; | 698 | qtet_privates[kcontrol->private_value]; |
709 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 699 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(private.texts), |
710 | uinfo->count = 1; | 700 | private.texts); |
711 | uinfo->value.enumerated.items = ARRAY_SIZE(private.texts); | ||
712 | |||
713 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
714 | uinfo->value.enumerated.item = | ||
715 | uinfo->value.enumerated.items - 1; | ||
716 | strcpy(uinfo->value.enumerated.name, | ||
717 | private.texts[uinfo->value.enumerated.item]); | ||
718 | |||
719 | return 0; | ||
720 | } | 701 | } |
721 | 702 | ||
722 | static int qtet_sw_get(struct snd_kcontrol *kcontrol, | 703 | static int qtet_sw_get(struct snd_kcontrol *kcontrol, |
@@ -852,11 +833,8 @@ static int qtet_add_controls(struct snd_ice1712 *ice) | |||
852 | if (err < 0) | 833 | if (err < 0) |
853 | return err; | 834 | return err; |
854 | /* only capture SPDIF over AK4113 */ | 835 | /* only capture SPDIF over AK4113 */ |
855 | err = snd_ak4113_build(spec->ak4113, | 836 | return snd_ak4113_build(spec->ak4113, |
856 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); | 837 | ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); |
857 | if (err < 0) | ||
858 | return err; | ||
859 | return 0; | ||
860 | } | 838 | } |
861 | 839 | ||
862 | static inline int qtet_is_spdif_master(struct snd_ice1712 *ice) | 840 | static inline int qtet_is_spdif_master(struct snd_ice1712 *ice) |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 1112ec1953be..1d81ae677573 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -494,11 +494,13 @@ static int ap192_ak4114_init(struct snd_ice1712 *ice) | |||
494 | ap192_ak4114_write, | 494 | ap192_ak4114_write, |
495 | ak4114_init_vals, ak4114_init_txcsb, | 495 | ak4114_init_vals, ak4114_init_txcsb, |
496 | ice, &spec->ak4114); | 496 | ice, &spec->ak4114); |
497 | if (err < 0) | ||
498 | return err; | ||
497 | /* AK4114 in Revo cannot detect external rate correctly. | 499 | /* AK4114 in Revo cannot detect external rate correctly. |
498 | * No reason to stop capture stream due to incorrect checks */ | 500 | * No reason to stop capture stream due to incorrect checks */ |
499 | spec->ak4114->check_flags = AK4114_CHECK_NO_RATE; | 501 | spec->ak4114->check_flags = AK4114_CHECK_NO_RATE; |
500 | 502 | ||
501 | return 0; /* error ignored; it's no fatal error */ | 503 | return 0; |
502 | } | 504 | } |
503 | 505 | ||
504 | static int revo_init(struct snd_ice1712 *ice) | 506 | static int revo_init(struct snd_ice1712 *ice) |
diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c index ffd894bb4507..1c5d5b22c7a0 100644 --- a/sound/pci/ice1712/se.c +++ b/sound/pci/ice1712/se.c | |||
@@ -452,14 +452,7 @@ static int se200pci_cont_enum_info(struct snd_kcontrol *kc, | |||
452 | c = se200pci_get_enum_count(n); | 452 | c = se200pci_get_enum_count(n); |
453 | if (!c) | 453 | if (!c) |
454 | return -EINVAL; | 454 | return -EINVAL; |
455 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 455 | return snd_ctl_enum_info(uinfo, 1, c, se200pci_cont[n].member); |
456 | uinfo->count = 1; | ||
457 | uinfo->value.enumerated.items = c; | ||
458 | if (uinfo->value.enumerated.item >= c) | ||
459 | uinfo->value.enumerated.item = c - 1; | ||
460 | strcpy(uinfo->value.enumerated.name, | ||
461 | se200pci_cont[n].member[uinfo->value.enumerated.item]); | ||
462 | return 0; | ||
463 | } | 456 | } |
464 | 457 | ||
465 | static int se200pci_cont_volume_get(struct snd_kcontrol *kc, | 458 | static int se200pci_cont_volume_get(struct snd_kcontrol *kc, |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 9fe549b2efdf..59d21c9401d2 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -444,9 +444,9 @@ static char *stateName[] = { | |||
444 | "Invalid" | 444 | "Invalid" |
445 | }; | 445 | }; |
446 | 446 | ||
447 | static char *clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" }; | 447 | static const char * const clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" }; |
448 | 448 | ||
449 | static char *clockSourceName[] = { | 449 | static const char * const clockSourceName[] = { |
450 | "ADAT at 44.1 kHz", | 450 | "ADAT at 44.1 kHz", |
451 | "ADAT at 48 kHz", | 451 | "ADAT at 48 kHz", |
452 | "S/PDIF at 44.1 kHz", | 452 | "S/PDIF at 44.1 kHz", |
@@ -455,7 +455,7 @@ static char *clockSourceName[] = { | |||
455 | "local clock at 48 kHz" | 455 | "local clock at 48 kHz" |
456 | }; | 456 | }; |
457 | 457 | ||
458 | static char *channelName[] = { | 458 | static const char * const channelName[] = { |
459 | "ADAT-1", | 459 | "ADAT-1", |
460 | "ADAT-2", | 460 | "ADAT-2", |
461 | "ADAT-3", | 461 | "ADAT-3", |
@@ -1844,14 +1844,9 @@ static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol, | |||
1844 | static int snd_korg1212_control_route_info(struct snd_kcontrol *kcontrol, | 1844 | static int snd_korg1212_control_route_info(struct snd_kcontrol *kcontrol, |
1845 | struct snd_ctl_elem_info *uinfo) | 1845 | struct snd_ctl_elem_info *uinfo) |
1846 | { | 1846 | { |
1847 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1847 | return snd_ctl_enum_info(uinfo, |
1848 | uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1; | 1848 | (kcontrol->private_value >= 8) ? 2 : 1, |
1849 | uinfo->value.enumerated.items = kAudioChannels; | 1849 | kAudioChannels, channelName); |
1850 | if (uinfo->value.enumerated.item > kAudioChannels-1) { | ||
1851 | uinfo->value.enumerated.item = kAudioChannels-1; | ||
1852 | } | ||
1853 | strcpy(uinfo->value.enumerated.name, channelName[uinfo->value.enumerated.item]); | ||
1854 | return 0; | ||
1855 | } | 1850 | } |
1856 | 1851 | ||
1857 | static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol, | 1852 | static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol, |
@@ -1961,14 +1956,7 @@ static int snd_korg1212_control_put(struct snd_kcontrol *kcontrol, | |||
1961 | static int snd_korg1212_control_sync_info(struct snd_kcontrol *kcontrol, | 1956 | static int snd_korg1212_control_sync_info(struct snd_kcontrol *kcontrol, |
1962 | struct snd_ctl_elem_info *uinfo) | 1957 | struct snd_ctl_elem_info *uinfo) |
1963 | { | 1958 | { |
1964 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1959 | return snd_ctl_enum_info(uinfo, 1, 3, clockSourceTypeName); |
1965 | uinfo->count = 1; | ||
1966 | uinfo->value.enumerated.items = 3; | ||
1967 | if (uinfo->value.enumerated.item > 2) { | ||
1968 | uinfo->value.enumerated.item = 2; | ||
1969 | } | ||
1970 | strcpy(uinfo->value.enumerated.name, clockSourceTypeName[uinfo->value.enumerated.item]); | ||
1971 | return 0; | ||
1972 | } | 1960 | } |
1973 | 1961 | ||
1974 | static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol, | 1962 | static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c index 782f4d8299ae..e7fe15dd5a90 100644 --- a/sound/pci/lola/lola_mixer.c +++ b/sound/pci/lola/lola_mixer.c | |||
@@ -108,8 +108,7 @@ int lola_init_pins(struct lola *chip, int dir, int *nidp) | |||
108 | 108 | ||
109 | void lola_free_mixer(struct lola *chip) | 109 | void lola_free_mixer(struct lola *chip) |
110 | { | 110 | { |
111 | if (chip->mixer.array_saved) | 111 | vfree(chip->mixer.array_saved); |
112 | vfree(chip->mixer.array_saved); | ||
113 | } | 112 | } |
114 | 113 | ||
115 | int lola_init_mixer_widget(struct lola *chip, int nid) | 114 | int lola_init_mixer_widget(struct lola *chip, int nid) |
diff --git a/sound/pci/lx6464es/lx_defs.h b/sound/pci/lx6464es/lx_defs.h index 49d36bdd512c..469bcc685edf 100644 --- a/sound/pci/lx6464es/lx_defs.h +++ b/sound/pci/lx6464es/lx_defs.h | |||
@@ -175,7 +175,7 @@ enum buffer_flags { | |||
175 | BF_ZERO = 0x00, /* no flags (init).*/ | 175 | BF_ZERO = 0x00, /* no flags (init).*/ |
176 | }; | 176 | }; |
177 | 177 | ||
178 | /** | 178 | /* |
179 | * Stream Flags definitions | 179 | * Stream Flags definitions |
180 | */ | 180 | */ |
181 | enum stream_flags { | 181 | enum stream_flags { |
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 581e1e74863c..9996a4dead0f 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c | |||
@@ -37,10 +37,11 @@ | |||
37 | /** | 37 | /** |
38 | * wait for a value on a peudo register, exit with a timeout | 38 | * wait for a value on a peudo register, exit with a timeout |
39 | * | 39 | * |
40 | * @param mgr pointer to miXart manager structure | 40 | * @mgr: pointer to miXart manager structure |
41 | * @param offset unsigned pseudo_register base + offset of value | 41 | * @offset: unsigned pseudo_register base + offset of value |
42 | * @param value value | 42 | * @is_egal: wait for the equal value |
43 | * @param timeout timeout in centisenconds | 43 | * @value: value |
44 | * @timeout: timeout in centisenconds | ||
44 | */ | 45 | */ |
45 | static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr, | 46 | static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr, |
46 | u32 offset, int is_egal, | 47 | u32 offset, int is_egal, |
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index b854fc5e01f5..a60293015267 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -501,10 +501,10 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, | |||
501 | /* | 501 | /* |
502 | * start or stop playback/capture substream | 502 | * start or stop playback/capture substream |
503 | */ | 503 | */ |
504 | static int pcxhr_set_stream_state(struct pcxhr_stream *stream) | 504 | static int pcxhr_set_stream_state(struct snd_pcxhr *chip, |
505 | struct pcxhr_stream *stream) | ||
505 | { | 506 | { |
506 | int err; | 507 | int err; |
507 | struct snd_pcxhr *chip; | ||
508 | struct pcxhr_rmh rmh; | 508 | struct pcxhr_rmh rmh; |
509 | int stream_mask, start; | 509 | int stream_mask, start; |
510 | 510 | ||
@@ -512,8 +512,8 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream) | |||
512 | start = 1; | 512 | start = 1; |
513 | else { | 513 | else { |
514 | if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) { | 514 | if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) { |
515 | snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state " | 515 | dev_err(chip->card->dev, |
516 | "CANNOT be stopped\n"); | 516 | "pcxhr_set_stream_state CANNOT be stopped\n"); |
517 | return -EINVAL; | 517 | return -EINVAL; |
518 | } | 518 | } |
519 | start = 0; | 519 | start = 0; |
@@ -560,6 +560,7 @@ static int pcxhr_set_format(struct pcxhr_stream *stream) | |||
560 | struct pcxhr_rmh rmh; | 560 | struct pcxhr_rmh rmh; |
561 | unsigned int header; | 561 | unsigned int header; |
562 | 562 | ||
563 | chip = snd_pcm_substream_chip(stream->substream); | ||
563 | switch (stream->format) { | 564 | switch (stream->format) { |
564 | case SNDRV_PCM_FORMAT_U8: | 565 | case SNDRV_PCM_FORMAT_U8: |
565 | header = HEADER_FMT_BASE_LIN; | 566 | header = HEADER_FMT_BASE_LIN; |
@@ -582,11 +583,10 @@ static int pcxhr_set_format(struct pcxhr_stream *stream) | |||
582 | header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL; | 583 | header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL; |
583 | break; | 584 | break; |
584 | default: | 585 | default: |
585 | snd_printk(KERN_ERR | 586 | dev_err(chip->card->dev, |
586 | "error pcxhr_set_format() : unknown format\n"); | 587 | "error pcxhr_set_format() : unknown format\n"); |
587 | return -EINVAL; | 588 | return -EINVAL; |
588 | } | 589 | } |
589 | chip = snd_pcm_substream_chip(stream->substream); | ||
590 | 590 | ||
591 | sample_rate = chip->mgr->sample_rate; | 591 | sample_rate = chip->mgr->sample_rate; |
592 | if (sample_rate <= 32000 && sample_rate !=0) { | 592 | if (sample_rate <= 32000 && sample_rate !=0) { |
@@ -643,11 +643,11 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream) | |||
643 | is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); | 643 | is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); |
644 | stream_num = is_capture ? 0 : subs->number; | 644 | stream_num = is_capture ? 0 : subs->number; |
645 | 645 | ||
646 | snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : " | 646 | dev_dbg(chip->card->dev, |
647 | "addr(%p) bytes(%zx) subs(%d)\n", | 647 | "pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", |
648 | is_capture ? 'c' : 'p', | 648 | is_capture ? 'c' : 'p', |
649 | chip->chip_idx, (void *)(long)subs->runtime->dma_addr, | 649 | chip->chip_idx, (void *)(long)subs->runtime->dma_addr, |
650 | subs->runtime->dma_bytes, subs->number); | 650 | subs->runtime->dma_bytes, subs->number); |
651 | 651 | ||
652 | pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); | 652 | pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); |
653 | pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, | 653 | pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, |
@@ -687,7 +687,7 @@ static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream, | |||
687 | *sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24; | 687 | *sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24; |
688 | *sample_count += (snd_pcm_uframes_t)rmh.stat[1]; | 688 | *sample_count += (snd_pcm_uframes_t)rmh.stat[1]; |
689 | } | 689 | } |
690 | snd_printdd("PIPE_SAMPLE_COUNT = %lx\n", *sample_count); | 690 | dev_dbg(chip->card->dev, "PIPE_SAMPLE_COUNT = %lx\n", *sample_count); |
691 | return err; | 691 | return err; |
692 | } | 692 | } |
693 | #endif | 693 | #endif |
@@ -711,8 +711,9 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr) | |||
711 | int playback_mask = 0; | 711 | int playback_mask = 0; |
712 | 712 | ||
713 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 713 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
714 | struct timeval my_tv1, my_tv2; | 714 | ktime_t start_time, stop_time, diff_time; |
715 | do_gettimeofday(&my_tv1); | 715 | |
716 | start_time = ktime_get(); | ||
716 | #endif | 717 | #endif |
717 | mutex_lock(&mgr->setup_mutex); | 718 | mutex_lock(&mgr->setup_mutex); |
718 | 719 | ||
@@ -778,12 +779,12 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr) | |||
778 | for (j = 0; j < chip->nb_streams_capt; j++) { | 779 | for (j = 0; j < chip->nb_streams_capt; j++) { |
779 | stream = &chip->capture_stream[j]; | 780 | stream = &chip->capture_stream[j]; |
780 | if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) | 781 | if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) |
781 | err = pcxhr_set_stream_state(stream); | 782 | err = pcxhr_set_stream_state(chip, stream); |
782 | } | 783 | } |
783 | for (j = 0; j < chip->nb_streams_play; j++) { | 784 | for (j = 0; j < chip->nb_streams_play; j++) { |
784 | stream = &chip->playback_stream[j]; | 785 | stream = &chip->playback_stream[j]; |
785 | if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) | 786 | if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) |
786 | err = pcxhr_set_stream_state(stream); | 787 | err = pcxhr_set_stream_state(chip, stream); |
787 | } | 788 | } |
788 | } | 789 | } |
789 | 790 | ||
@@ -823,9 +824,10 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr) | |||
823 | mutex_unlock(&mgr->setup_mutex); | 824 | mutex_unlock(&mgr->setup_mutex); |
824 | 825 | ||
825 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 826 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
826 | do_gettimeofday(&my_tv2); | 827 | stop_time = ktime_get(); |
828 | diff_time = ktime_sub(stop_time, start_time); | ||
827 | dev_dbg(&mgr->pci->dev, "***TRIGGER START*** TIME = %ld (err = %x)\n", | 829 | dev_dbg(&mgr->pci->dev, "***TRIGGER START*** TIME = %ld (err = %x)\n", |
828 | (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); | 830 | (long)(ktime_to_ns(diff_time)), err); |
829 | #endif | 831 | #endif |
830 | } | 832 | } |
831 | 833 | ||
@@ -837,12 +839,12 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) | |||
837 | { | 839 | { |
838 | struct pcxhr_stream *stream; | 840 | struct pcxhr_stream *stream; |
839 | struct snd_pcm_substream *s; | 841 | struct snd_pcm_substream *s; |
842 | struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); | ||
840 | 843 | ||
841 | switch (cmd) { | 844 | switch (cmd) { |
842 | case SNDRV_PCM_TRIGGER_START: | 845 | case SNDRV_PCM_TRIGGER_START: |
843 | snd_printdd("SNDRV_PCM_TRIGGER_START\n"); | 846 | dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_START\n"); |
844 | if (snd_pcm_stream_linked(subs)) { | 847 | if (snd_pcm_stream_linked(subs)) { |
845 | struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); | ||
846 | snd_pcm_group_for_each_entry(s, subs) { | 848 | snd_pcm_group_for_each_entry(s, subs) { |
847 | if (snd_pcm_substream_chip(s) != chip) | 849 | if (snd_pcm_substream_chip(s) != chip) |
848 | continue; | 850 | continue; |
@@ -854,7 +856,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) | |||
854 | pcxhr_start_linked_stream(chip->mgr); | 856 | pcxhr_start_linked_stream(chip->mgr); |
855 | } else { | 857 | } else { |
856 | stream = subs->runtime->private_data; | 858 | stream = subs->runtime->private_data; |
857 | snd_printdd("Only one Substream %c %d\n", | 859 | dev_dbg(chip->card->dev, "Only one Substream %c %d\n", |
858 | stream->pipe->is_capture ? 'C' : 'P', | 860 | stream->pipe->is_capture ? 'C' : 'P', |
859 | stream->pipe->first_audio); | 861 | stream->pipe->first_audio); |
860 | if (pcxhr_set_format(stream)) | 862 | if (pcxhr_set_format(stream)) |
@@ -863,17 +865,17 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) | |||
863 | return -EINVAL; | 865 | return -EINVAL; |
864 | 866 | ||
865 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; | 867 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; |
866 | if (pcxhr_set_stream_state(stream)) | 868 | if (pcxhr_set_stream_state(chip, stream)) |
867 | return -EINVAL; | 869 | return -EINVAL; |
868 | stream->status = PCXHR_STREAM_STATUS_RUNNING; | 870 | stream->status = PCXHR_STREAM_STATUS_RUNNING; |
869 | } | 871 | } |
870 | break; | 872 | break; |
871 | case SNDRV_PCM_TRIGGER_STOP: | 873 | case SNDRV_PCM_TRIGGER_STOP: |
872 | snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); | 874 | dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_STOP\n"); |
873 | snd_pcm_group_for_each_entry(s, subs) { | 875 | snd_pcm_group_for_each_entry(s, subs) { |
874 | stream = s->runtime->private_data; | 876 | stream = s->runtime->private_data; |
875 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; | 877 | stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; |
876 | if (pcxhr_set_stream_state(stream)) | 878 | if (pcxhr_set_stream_state(chip, stream)) |
877 | return -EINVAL; | 879 | return -EINVAL; |
878 | snd_pcm_trigger_done(s, subs); | 880 | snd_pcm_trigger_done(s, subs); |
879 | } | 881 | } |
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index a584acb61c00..181f7729d409 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c | |||
@@ -910,8 +910,9 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, | |||
910 | int audio_mask; | 910 | int audio_mask; |
911 | 911 | ||
912 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 912 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
913 | struct timeval my_tv1, my_tv2; | 913 | ktime_t start_time, stop_time, diff_time; |
914 | do_gettimeofday(&my_tv1); | 914 | |
915 | start_time = ktime_get(); | ||
915 | #endif | 916 | #endif |
916 | audio_mask = (playback_mask | | 917 | audio_mask = (playback_mask | |
917 | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET)); | 918 | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET)); |
@@ -960,9 +961,10 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, | |||
960 | return err; | 961 | return err; |
961 | } | 962 | } |
962 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 963 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
963 | do_gettimeofday(&my_tv2); | 964 | stop_time = ktime_get(); |
965 | diff_time = ktime_sub(stop_time, start_time); | ||
964 | dev_dbg(&mgr->pci->dev, "***SET PIPE STATE*** TIME = %ld (err = %x)\n", | 966 | dev_dbg(&mgr->pci->dev, "***SET PIPE STATE*** TIME = %ld (err = %x)\n", |
965 | (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); | 967 | (long)(ktime_to_ns(diff_time)), err); |
966 | #endif | 968 | #endif |
967 | return 0; | 969 | return 0; |
968 | } | 970 | } |
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index 95c9571780d8..63136c4f3f3d 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c | |||
@@ -660,14 +660,7 @@ static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol, | |||
660 | if (chip->mgr->board_has_mic) | 660 | if (chip->mgr->board_has_mic) |
661 | i = 5; /* Mic and MicroMix available */ | 661 | i = 5; /* Mic and MicroMix available */ |
662 | } | 662 | } |
663 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 663 | return snd_ctl_enum_info(uinfo, 1, i, texts); |
664 | uinfo->count = 1; | ||
665 | uinfo->value.enumerated.items = i; | ||
666 | if (uinfo->value.enumerated.item > (i-1)) | ||
667 | uinfo->value.enumerated.item = i-1; | ||
668 | strcpy(uinfo->value.enumerated.name, | ||
669 | texts[uinfo->value.enumerated.item]); | ||
670 | return 0; | ||
671 | } | 664 | } |
672 | 665 | ||
673 | static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol, | 666 | static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol, |
@@ -756,14 +749,7 @@ static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol, | |||
756 | texts = textsPCXHR; | 749 | texts = textsPCXHR; |
757 | snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1)); | 750 | snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1)); |
758 | } | 751 | } |
759 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 752 | return snd_ctl_enum_info(uinfo, 1, clock_items, texts); |
760 | uinfo->count = 1; | ||
761 | uinfo->value.enumerated.items = clock_items; | ||
762 | if (uinfo->value.enumerated.item >= clock_items) | ||
763 | uinfo->value.enumerated.item = clock_items-1; | ||
764 | strcpy(uinfo->value.enumerated.name, | ||
765 | texts[uinfo->value.enumerated.item]); | ||
766 | return 0; | ||
767 | } | 753 | } |
768 | 754 | ||
769 | static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol, | 755 | static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 4afd3cab775b..6c60dcd2e5a1 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -1608,30 +1608,24 @@ snd_rme32_info_inputtype_control(struct snd_kcontrol *kcontrol, | |||
1608 | struct snd_ctl_elem_info *uinfo) | 1608 | struct snd_ctl_elem_info *uinfo) |
1609 | { | 1609 | { |
1610 | struct rme32 *rme32 = snd_kcontrol_chip(kcontrol); | 1610 | struct rme32 *rme32 = snd_kcontrol_chip(kcontrol); |
1611 | static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" }; | 1611 | static const char * const texts[4] = { |
1612 | "Optical", "Coaxial", "Internal", "XLR" | ||
1613 | }; | ||
1614 | int num_items; | ||
1612 | 1615 | ||
1613 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1614 | uinfo->count = 1; | ||
1615 | switch (rme32->pci->device) { | 1616 | switch (rme32->pci->device) { |
1616 | case PCI_DEVICE_ID_RME_DIGI32: | 1617 | case PCI_DEVICE_ID_RME_DIGI32: |
1617 | case PCI_DEVICE_ID_RME_DIGI32_8: | 1618 | case PCI_DEVICE_ID_RME_DIGI32_8: |
1618 | uinfo->value.enumerated.items = 3; | 1619 | num_items = 3; |
1619 | break; | 1620 | break; |
1620 | case PCI_DEVICE_ID_RME_DIGI32_PRO: | 1621 | case PCI_DEVICE_ID_RME_DIGI32_PRO: |
1621 | uinfo->value.enumerated.items = 4; | 1622 | num_items = 4; |
1622 | break; | 1623 | break; |
1623 | default: | 1624 | default: |
1624 | snd_BUG(); | 1625 | snd_BUG(); |
1625 | break; | 1626 | return -EINVAL; |
1626 | } | ||
1627 | if (uinfo->value.enumerated.item > | ||
1628 | uinfo->value.enumerated.items - 1) { | ||
1629 | uinfo->value.enumerated.item = | ||
1630 | uinfo->value.enumerated.items - 1; | ||
1631 | } | 1627 | } |
1632 | strcpy(uinfo->value.enumerated.name, | 1628 | return snd_ctl_enum_info(uinfo, 1, num_items, texts); |
1633 | texts[uinfo->value.enumerated.item]); | ||
1634 | return 0; | ||
1635 | } | 1629 | } |
1636 | static int | 1630 | static int |
1637 | snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol, | 1631 | snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol, |
@@ -1695,20 +1689,12 @@ static int | |||
1695 | snd_rme32_info_clockmode_control(struct snd_kcontrol *kcontrol, | 1689 | snd_rme32_info_clockmode_control(struct snd_kcontrol *kcontrol, |
1696 | struct snd_ctl_elem_info *uinfo) | 1690 | struct snd_ctl_elem_info *uinfo) |
1697 | { | 1691 | { |
1698 | static char *texts[4] = { "AutoSync", | 1692 | static const char * const texts[4] = { "AutoSync", |
1699 | "Internal 32.0kHz", | 1693 | "Internal 32.0kHz", |
1700 | "Internal 44.1kHz", | 1694 | "Internal 44.1kHz", |
1701 | "Internal 48.0kHz" }; | 1695 | "Internal 48.0kHz" }; |
1702 | 1696 | ||
1703 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1697 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
1704 | uinfo->count = 1; | ||
1705 | uinfo->value.enumerated.items = 4; | ||
1706 | if (uinfo->value.enumerated.item > 3) { | ||
1707 | uinfo->value.enumerated.item = 3; | ||
1708 | } | ||
1709 | strcpy(uinfo->value.enumerated.name, | ||
1710 | texts[uinfo->value.enumerated.item]); | ||
1711 | return 0; | ||
1712 | } | 1698 | } |
1713 | static int | 1699 | static int |
1714 | snd_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol, | 1700 | snd_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 5a395c87c6fc..2f1a85185a16 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -1884,39 +1884,38 @@ snd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
1884 | static int | 1884 | static int |
1885 | snd_rme96_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1885 | snd_rme96_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1886 | { | 1886 | { |
1887 | static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" }; | 1887 | static const char * const _texts[5] = { |
1888 | "Optical", "Coaxial", "Internal", "XLR", "Analog" | ||
1889 | }; | ||
1888 | struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); | 1890 | struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); |
1889 | char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] }; | 1891 | const char *texts[5] = { |
1892 | _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] | ||
1893 | }; | ||
1894 | int num_items; | ||
1890 | 1895 | ||
1891 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1892 | uinfo->count = 1; | ||
1893 | switch (rme96->pci->device) { | 1896 | switch (rme96->pci->device) { |
1894 | case PCI_DEVICE_ID_RME_DIGI96: | 1897 | case PCI_DEVICE_ID_RME_DIGI96: |
1895 | case PCI_DEVICE_ID_RME_DIGI96_8: | 1898 | case PCI_DEVICE_ID_RME_DIGI96_8: |
1896 | uinfo->value.enumerated.items = 3; | 1899 | num_items = 3; |
1897 | break; | 1900 | break; |
1898 | case PCI_DEVICE_ID_RME_DIGI96_8_PRO: | 1901 | case PCI_DEVICE_ID_RME_DIGI96_8_PRO: |
1899 | uinfo->value.enumerated.items = 4; | 1902 | num_items = 4; |
1900 | break; | 1903 | break; |
1901 | case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: | 1904 | case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: |
1902 | if (rme96->rev > 4) { | 1905 | if (rme96->rev > 4) { |
1903 | /* PST */ | 1906 | /* PST */ |
1904 | uinfo->value.enumerated.items = 4; | 1907 | num_items = 4; |
1905 | texts[3] = _texts[4]; /* Analog instead of XLR */ | 1908 | texts[3] = _texts[4]; /* Analog instead of XLR */ |
1906 | } else { | 1909 | } else { |
1907 | /* PAD */ | 1910 | /* PAD */ |
1908 | uinfo->value.enumerated.items = 5; | 1911 | num_items = 5; |
1909 | } | 1912 | } |
1910 | break; | 1913 | break; |
1911 | default: | 1914 | default: |
1912 | snd_BUG(); | 1915 | snd_BUG(); |
1913 | break; | 1916 | return -EINVAL; |
1914 | } | ||
1915 | if (uinfo->value.enumerated.item > uinfo->value.enumerated.items - 1) { | ||
1916 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1917 | } | 1917 | } |
1918 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 1918 | return snd_ctl_enum_info(uinfo, 1, num_items, texts); |
1919 | return 0; | ||
1920 | } | 1919 | } |
1921 | static int | 1920 | static int |
1922 | snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1921 | snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2002,16 +2001,9 @@ snd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
2002 | static int | 2001 | static int |
2003 | snd_rme96_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2002 | snd_rme96_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2004 | { | 2003 | { |
2005 | static char *texts[3] = { "AutoSync", "Internal", "Word" }; | 2004 | static const char * const texts[3] = { "AutoSync", "Internal", "Word" }; |
2006 | 2005 | ||
2007 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2006 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2008 | uinfo->count = 1; | ||
2009 | uinfo->value.enumerated.items = 3; | ||
2010 | if (uinfo->value.enumerated.item > 2) { | ||
2011 | uinfo->value.enumerated.item = 2; | ||
2012 | } | ||
2013 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2014 | return 0; | ||
2015 | } | 2007 | } |
2016 | static int | 2008 | static int |
2017 | snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2009 | snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2041,16 +2033,11 @@ snd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
2041 | static int | 2033 | static int |
2042 | snd_rme96_info_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2034 | snd_rme96_info_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2043 | { | 2035 | { |
2044 | static char *texts[4] = { "0 dB", "-6 dB", "-12 dB", "-18 dB" }; | 2036 | static const char * const texts[4] = { |
2037 | "0 dB", "-6 dB", "-12 dB", "-18 dB" | ||
2038 | }; | ||
2045 | 2039 | ||
2046 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2040 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
2047 | uinfo->count = 1; | ||
2048 | uinfo->value.enumerated.items = 4; | ||
2049 | if (uinfo->value.enumerated.item > 3) { | ||
2050 | uinfo->value.enumerated.item = 3; | ||
2051 | } | ||
2052 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2053 | return 0; | ||
2054 | } | 2041 | } |
2055 | static int | 2042 | static int |
2056 | snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2043 | snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2081,16 +2068,9 @@ snd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
2081 | static int | 2068 | static int |
2082 | snd_rme96_info_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2069 | snd_rme96_info_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2083 | { | 2070 | { |
2084 | static char *texts[4] = { "1+2", "3+4", "5+6", "7+8" }; | 2071 | static const char * const texts[4] = { "1+2", "3+4", "5+6", "7+8" }; |
2085 | 2072 | ||
2086 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2073 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
2087 | uinfo->count = 1; | ||
2088 | uinfo->value.enumerated.items = 4; | ||
2089 | if (uinfo->value.enumerated.item > 3) { | ||
2090 | uinfo->value.enumerated.item = 3; | ||
2091 | } | ||
2092 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2093 | return 0; | ||
2094 | } | 2074 | } |
2095 | static int | 2075 | static int |
2096 | snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2076 | snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 7646ba1664eb..cf5a6c8b9a63 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -1680,16 +1680,13 @@ static int hdsp_set_spdif_input(struct hdsp *hdsp, int in) | |||
1680 | 1680 | ||
1681 | static int snd_hdsp_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1681 | static int snd_hdsp_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1682 | { | 1682 | { |
1683 | static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"}; | 1683 | static const char * const texts[4] = { |
1684 | "Optical", "Coaxial", "Internal", "AES" | ||
1685 | }; | ||
1684 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1686 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1685 | 1687 | ||
1686 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1688 | return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 4 : 3, |
1687 | uinfo->count = 1; | 1689 | texts); |
1688 | uinfo->value.enumerated.items = ((hdsp->io_type == H9632) ? 4 : 3); | ||
1689 | if (uinfo->value.enumerated.item > ((hdsp->io_type == H9632) ? 3 : 2)) | ||
1690 | uinfo->value.enumerated.item = ((hdsp->io_type == H9632) ? 3 : 2); | ||
1691 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1692 | return 0; | ||
1693 | } | 1690 | } |
1694 | 1691 | ||
1695 | static int snd_hdsp_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1692 | static int snd_hdsp_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1786,16 +1783,14 @@ static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol, | |||
1786 | 1783 | ||
1787 | static int snd_hdsp_info_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1784 | static int snd_hdsp_info_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1788 | { | 1785 | { |
1789 | static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"}; | 1786 | static const char * const texts[] = { |
1787 | "32000", "44100", "48000", "64000", "88200", "96000", | ||
1788 | "None", "128000", "176400", "192000" | ||
1789 | }; | ||
1790 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1790 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1791 | 1791 | ||
1792 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1792 | return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 10 : 7, |
1793 | uinfo->count = 1; | 1793 | texts); |
1794 | uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7; | ||
1795 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1796 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1797 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1798 | return 0; | ||
1799 | } | 1794 | } |
1800 | 1795 | ||
1801 | static int snd_hdsp_get_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1796 | static int snd_hdsp_get_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1872,14 +1867,13 @@ static int snd_hdsp_get_system_sample_rate(struct snd_kcontrol *kcontrol, struct | |||
1872 | static int snd_hdsp_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1867 | static int snd_hdsp_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1873 | { | 1868 | { |
1874 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1869 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1875 | static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"}; | 1870 | static const char * const texts[] = { |
1876 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1871 | "32000", "44100", "48000", "64000", "88200", "96000", |
1877 | uinfo->count = 1; | 1872 | "None", "128000", "176400", "192000" |
1878 | uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7 ; | 1873 | }; |
1879 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 1874 | |
1880 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | 1875 | return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 10 : 7, |
1881 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 1876 | texts); |
1882 | return 0; | ||
1883 | } | 1877 | } |
1884 | 1878 | ||
1885 | static int snd_hdsp_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1879 | static int snd_hdsp_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1940,15 +1934,9 @@ static int hdsp_system_clock_mode(struct hdsp *hdsp) | |||
1940 | 1934 | ||
1941 | static int snd_hdsp_info_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1935 | static int snd_hdsp_info_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1942 | { | 1936 | { |
1943 | static char *texts[] = {"Master", "Slave" }; | 1937 | static const char * const texts[] = {"Master", "Slave" }; |
1944 | 1938 | ||
1945 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1939 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
1946 | uinfo->count = 1; | ||
1947 | uinfo->value.enumerated.items = 2; | ||
1948 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1949 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1950 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1951 | return 0; | ||
1952 | } | 1940 | } |
1953 | 1941 | ||
1954 | static int snd_hdsp_get_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1942 | static int snd_hdsp_get_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2049,19 +2037,16 @@ static int hdsp_set_clock_source(struct hdsp *hdsp, int mode) | |||
2049 | 2037 | ||
2050 | static int snd_hdsp_info_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2038 | static int snd_hdsp_info_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2051 | { | 2039 | { |
2052 | static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" }; | 2040 | static const char * const texts[] = { |
2041 | "AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", | ||
2042 | "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", | ||
2043 | "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", | ||
2044 | "Internal 192.0 KHz" | ||
2045 | }; | ||
2053 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 2046 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
2054 | 2047 | ||
2055 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2048 | return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 10 : 7, |
2056 | uinfo->count = 1; | 2049 | texts); |
2057 | if (hdsp->io_type == H9632) | ||
2058 | uinfo->value.enumerated.items = 10; | ||
2059 | else | ||
2060 | uinfo->value.enumerated.items = 7; | ||
2061 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2062 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2063 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2064 | return 0; | ||
2065 | } | 2050 | } |
2066 | 2051 | ||
2067 | static int snd_hdsp_get_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2052 | static int snd_hdsp_get_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2165,15 +2150,9 @@ static int hdsp_set_da_gain(struct hdsp *hdsp, int mode) | |||
2165 | 2150 | ||
2166 | static int snd_hdsp_info_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2151 | static int snd_hdsp_info_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2167 | { | 2152 | { |
2168 | static char *texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"}; | 2153 | static const char * const texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"}; |
2169 | 2154 | ||
2170 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2155 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2171 | uinfo->count = 1; | ||
2172 | uinfo->value.enumerated.items = 3; | ||
2173 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2174 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2175 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2176 | return 0; | ||
2177 | } | 2156 | } |
2178 | 2157 | ||
2179 | static int snd_hdsp_get_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2158 | static int snd_hdsp_get_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2250,15 +2229,9 @@ static int hdsp_set_ad_gain(struct hdsp *hdsp, int mode) | |||
2250 | 2229 | ||
2251 | static int snd_hdsp_info_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2230 | static int snd_hdsp_info_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2252 | { | 2231 | { |
2253 | static char *texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"}; | 2232 | static const char * const texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"}; |
2254 | 2233 | ||
2255 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2234 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2256 | uinfo->count = 1; | ||
2257 | uinfo->value.enumerated.items = 3; | ||
2258 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2259 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2260 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2261 | return 0; | ||
2262 | } | 2235 | } |
2263 | 2236 | ||
2264 | static int snd_hdsp_get_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2237 | static int snd_hdsp_get_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2335,15 +2308,9 @@ static int hdsp_set_phone_gain(struct hdsp *hdsp, int mode) | |||
2335 | 2308 | ||
2336 | static int snd_hdsp_info_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2309 | static int snd_hdsp_info_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2337 | { | 2310 | { |
2338 | static char *texts[] = {"0 dB", "-6 dB", "-12 dB"}; | 2311 | static const char * const texts[] = {"0 dB", "-6 dB", "-12 dB"}; |
2339 | 2312 | ||
2340 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2313 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2341 | uinfo->count = 1; | ||
2342 | uinfo->value.enumerated.items = 3; | ||
2343 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2344 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2345 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2346 | return 0; | ||
2347 | } | 2314 | } |
2348 | 2315 | ||
2349 | static int snd_hdsp_get_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2316 | static int snd_hdsp_get_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2439,31 +2406,28 @@ static int hdsp_set_pref_sync_ref(struct hdsp *hdsp, int pref) | |||
2439 | 2406 | ||
2440 | static int snd_hdsp_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2407 | static int snd_hdsp_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2441 | { | 2408 | { |
2442 | static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" }; | 2409 | static const char * const texts[] = { |
2410 | "Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" | ||
2411 | }; | ||
2443 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 2412 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
2444 | 2413 | int num_items; | |
2445 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2446 | uinfo->count = 1; | ||
2447 | 2414 | ||
2448 | switch (hdsp->io_type) { | 2415 | switch (hdsp->io_type) { |
2449 | case Digiface: | 2416 | case Digiface: |
2450 | case H9652: | 2417 | case H9652: |
2451 | uinfo->value.enumerated.items = 6; | 2418 | num_items = 6; |
2452 | break; | 2419 | break; |
2453 | case Multiface: | 2420 | case Multiface: |
2454 | uinfo->value.enumerated.items = 4; | 2421 | num_items = 4; |
2455 | break; | 2422 | break; |
2456 | case H9632: | 2423 | case H9632: |
2457 | uinfo->value.enumerated.items = 3; | 2424 | num_items = 3; |
2458 | break; | 2425 | break; |
2459 | default: | 2426 | default: |
2460 | return -EINVAL; | 2427 | return -EINVAL; |
2461 | } | 2428 | } |
2462 | 2429 | ||
2463 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 2430 | return snd_ctl_enum_info(uinfo, 1, num_items, texts); |
2464 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2465 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2466 | return 0; | ||
2467 | } | 2431 | } |
2468 | 2432 | ||
2469 | static int snd_hdsp_get_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2433 | static int snd_hdsp_get_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2543,15 +2507,11 @@ static int hdsp_autosync_ref(struct hdsp *hdsp) | |||
2543 | 2507 | ||
2544 | static int snd_hdsp_info_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2508 | static int snd_hdsp_info_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2545 | { | 2509 | { |
2546 | static char *texts[] = {"Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" }; | 2510 | static const char * const texts[] = { |
2511 | "Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" | ||
2512 | }; | ||
2547 | 2513 | ||
2548 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2514 | return snd_ctl_enum_info(uinfo, 1, 7, texts); |
2549 | uinfo->count = 1; | ||
2550 | uinfo->value.enumerated.items = 7; | ||
2551 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2552 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2553 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2554 | return 0; | ||
2555 | } | 2515 | } |
2556 | 2516 | ||
2557 | static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2517 | static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -2738,14 +2698,9 @@ static int snd_hdsp_put_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
2738 | 2698 | ||
2739 | static int snd_hdsp_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 2699 | static int snd_hdsp_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
2740 | { | 2700 | { |
2741 | static char *texts[] = {"No Lock", "Lock", "Sync" }; | 2701 | static const char * const texts[] = {"No Lock", "Lock", "Sync" }; |
2742 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2702 | |
2743 | uinfo->count = 1; | 2703 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
2744 | uinfo->value.enumerated.items = 3; | ||
2745 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2746 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2747 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
2748 | return 0; | ||
2749 | } | 2704 | } |
2750 | 2705 | ||
2751 | static int hdsp_wc_sync_check(struct hdsp *hdsp) | 2706 | static int hdsp_wc_sync_check(struct hdsp *hdsp) |
@@ -3101,15 +3056,11 @@ static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ct | |||
3101 | 3056 | ||
3102 | static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 3057 | static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
3103 | { | 3058 | { |
3104 | static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"}; | 3059 | static const char * const texts[] = { |
3060 | "Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB" | ||
3061 | }; | ||
3105 | 3062 | ||
3106 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3063 | return snd_ctl_enum_info(uinfo, 1, 5, texts); |
3107 | uinfo->count = 1; | ||
3108 | uinfo->value.enumerated.items = 5; | ||
3109 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3110 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
3111 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
3112 | return 0; | ||
3113 | } | 3064 | } |
3114 | 3065 | ||
3115 | 3066 | ||
@@ -3234,15 +3185,9 @@ static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
3234 | 3185 | ||
3235 | static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 3186 | static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
3236 | { | 3187 | { |
3237 | static char *texts[] = {"On", "Off"}; | 3188 | static const char * const texts[] = {"On", "Off"}; |
3238 | 3189 | ||
3239 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3190 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
3240 | uinfo->count = 1; | ||
3241 | uinfo->value.enumerated.items = 2; | ||
3242 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3243 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
3244 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
3245 | return 0; | ||
3246 | } | 3191 | } |
3247 | 3192 | ||
3248 | 3193 | ||
@@ -3291,15 +3236,9 @@ static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd | |||
3291 | 3236 | ||
3292 | static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 3237 | static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
3293 | { | 3238 | { |
3294 | static char *texts[] = {"On", "Off"}; | 3239 | static const char * const texts[] = {"On", "Off"}; |
3295 | 3240 | ||
3296 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3241 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
3297 | uinfo->count = 1; | ||
3298 | uinfo->value.enumerated.items = 2; | ||
3299 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3300 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
3301 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
3302 | return 0; | ||
3303 | } | 3242 | } |
3304 | 3243 | ||
3305 | static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { | 3244 | static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { |
@@ -5368,8 +5307,7 @@ static int snd_hdsp_free(struct hdsp *hdsp) | |||
5368 | 5307 | ||
5369 | snd_hdsp_free_buffers(hdsp); | 5308 | snd_hdsp_free_buffers(hdsp); |
5370 | 5309 | ||
5371 | if (hdsp->firmware) | 5310 | release_firmware(hdsp->firmware); |
5372 | release_firmware(hdsp->firmware); | ||
5373 | vfree(hdsp->fw_uploaded); | 5311 | vfree(hdsp->fw_uploaded); |
5374 | 5312 | ||
5375 | if (hdsp->iobase) | 5313 | if (hdsp->iobase) |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 52d86af3ef2d..3342705a5715 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -1257,14 +1257,13 @@ static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate) | |||
1257 | /* check for external sample rate, returns the sample rate in Hz*/ | 1257 | /* check for external sample rate, returns the sample rate in Hz*/ |
1258 | static int hdspm_external_sample_rate(struct hdspm *hdspm) | 1258 | static int hdspm_external_sample_rate(struct hdspm *hdspm) |
1259 | { | 1259 | { |
1260 | unsigned int status, status2, timecode; | 1260 | unsigned int status, status2; |
1261 | int syncref, rate = 0, rate_bits; | 1261 | int syncref, rate = 0, rate_bits; |
1262 | 1262 | ||
1263 | switch (hdspm->io_type) { | 1263 | switch (hdspm->io_type) { |
1264 | case AES32: | 1264 | case AES32: |
1265 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 1265 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); |
1266 | status = hdspm_read(hdspm, HDSPM_statusRegister); | 1266 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
1267 | timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); | ||
1268 | 1267 | ||
1269 | syncref = hdspm_autosync_ref(hdspm); | 1268 | syncref = hdspm_autosync_ref(hdspm); |
1270 | switch (syncref) { | 1269 | switch (syncref) { |
@@ -2202,10 +2201,10 @@ static inline int hdspm_get_pll_freq(struct hdspm *hdspm) | |||
2202 | return rate; | 2201 | return rate; |
2203 | } | 2202 | } |
2204 | 2203 | ||
2205 | /** | 2204 | /* |
2206 | * Calculate the real sample rate from the | 2205 | * Calculate the real sample rate from the |
2207 | * current DDS value. | 2206 | * current DDS value. |
2208 | **/ | 2207 | */ |
2209 | static int hdspm_get_system_sample_rate(struct hdspm *hdspm) | 2208 | static int hdspm_get_system_sample_rate(struct hdspm *hdspm) |
2210 | { | 2209 | { |
2211 | unsigned int rate; | 2210 | unsigned int rate; |
@@ -2271,9 +2270,9 @@ static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol, | |||
2271 | } | 2270 | } |
2272 | 2271 | ||
2273 | 2272 | ||
2274 | /** | 2273 | /* |
2275 | * Returns the WordClock sample rate class for the given card. | 2274 | * Returns the WordClock sample rate class for the given card. |
2276 | **/ | 2275 | */ |
2277 | static int hdspm_get_wc_sample_rate(struct hdspm *hdspm) | 2276 | static int hdspm_get_wc_sample_rate(struct hdspm *hdspm) |
2278 | { | 2277 | { |
2279 | int status; | 2278 | int status; |
@@ -2296,9 +2295,9 @@ static int hdspm_get_wc_sample_rate(struct hdspm *hdspm) | |||
2296 | } | 2295 | } |
2297 | 2296 | ||
2298 | 2297 | ||
2299 | /** | 2298 | /* |
2300 | * Returns the TCO sample rate class for the given card. | 2299 | * Returns the TCO sample rate class for the given card. |
2301 | **/ | 2300 | */ |
2302 | static int hdspm_get_tco_sample_rate(struct hdspm *hdspm) | 2301 | static int hdspm_get_tco_sample_rate(struct hdspm *hdspm) |
2303 | { | 2302 | { |
2304 | int status; | 2303 | int status; |
@@ -2322,9 +2321,9 @@ static int hdspm_get_tco_sample_rate(struct hdspm *hdspm) | |||
2322 | } | 2321 | } |
2323 | 2322 | ||
2324 | 2323 | ||
2325 | /** | 2324 | /* |
2326 | * Returns the SYNC_IN sample rate class for the given card. | 2325 | * Returns the SYNC_IN sample rate class for the given card. |
2327 | **/ | 2326 | */ |
2328 | static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm) | 2327 | static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm) |
2329 | { | 2328 | { |
2330 | int status; | 2329 | int status; |
@@ -2344,9 +2343,9 @@ static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm) | |||
2344 | return 0; | 2343 | return 0; |
2345 | } | 2344 | } |
2346 | 2345 | ||
2347 | /** | 2346 | /* |
2348 | * Returns the AES sample rate class for the given card. | 2347 | * Returns the AES sample rate class for the given card. |
2349 | **/ | 2348 | */ |
2350 | static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index) | 2349 | static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index) |
2351 | { | 2350 | { |
2352 | int timecode; | 2351 | int timecode; |
@@ -2362,10 +2361,10 @@ static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index) | |||
2362 | return 0; | 2361 | return 0; |
2363 | } | 2362 | } |
2364 | 2363 | ||
2365 | /** | 2364 | /* |
2366 | * Returns the sample rate class for input source <idx> for | 2365 | * Returns the sample rate class for input source <idx> for |
2367 | * 'new style' cards like the AIO and RayDAT. | 2366 | * 'new style' cards like the AIO and RayDAT. |
2368 | **/ | 2367 | */ |
2369 | static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) | 2368 | static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) |
2370 | { | 2369 | { |
2371 | int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2); | 2370 | int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2); |
@@ -2513,10 +2512,10 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, | |||
2513 | } | 2512 | } |
2514 | 2513 | ||
2515 | 2514 | ||
2516 | /** | 2515 | /* |
2517 | * Returns the system clock mode for the given card. | 2516 | * Returns the system clock mode for the given card. |
2518 | * @returns 0 - master, 1 - slave | 2517 | * @returns 0 - master, 1 - slave |
2519 | **/ | 2518 | */ |
2520 | static int hdspm_system_clock_mode(struct hdspm *hdspm) | 2519 | static int hdspm_system_clock_mode(struct hdspm *hdspm) |
2521 | { | 2520 | { |
2522 | switch (hdspm->io_type) { | 2521 | switch (hdspm->io_type) { |
@@ -2535,10 +2534,10 @@ static int hdspm_system_clock_mode(struct hdspm *hdspm) | |||
2535 | } | 2534 | } |
2536 | 2535 | ||
2537 | 2536 | ||
2538 | /** | 2537 | /* |
2539 | * Sets the system clock mode. | 2538 | * Sets the system clock mode. |
2540 | * @param mode 0 - master, 1 - slave | 2539 | * @param mode 0 - master, 1 - slave |
2541 | **/ | 2540 | */ |
2542 | static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) | 2541 | static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) |
2543 | { | 2542 | { |
2544 | hdspm_set_toggle_setting(hdspm, | 2543 | hdspm_set_toggle_setting(hdspm, |
@@ -2645,18 +2644,7 @@ static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) | |||
2645 | static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, | 2644 | static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, |
2646 | struct snd_ctl_elem_info *uinfo) | 2645 | struct snd_ctl_elem_info *uinfo) |
2647 | { | 2646 | { |
2648 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2647 | return snd_ctl_enum_info(uinfo, 1, 9, texts_freq + 1); |
2649 | uinfo->count = 1; | ||
2650 | uinfo->value.enumerated.items = 9; | ||
2651 | |||
2652 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2653 | uinfo->value.enumerated.item = | ||
2654 | uinfo->value.enumerated.items - 1; | ||
2655 | |||
2656 | strcpy(uinfo->value.enumerated.name, | ||
2657 | texts_freq[uinfo->value.enumerated.item+1]); | ||
2658 | |||
2659 | return 0; | ||
2660 | } | 2648 | } |
2661 | 2649 | ||
2662 | static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol, | 2650 | static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol, |
@@ -2704,11 +2692,11 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol, | |||
2704 | } | 2692 | } |
2705 | 2693 | ||
2706 | 2694 | ||
2707 | /** | 2695 | /* |
2708 | * Returns the current preferred sync reference setting. | 2696 | * Returns the current preferred sync reference setting. |
2709 | * The semantics of the return value are depending on the | 2697 | * The semantics of the return value are depending on the |
2710 | * card, please see the comments for clarification. | 2698 | * card, please see the comments for clarification. |
2711 | **/ | 2699 | */ |
2712 | static int hdspm_pref_sync_ref(struct hdspm * hdspm) | 2700 | static int hdspm_pref_sync_ref(struct hdspm * hdspm) |
2713 | { | 2701 | { |
2714 | switch (hdspm->io_type) { | 2702 | switch (hdspm->io_type) { |
@@ -2807,11 +2795,11 @@ static int hdspm_pref_sync_ref(struct hdspm * hdspm) | |||
2807 | } | 2795 | } |
2808 | 2796 | ||
2809 | 2797 | ||
2810 | /** | 2798 | /* |
2811 | * Set the preferred sync reference to <pref>. The semantics | 2799 | * Set the preferred sync reference to <pref>. The semantics |
2812 | * of <pref> are depending on the card type, see the comments | 2800 | * of <pref> are depending on the card type, see the comments |
2813 | * for clarification. | 2801 | * for clarification. |
2814 | **/ | 2802 | */ |
2815 | static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) | 2803 | static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) |
2816 | { | 2804 | { |
2817 | int p = 0; | 2805 | int p = 0; |
@@ -4113,9 +4101,9 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, | |||
4113 | 4101 | ||
4114 | 4102 | ||
4115 | 4103 | ||
4116 | /** | 4104 | /* |
4117 | * TCO controls | 4105 | * TCO controls |
4118 | **/ | 4106 | */ |
4119 | static void hdspm_tco_write(struct hdspm *hdspm) | 4107 | static void hdspm_tco_write(struct hdspm *hdspm) |
4120 | { | 4108 | { |
4121 | unsigned int tc[4] = { 0, 0, 0, 0}; | 4109 | unsigned int tc[4] = { 0, 0, 0, 0}; |
@@ -4873,18 +4861,15 @@ snd_hdspm_proc_read_madi(struct snd_info_entry *entry, | |||
4873 | struct snd_info_buffer *buffer) | 4861 | struct snd_info_buffer *buffer) |
4874 | { | 4862 | { |
4875 | struct hdspm *hdspm = entry->private_data; | 4863 | struct hdspm *hdspm = entry->private_data; |
4876 | unsigned int status, status2, control, freq; | 4864 | unsigned int status, status2; |
4877 | 4865 | ||
4878 | char *pref_sync_ref; | 4866 | char *pref_sync_ref; |
4879 | char *autosync_ref; | 4867 | char *autosync_ref; |
4880 | char *system_clock_mode; | 4868 | char *system_clock_mode; |
4881 | char *insel; | ||
4882 | int x, x2; | 4869 | int x, x2; |
4883 | 4870 | ||
4884 | status = hdspm_read(hdspm, HDSPM_statusRegister); | 4871 | status = hdspm_read(hdspm, HDSPM_statusRegister); |
4885 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); | 4872 | status2 = hdspm_read(hdspm, HDSPM_statusRegister2); |
4886 | control = hdspm->control_register; | ||
4887 | freq = hdspm_read(hdspm, HDSPM_timecodeRegister); | ||
4888 | 4873 | ||
4889 | snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", | 4874 | snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", |
4890 | hdspm->card_name, hdspm->card->number + 1, | 4875 | hdspm->card_name, hdspm->card->number + 1, |
@@ -4947,17 +4932,6 @@ snd_hdspm_proc_read_madi(struct snd_info_entry *entry, | |||
4947 | snd_iprintf(buffer, "Line out: %s\n", | 4932 | snd_iprintf(buffer, "Line out: %s\n", |
4948 | (hdspm->control_register & HDSPM_LineOut) ? "on " : "off"); | 4933 | (hdspm->control_register & HDSPM_LineOut) ? "on " : "off"); |
4949 | 4934 | ||
4950 | switch (hdspm->control_register & HDSPM_InputMask) { | ||
4951 | case HDSPM_InputOptical: | ||
4952 | insel = "Optical"; | ||
4953 | break; | ||
4954 | case HDSPM_InputCoaxial: | ||
4955 | insel = "Coaxial"; | ||
4956 | break; | ||
4957 | default: | ||
4958 | insel = "Unknown"; | ||
4959 | } | ||
4960 | |||
4961 | snd_iprintf(buffer, | 4935 | snd_iprintf(buffer, |
4962 | "ClearTrackMarker = %s, Transmit in %s Channel Mode, " | 4936 | "ClearTrackMarker = %s, Transmit in %s Channel Mode, " |
4963 | "Auto Input %s\n", | 4937 | "Auto Input %s\n", |
@@ -5202,15 +5176,13 @@ snd_hdspm_proc_read_raydat(struct snd_info_entry *entry, | |||
5202 | struct snd_info_buffer *buffer) | 5176 | struct snd_info_buffer *buffer) |
5203 | { | 5177 | { |
5204 | struct hdspm *hdspm = entry->private_data; | 5178 | struct hdspm *hdspm = entry->private_data; |
5205 | unsigned int status1, status2, status3, control, i; | 5179 | unsigned int status1, status2, status3, i; |
5206 | unsigned int lock, sync; | 5180 | unsigned int lock, sync; |
5207 | 5181 | ||
5208 | status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */ | 5182 | status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */ |
5209 | status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */ | 5183 | status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */ |
5210 | status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */ | 5184 | status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */ |
5211 | 5185 | ||
5212 | control = hdspm->control_register; | ||
5213 | |||
5214 | snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1); | 5186 | snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1); |
5215 | snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2); | 5187 | snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2); |
5216 | snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3); | 5188 | snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3); |
@@ -5431,7 +5403,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) | |||
5431 | HDSPM_midi2IRQPending | HDSPM_midi3IRQPending); | 5403 | HDSPM_midi2IRQPending | HDSPM_midi3IRQPending); |
5432 | 5404 | ||
5433 | /* now = get_cycles(); */ | 5405 | /* now = get_cycles(); */ |
5434 | /** | 5406 | /* |
5435 | * LAT_2..LAT_0 period counter (win) counter (mac) | 5407 | * LAT_2..LAT_0 period counter (win) counter (mac) |
5436 | * 6 4096 ~256053425 ~514672358 | 5408 | * 6 4096 ~256053425 ~514672358 |
5437 | * 5 2048 ~128024983 ~257373821 | 5409 | * 5 2048 ~128024983 ~257373821 |
@@ -5440,7 +5412,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) | |||
5440 | * 2 256 ~16003039 ~32260176 | 5412 | * 2 256 ~16003039 ~32260176 |
5441 | * 1 128 ~7998738 ~16194507 | 5413 | * 1 128 ~7998738 ~16194507 |
5442 | * 0 64 ~3998231 ~8191558 | 5414 | * 0 64 ~3998231 ~8191558 |
5443 | **/ | 5415 | */ |
5444 | /* | 5416 | /* |
5445 | dev_info(hdspm->card->dev, "snd_hdspm_interrupt %llu @ %llx\n", | 5417 | dev_info(hdspm->card->dev, "snd_hdspm_interrupt %llu @ %llx\n", |
5446 | now-hdspm->last_interrupt, status & 0xFFC0); | 5418 | now-hdspm->last_interrupt, status & 0xFFC0); |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index fa9a2a8dce5a..6521521853b8 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -920,15 +920,9 @@ static int rme9652_set_adat1_input(struct snd_rme9652 *rme9652, int internal) | |||
920 | 920 | ||
921 | static int snd_rme9652_info_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 921 | static int snd_rme9652_info_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
922 | { | 922 | { |
923 | static char *texts[2] = {"ADAT1", "Internal"}; | 923 | static const char * const texts[2] = {"ADAT1", "Internal"}; |
924 | 924 | ||
925 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 925 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
926 | uinfo->count = 1; | ||
927 | uinfo->value.enumerated.items = 2; | ||
928 | if (uinfo->value.enumerated.item > 1) | ||
929 | uinfo->value.enumerated.item = 1; | ||
930 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
931 | return 0; | ||
932 | } | 926 | } |
933 | 927 | ||
934 | static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 928 | static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -991,15 +985,9 @@ static int rme9652_set_spdif_input(struct snd_rme9652 *rme9652, int in) | |||
991 | 985 | ||
992 | static int snd_rme9652_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 986 | static int snd_rme9652_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
993 | { | 987 | { |
994 | static char *texts[3] = {"ADAT1", "Coaxial", "Internal"}; | 988 | static const char * const texts[3] = {"ADAT1", "Coaxial", "Internal"}; |
995 | 989 | ||
996 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 990 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
997 | uinfo->count = 1; | ||
998 | uinfo->value.enumerated.items = 3; | ||
999 | if (uinfo->value.enumerated.item > 2) | ||
1000 | uinfo->value.enumerated.item = 2; | ||
1001 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1002 | return 0; | ||
1003 | } | 991 | } |
1004 | 992 | ||
1005 | static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 993 | static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1140,15 +1128,11 @@ static int rme9652_set_sync_mode(struct snd_rme9652 *rme9652, int mode) | |||
1140 | 1128 | ||
1141 | static int snd_rme9652_info_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1129 | static int snd_rme9652_info_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1142 | { | 1130 | { |
1143 | static char *texts[3] = {"AutoSync", "Master", "Word Clock"}; | 1131 | static const char * const texts[3] = { |
1132 | "AutoSync", "Master", "Word Clock" | ||
1133 | }; | ||
1144 | 1134 | ||
1145 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1135 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
1146 | uinfo->count = 1; | ||
1147 | uinfo->value.enumerated.items = 3; | ||
1148 | if (uinfo->value.enumerated.item > 2) | ||
1149 | uinfo->value.enumerated.item = 2; | ||
1150 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1151 | return 0; | ||
1152 | } | 1136 | } |
1153 | 1137 | ||
1154 | static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1138 | static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1231,16 +1215,14 @@ static int rme9652_set_sync_pref(struct snd_rme9652 *rme9652, int pref) | |||
1231 | 1215 | ||
1232 | static int snd_rme9652_info_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1216 | static int snd_rme9652_info_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1233 | { | 1217 | { |
1234 | static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"}; | 1218 | static const char * const texts[4] = { |
1219 | "IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In" | ||
1220 | }; | ||
1235 | struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol); | 1221 | struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol); |
1236 | 1222 | ||
1237 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1223 | return snd_ctl_enum_info(uinfo, 1, |
1238 | uinfo->count = 1; | 1224 | rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3, |
1239 | uinfo->value.enumerated.items = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3; | 1225 | texts); |
1240 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1241 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1242 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1243 | return 0; | ||
1244 | } | 1226 | } |
1245 | 1227 | ||
1246 | static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1228 | static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1392,15 +1374,11 @@ static int snd_rme9652_get_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ | |||
1392 | 1374 | ||
1393 | static int snd_rme9652_info_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1375 | static int snd_rme9652_info_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1394 | { | 1376 | { |
1395 | static char *texts[4] = {"No Lock", "Lock", "No Lock Sync", "Lock Sync"}; | 1377 | static const char * const texts[4] = { |
1378 | "No Lock", "Lock", "No Lock Sync", "Lock Sync" | ||
1379 | }; | ||
1396 | 1380 | ||
1397 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1381 | return snd_ctl_enum_info(uinfo, 1, 4, texts); |
1398 | uinfo->count = 1; | ||
1399 | uinfo->value.enumerated.items = 4; | ||
1400 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1401 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1402 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1403 | return 0; | ||
1404 | } | 1382 | } |
1405 | 1383 | ||
1406 | static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1384 | static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 5b0d317cc9a6..313a7328bf9c 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -918,17 +918,11 @@ static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device, | |||
918 | 918 | ||
919 | static int snd_sonicvibes_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 919 | static int snd_sonicvibes_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
920 | { | 920 | { |
921 | static char *texts[7] = { | 921 | static const char * const texts[7] = { |
922 | "CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix" | 922 | "CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix" |
923 | }; | 923 | }; |
924 | 924 | ||
925 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 925 | return snd_ctl_enum_info(uinfo, 2, 7, texts); |
926 | uinfo->count = 2; | ||
927 | uinfo->value.enumerated.items = 7; | ||
928 | if (uinfo->value.enumerated.item >= 7) | ||
929 | uinfo->value.enumerated.item = 6; | ||
930 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
931 | return 0; | ||
932 | } | 926 | } |
933 | 927 | ||
934 | static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 928 | static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index da875dced2ef..57cd757acfe7 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
@@ -3702,8 +3702,7 @@ static int snd_trident_free(struct snd_trident *trident) | |||
3702 | free_irq(trident->irq, trident); | 3702 | free_irq(trident->irq, trident); |
3703 | if (trident->tlb.buffer.area) { | 3703 | if (trident->tlb.buffer.area) { |
3704 | outl(0, TRID_REG(trident, NX_TLBC)); | 3704 | outl(0, TRID_REG(trident, NX_TLBC)); |
3705 | if (trident->tlb.memhdr) | 3705 | snd_util_memhdr_free(trident->tlb.memhdr); |
3706 | snd_util_memhdr_free(trident->tlb.memhdr); | ||
3707 | if (trident->tlb.silent_page.area) | 3706 | if (trident->tlb.silent_page.area) |
3708 | snd_dma_free_pages(&trident->tlb.silent_page); | 3707 | snd_dma_free_pages(&trident->tlb.silent_page); |
3709 | vfree(trident->tlb.shadow_entries); | 3708 | vfree(trident->tlb.shadow_entries); |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index ecedf4dbfa2a..e088467fb736 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -1610,16 +1610,10 @@ static int snd_via8233_capture_source_info(struct snd_kcontrol *kcontrol, | |||
1610 | /* formerly they were "Line" and "Mic", but it looks like that they | 1610 | /* formerly they were "Line" and "Mic", but it looks like that they |
1611 | * have nothing to do with the actual physical connections... | 1611 | * have nothing to do with the actual physical connections... |
1612 | */ | 1612 | */ |
1613 | static char *texts[2] = { | 1613 | static const char * const texts[2] = { |
1614 | "Input1", "Input2" | 1614 | "Input1", "Input2" |
1615 | }; | 1615 | }; |
1616 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1616 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
1617 | uinfo->count = 1; | ||
1618 | uinfo->value.enumerated.items = 2; | ||
1619 | if (uinfo->value.enumerated.item >= 2) | ||
1620 | uinfo->value.enumerated.item = 1; | ||
1621 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1622 | return 0; | ||
1623 | } | 1617 | } |
1624 | 1618 | ||
1625 | static int snd_via8233_capture_source_get(struct snd_kcontrol *kcontrol, | 1619 | static int snd_via8233_capture_source_get(struct snd_kcontrol *kcontrol, |
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index 2d1570273e99..52c1a8d5b88a 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c | |||
@@ -92,6 +92,7 @@ static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg) | |||
92 | 92 | ||
93 | /** | 93 | /** |
94 | * snd_vx_inb - read a byte from the register | 94 | * snd_vx_inb - read a byte from the register |
95 | * @chip: VX core instance | ||
95 | * @offset: register enum | 96 | * @offset: register enum |
96 | */ | 97 | */ |
97 | static unsigned char vx2_inb(struct vx_core *chip, int offset) | 98 | static unsigned char vx2_inb(struct vx_core *chip, int offset) |
@@ -101,6 +102,7 @@ static unsigned char vx2_inb(struct vx_core *chip, int offset) | |||
101 | 102 | ||
102 | /** | 103 | /** |
103 | * snd_vx_outb - write a byte on the register | 104 | * snd_vx_outb - write a byte on the register |
105 | * @chip: VX core instance | ||
104 | * @offset: the register offset | 106 | * @offset: the register offset |
105 | * @val: the value to write | 107 | * @val: the value to write |
106 | */ | 108 | */ |
@@ -114,6 +116,7 @@ static void vx2_outb(struct vx_core *chip, int offset, unsigned char val) | |||
114 | 116 | ||
115 | /** | 117 | /** |
116 | * snd_vx_inl - read a 32bit word from the register | 118 | * snd_vx_inl - read a 32bit word from the register |
119 | * @chip: VX core instance | ||
117 | * @offset: register enum | 120 | * @offset: register enum |
118 | */ | 121 | */ |
119 | static unsigned int vx2_inl(struct vx_core *chip, int offset) | 122 | static unsigned int vx2_inl(struct vx_core *chip, int offset) |
@@ -123,6 +126,7 @@ static unsigned int vx2_inl(struct vx_core *chip, int offset) | |||
123 | 126 | ||
124 | /** | 127 | /** |
125 | * snd_vx_outl - write a 32bit word on the register | 128 | * snd_vx_outl - write a 32bit word on the register |
129 | * @chip: VX core instance | ||
126 | * @offset: the register enum | 130 | * @offset: the register enum |
127 | * @val: the value to write | 131 | * @val: the value to write |
128 | */ | 132 | */ |
@@ -223,6 +227,7 @@ static int vx2_test_xilinx(struct vx_core *_chip) | |||
223 | 227 | ||
224 | /** | 228 | /** |
225 | * vx_setup_pseudo_dma - set up the pseudo dma read/write mode. | 229 | * vx_setup_pseudo_dma - set up the pseudo dma read/write mode. |
230 | * @chip: VX core instance | ||
226 | * @do_write: 0 = read, 1 = set up for DMA write | 231 | * @do_write: 0 = read, 1 = set up for DMA write |
227 | */ | 232 | */ |
228 | static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write) | 233 | static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write) |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 92ec11456e3a..b16f42deed67 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -174,6 +174,7 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, | |||
174 | 174 | ||
175 | /** | 175 | /** |
176 | * snd_vxpocket_assign_resources - initialize the hardware and card instance. | 176 | * snd_vxpocket_assign_resources - initialize the hardware and card instance. |
177 | * @chip: VX core instance | ||
177 | * @port: i/o port for the card | 178 | * @port: i/o port for the card |
178 | * @irq: irq number for the card | 179 | * @irq: irq number for the card |
179 | * | 180 | * |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 8a431bcb056c..5a13b22748b2 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -887,8 +887,7 @@ static int snd_pmac_free(struct snd_pmac *chip) | |||
887 | } | 887 | } |
888 | } | 888 | } |
889 | 889 | ||
890 | if (chip->pdev) | 890 | pci_dev_put(chip->pdev); |
891 | pci_dev_put(chip->pdev); | ||
892 | of_node_put(chip->node); | 891 | of_node_put(chip->node); |
893 | kfree(chip); | 892 | kfree(chip); |
894 | return 0; | 893 | return 0; |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index b9ffc17a4799..24c8766a925d 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -795,16 +795,11 @@ static int snapper_set_capture_source(struct pmac_tumbler *mix) | |||
795 | static int snapper_info_capture_source(struct snd_kcontrol *kcontrol, | 795 | static int snapper_info_capture_source(struct snd_kcontrol *kcontrol, |
796 | struct snd_ctl_elem_info *uinfo) | 796 | struct snd_ctl_elem_info *uinfo) |
797 | { | 797 | { |
798 | static char *texts[2] = { | 798 | static const char * const texts[2] = { |
799 | "Line", "Mic" | 799 | "Line", "Mic" |
800 | }; | 800 | }; |
801 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 801 | |
802 | uinfo->count = 1; | 802 | return snd_ctl_enum_info(uinfo, 1, 2, texts); |
803 | uinfo->value.enumerated.items = 2; | ||
804 | if (uinfo->value.enumerated.item > 1) | ||
805 | uinfo->value.enumerated.item = 1; | ||
806 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
807 | return 0; | ||
808 | } | 803 | } |
809 | 804 | ||
810 | static int snapper_get_capture_source(struct snd_kcontrol *kcontrol, | 805 | static int snapper_get_capture_source(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index b79a2a864513..33fb3bb133df 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c | |||
@@ -80,9 +80,7 @@ static void atmel_pcm_dma_irq(u32 ssc_sr, | |||
80 | 80 | ||
81 | /* stop RX and capture: will be enabled again at restart */ | 81 | /* stop RX and capture: will be enabled again at restart */ |
82 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); | 82 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); |
83 | snd_pcm_stream_lock(substream); | 83 | snd_pcm_stop_xrun(substream); |
84 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
85 | snd_pcm_stream_unlock(substream); | ||
86 | 84 | ||
87 | /* now drain RHR and read status to remove xrun condition */ | 85 | /* now drain RHR and read status to remove xrun condition */ |
88 | ssc_readx(prtd->ssc->regs, SSC_RHR); | 86 | ssc_readx(prtd->ssc->regs, SSC_RHR); |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index a609aafc994d..b2b108805b24 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -151,14 +151,7 @@ static const struct snd_pcm_hardware fsl_dma_hardware = { | |||
151 | */ | 151 | */ |
152 | static void fsl_dma_abort_stream(struct snd_pcm_substream *substream) | 152 | static void fsl_dma_abort_stream(struct snd_pcm_substream *substream) |
153 | { | 153 | { |
154 | unsigned long flags; | 154 | snd_pcm_stop_xrun(substream); |
155 | |||
156 | snd_pcm_stream_lock_irqsave(substream, flags); | ||
157 | |||
158 | if (snd_pcm_running(substream)) | ||
159 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
160 | |||
161 | snd_pcm_stream_unlock_irqrestore(substream, flags); | ||
162 | } | 155 | } |
163 | 156 | ||
164 | /** | 157 | /** |
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 4e91bcaa3664..06606f9bbf78 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -1285,19 +1285,11 @@ static int snd_cs4231_timer(struct snd_card *card) | |||
1285 | static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, | 1285 | static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, |
1286 | struct snd_ctl_elem_info *uinfo) | 1286 | struct snd_ctl_elem_info *uinfo) |
1287 | { | 1287 | { |
1288 | static char *texts[4] = { | 1288 | static const char * const texts[4] = { |
1289 | "Line", "CD", "Mic", "Mix" | 1289 | "Line", "CD", "Mic", "Mix" |
1290 | }; | 1290 | }; |
1291 | 1291 | ||
1292 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1292 | return snd_ctl_enum_info(uinfo, 2, 4, texts); |
1293 | uinfo->count = 2; | ||
1294 | uinfo->value.enumerated.items = 4; | ||
1295 | if (uinfo->value.enumerated.item > 3) | ||
1296 | uinfo->value.enumerated.item = 3; | ||
1297 | strcpy(uinfo->value.enumerated.name, | ||
1298 | texts[uinfo->value.enumerated.item]); | ||
1299 | |||
1300 | return 0; | ||
1301 | } | 1293 | } |
1302 | 1294 | ||
1303 | static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, | 1295 | static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, |
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index 184e3987ac24..54656eed6e2e 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include "comm.h" | 25 | #include "comm.h" |
26 | #include "chip.h" | 26 | #include "chip.h" |
27 | 27 | ||
28 | static char *opt_coax_texts[2] = { "Optical", "Coax" }; | 28 | static const char * const opt_coax_texts[2] = { "Optical", "Coax" }; |
29 | static char *line_phono_texts[2] = { "Line", "Phono" }; | 29 | static const char * const line_phono_texts[2] = { "Line", "Phono" }; |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * data that needs to be sent to device. sets up card internal stuff. | 32 | * data that needs to be sent to device. sets up card internal stuff. |
@@ -327,14 +327,7 @@ static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol, | |||
327 | static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol, | 327 | static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol, |
328 | struct snd_ctl_elem_info *uinfo) | 328 | struct snd_ctl_elem_info *uinfo) |
329 | { | 329 | { |
330 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 330 | return snd_ctl_enum_info(uinfo, 1, 2, line_phono_texts); |
331 | uinfo->count = 1; | ||
332 | uinfo->value.enumerated.items = 2; | ||
333 | if (uinfo->value.enumerated.item > 1) | ||
334 | uinfo->value.enumerated.item = 1; | ||
335 | strcpy(uinfo->value.enumerated.name, | ||
336 | line_phono_texts[uinfo->value.enumerated.item]); | ||
337 | return 0; | ||
338 | } | 331 | } |
339 | 332 | ||
340 | static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol, | 333 | static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol, |
@@ -361,14 +354,7 @@ static int usb6fire_control_line_phono_get(struct snd_kcontrol *kcontrol, | |||
361 | static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol, | 354 | static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol, |
362 | struct snd_ctl_elem_info *uinfo) | 355 | struct snd_ctl_elem_info *uinfo) |
363 | { | 356 | { |
364 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 357 | return snd_ctl_enum_info(uinfo, 1, 2, opt_coax_texts); |
365 | uinfo->count = 1; | ||
366 | uinfo->value.enumerated.items = 2; | ||
367 | if (uinfo->value.enumerated.item > 1) | ||
368 | uinfo->value.enumerated.item = 1; | ||
369 | strcpy(uinfo->value.enumerated.name, | ||
370 | opt_coax_texts[uinfo->value.enumerated.item]); | ||
371 | return 0; | ||
372 | } | 358 | } |
373 | 359 | ||
374 | static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol, | 360 | static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol, |
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 3b02e54b8f6d..62c25e74f0e5 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
@@ -316,7 +316,7 @@ static int usb6fire_fw_fpga_upload( | |||
316 | 316 | ||
317 | while (c != end) { | 317 | while (c != end) { |
318 | for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) | 318 | for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) |
319 | buffer[i] = byte_rev_table[(u8) *c]; | 319 | buffer[i] = bitrev8((u8)*c); |
320 | 320 | ||
321 | ret = usb6fire_fw_fpga_write(device, buffer, i); | 321 | ret = usb6fire_fw_fpga_write(device, buffer, i); |
322 | if (ret < 0) { | 322 | if (ret < 0) { |
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index ba40489b2de4..36f4115eb1cd 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -679,25 +679,16 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | |||
679 | void usb6fire_pcm_abort(struct sfire_chip *chip) | 679 | void usb6fire_pcm_abort(struct sfire_chip *chip) |
680 | { | 680 | { |
681 | struct pcm_runtime *rt = chip->pcm; | 681 | struct pcm_runtime *rt = chip->pcm; |
682 | unsigned long flags; | ||
683 | int i; | 682 | int i; |
684 | 683 | ||
685 | if (rt) { | 684 | if (rt) { |
686 | rt->panic = true; | 685 | rt->panic = true; |
687 | 686 | ||
688 | if (rt->playback.instance) { | 687 | if (rt->playback.instance) |
689 | snd_pcm_stream_lock_irqsave(rt->playback.instance, flags); | 688 | snd_pcm_stop_xrun(rt->playback.instance); |
690 | snd_pcm_stop(rt->playback.instance, | ||
691 | SNDRV_PCM_STATE_XRUN); | ||
692 | snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags); | ||
693 | } | ||
694 | 689 | ||
695 | if (rt->capture.instance) { | 690 | if (rt->capture.instance) |
696 | snd_pcm_stream_lock_irqsave(rt->capture.instance, flags); | 691 | snd_pcm_stop_xrun(rt->capture.instance); |
697 | snd_pcm_stop(rt->capture.instance, | ||
698 | SNDRV_PCM_STATE_XRUN); | ||
699 | snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags); | ||
700 | } | ||
701 | 692 | ||
702 | for (i = 0; i < PCM_N_URBS; i++) { | 693 | for (i = 0; i < PCM_N_URBS; i++) { |
703 | usb_poison_urb(&rt->in_urbs[i].instance); | 694 | usb_poison_urb(&rt->in_urbs[i].instance); |
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 2b92f0dcbc4c..bcee4060fd18 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
@@ -9,6 +9,7 @@ snd-usb-audio-objs := card.o \ | |||
9 | helper.o \ | 9 | helper.o \ |
10 | mixer.o \ | 10 | mixer.o \ |
11 | mixer_quirks.o \ | 11 | mixer_quirks.o \ |
12 | mixer_scarlett.o \ | ||
12 | pcm.o \ | 13 | pcm.o \ |
13 | proc.o \ | 14 | proc.o \ |
14 | quirks.o \ | 15 | quirks.o \ |
diff --git a/sound/usb/card.c b/sound/usb/card.c index f61ebb17cc64..1fab9778807a 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -112,15 +112,13 @@ static struct usb_driver usb_audio_driver; | |||
112 | 112 | ||
113 | /* | 113 | /* |
114 | * disconnect streams | 114 | * disconnect streams |
115 | * called from snd_usb_audio_disconnect() | 115 | * called from usb_audio_disconnect() |
116 | */ | 116 | */ |
117 | static void snd_usb_stream_disconnect(struct list_head *head) | 117 | static void snd_usb_stream_disconnect(struct snd_usb_stream *as) |
118 | { | 118 | { |
119 | int idx; | 119 | int idx; |
120 | struct snd_usb_stream *as; | ||
121 | struct snd_usb_substream *subs; | 120 | struct snd_usb_substream *subs; |
122 | 121 | ||
123 | as = list_entry(head, struct snd_usb_stream, list); | ||
124 | for (idx = 0; idx < 2; idx++) { | 122 | for (idx = 0; idx < 2; idx++) { |
125 | subs = &as->substream[idx]; | 123 | subs = &as->substream[idx]; |
126 | if (!subs->num_formats) | 124 | if (!subs->num_formats) |
@@ -307,10 +305,10 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
307 | 305 | ||
308 | static int snd_usb_audio_free(struct snd_usb_audio *chip) | 306 | static int snd_usb_audio_free(struct snd_usb_audio *chip) |
309 | { | 307 | { |
310 | struct list_head *p, *n; | 308 | struct snd_usb_endpoint *ep, *n; |
311 | 309 | ||
312 | list_for_each_safe(p, n, &chip->ep_list) | 310 | list_for_each_entry_safe(ep, n, &chip->ep_list, list) |
313 | snd_usb_endpoint_free(p); | 311 | snd_usb_endpoint_free(ep); |
314 | 312 | ||
315 | mutex_destroy(&chip->mutex); | 313 | mutex_destroy(&chip->mutex); |
316 | kfree(chip); | 314 | kfree(chip); |
@@ -323,16 +321,6 @@ static int snd_usb_audio_dev_free(struct snd_device *device) | |||
323 | return snd_usb_audio_free(chip); | 321 | return snd_usb_audio_free(chip); |
324 | } | 322 | } |
325 | 323 | ||
326 | static void remove_trailing_spaces(char *str) | ||
327 | { | ||
328 | char *p; | ||
329 | |||
330 | if (!*str) | ||
331 | return; | ||
332 | for (p = str + strlen(str) - 1; p >= str && isspace(*p); p--) | ||
333 | *p = 0; | ||
334 | } | ||
335 | |||
336 | /* | 324 | /* |
337 | * create a chip instance and set its names. | 325 | * create a chip instance and set its names. |
338 | */ | 326 | */ |
@@ -416,7 +404,7 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
416 | USB_ID_PRODUCT(chip->usb_id)); | 404 | USB_ID_PRODUCT(chip->usb_id)); |
417 | } | 405 | } |
418 | } | 406 | } |
419 | remove_trailing_spaces(card->shortname); | 407 | strim(card->shortname); |
420 | 408 | ||
421 | /* retrieve the vendor and device strings as longname */ | 409 | /* retrieve the vendor and device strings as longname */ |
422 | if (quirk && quirk->vendor_name && *quirk->vendor_name) { | 410 | if (quirk && quirk->vendor_name && *quirk->vendor_name) { |
@@ -430,7 +418,7 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
430 | /* we don't really care if there isn't any vendor string */ | 418 | /* we don't really care if there isn't any vendor string */ |
431 | } | 419 | } |
432 | if (len > 0) { | 420 | if (len > 0) { |
433 | remove_trailing_spaces(card->longname); | 421 | strim(card->longname); |
434 | if (*card->longname) | 422 | if (*card->longname) |
435 | strlcat(card->longname, " ", sizeof(card->longname)); | 423 | strlcat(card->longname, " ", sizeof(card->longname)); |
436 | } | 424 | } |
@@ -475,14 +463,14 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
475 | * only at the first time. the successive calls of this function will | 463 | * only at the first time. the successive calls of this function will |
476 | * append the pcm interface to the corresponding card. | 464 | * append the pcm interface to the corresponding card. |
477 | */ | 465 | */ |
478 | static struct snd_usb_audio * | 466 | static int usb_audio_probe(struct usb_interface *intf, |
479 | snd_usb_audio_probe(struct usb_device *dev, | 467 | const struct usb_device_id *usb_id) |
480 | struct usb_interface *intf, | ||
481 | const struct usb_device_id *usb_id) | ||
482 | { | 468 | { |
483 | const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info; | 469 | struct usb_device *dev = interface_to_usbdev(intf); |
484 | int i, err; | 470 | const struct snd_usb_audio_quirk *quirk = |
471 | (const struct snd_usb_audio_quirk *)usb_id->driver_info; | ||
485 | struct snd_usb_audio *chip; | 472 | struct snd_usb_audio *chip; |
473 | int i, err; | ||
486 | struct usb_host_interface *alts; | 474 | struct usb_host_interface *alts; |
487 | int ifnum; | 475 | int ifnum; |
488 | u32 id; | 476 | u32 id; |
@@ -492,10 +480,11 @@ snd_usb_audio_probe(struct usb_device *dev, | |||
492 | id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), | 480 | id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), |
493 | le16_to_cpu(dev->descriptor.idProduct)); | 481 | le16_to_cpu(dev->descriptor.idProduct)); |
494 | if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) | 482 | if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) |
495 | goto __err_val; | 483 | return -ENXIO; |
496 | 484 | ||
497 | if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0) | 485 | err = snd_usb_apply_boot_quirk(dev, intf, quirk); |
498 | goto __err_val; | 486 | if (err < 0) |
487 | return err; | ||
499 | 488 | ||
500 | /* | 489 | /* |
501 | * found a config. now register to ALSA | 490 | * found a config. now register to ALSA |
@@ -508,6 +497,7 @@ snd_usb_audio_probe(struct usb_device *dev, | |||
508 | if (usb_chip[i] && usb_chip[i]->dev == dev) { | 497 | if (usb_chip[i] && usb_chip[i]->dev == dev) { |
509 | if (usb_chip[i]->shutdown) { | 498 | if (usb_chip[i]->shutdown) { |
510 | dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n"); | 499 | dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n"); |
500 | err = -EIO; | ||
511 | goto __error; | 501 | goto __error; |
512 | } | 502 | } |
513 | chip = usb_chip[i]; | 503 | chip = usb_chip[i]; |
@@ -523,15 +513,16 @@ snd_usb_audio_probe(struct usb_device *dev, | |||
523 | if (enable[i] && ! usb_chip[i] && | 513 | if (enable[i] && ! usb_chip[i] && |
524 | (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && | 514 | (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && |
525 | (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { | 515 | (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { |
526 | if (snd_usb_audio_create(intf, dev, i, quirk, | 516 | err = snd_usb_audio_create(intf, dev, i, quirk, |
527 | &chip) < 0) { | 517 | &chip); |
518 | if (err < 0) | ||
528 | goto __error; | 519 | goto __error; |
529 | } | ||
530 | chip->pm_intf = intf; | 520 | chip->pm_intf = intf; |
531 | break; | 521 | break; |
532 | } | 522 | } |
533 | if (!chip) { | 523 | if (!chip) { |
534 | dev_err(&dev->dev, "no available usb audio device\n"); | 524 | dev_err(&dev->dev, "no available usb audio device\n"); |
525 | err = -ENODEV; | ||
535 | goto __error; | 526 | goto __error; |
536 | } | 527 | } |
537 | } | 528 | } |
@@ -548,28 +539,32 @@ snd_usb_audio_probe(struct usb_device *dev, | |||
548 | err = 1; /* continue */ | 539 | err = 1; /* continue */ |
549 | if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { | 540 | if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { |
550 | /* need some special handlings */ | 541 | /* need some special handlings */ |
551 | if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0) | 542 | err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk); |
543 | if (err < 0) | ||
552 | goto __error; | 544 | goto __error; |
553 | } | 545 | } |
554 | 546 | ||
555 | if (err > 0) { | 547 | if (err > 0) { |
556 | /* create normal USB audio interfaces */ | 548 | /* create normal USB audio interfaces */ |
557 | if (snd_usb_create_streams(chip, ifnum) < 0 || | 549 | err = snd_usb_create_streams(chip, ifnum); |
558 | snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) { | 550 | if (err < 0) |
551 | goto __error; | ||
552 | err = snd_usb_create_mixer(chip, ifnum, ignore_ctl_error); | ||
553 | if (err < 0) | ||
559 | goto __error; | 554 | goto __error; |
560 | } | ||
561 | } | 555 | } |
562 | 556 | ||
563 | /* we are allowed to call snd_card_register() many times */ | 557 | /* we are allowed to call snd_card_register() many times */ |
564 | if (snd_card_register(chip->card) < 0) { | 558 | err = snd_card_register(chip->card); |
559 | if (err < 0) | ||
565 | goto __error; | 560 | goto __error; |
566 | } | ||
567 | 561 | ||
568 | usb_chip[chip->index] = chip; | 562 | usb_chip[chip->index] = chip; |
569 | chip->num_interfaces++; | 563 | chip->num_interfaces++; |
570 | chip->probing = 0; | 564 | chip->probing = 0; |
565 | usb_set_intfdata(intf, chip); | ||
571 | mutex_unlock(®ister_mutex); | 566 | mutex_unlock(®ister_mutex); |
572 | return chip; | 567 | return 0; |
573 | 568 | ||
574 | __error: | 569 | __error: |
575 | if (chip) { | 570 | if (chip) { |
@@ -578,17 +573,16 @@ snd_usb_audio_probe(struct usb_device *dev, | |||
578 | chip->probing = 0; | 573 | chip->probing = 0; |
579 | } | 574 | } |
580 | mutex_unlock(®ister_mutex); | 575 | mutex_unlock(®ister_mutex); |
581 | __err_val: | 576 | return err; |
582 | return NULL; | ||
583 | } | 577 | } |
584 | 578 | ||
585 | /* | 579 | /* |
586 | * we need to take care of counter, since disconnection can be called also | 580 | * we need to take care of counter, since disconnection can be called also |
587 | * many times as well as usb_audio_probe(). | 581 | * many times as well as usb_audio_probe(). |
588 | */ | 582 | */ |
589 | static void snd_usb_audio_disconnect(struct usb_device *dev, | 583 | static void usb_audio_disconnect(struct usb_interface *intf) |
590 | struct snd_usb_audio *chip) | ||
591 | { | 584 | { |
585 | struct snd_usb_audio *chip = usb_get_intfdata(intf); | ||
592 | struct snd_card *card; | 586 | struct snd_card *card; |
593 | struct list_head *p; | 587 | struct list_head *p; |
594 | bool was_shutdown; | 588 | bool was_shutdown; |
@@ -604,12 +598,14 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
604 | 598 | ||
605 | mutex_lock(®ister_mutex); | 599 | mutex_lock(®ister_mutex); |
606 | if (!was_shutdown) { | 600 | if (!was_shutdown) { |
601 | struct snd_usb_stream *as; | ||
607 | struct snd_usb_endpoint *ep; | 602 | struct snd_usb_endpoint *ep; |
603 | struct usb_mixer_interface *mixer; | ||
608 | 604 | ||
609 | snd_card_disconnect(card); | 605 | snd_card_disconnect(card); |
610 | /* release the pcm resources */ | 606 | /* release the pcm resources */ |
611 | list_for_each(p, &chip->pcm_list) { | 607 | list_for_each_entry(as, &chip->pcm_list, list) { |
612 | snd_usb_stream_disconnect(p); | 608 | snd_usb_stream_disconnect(as); |
613 | } | 609 | } |
614 | /* release the endpoint resources */ | 610 | /* release the endpoint resources */ |
615 | list_for_each_entry(ep, &chip->ep_list, list) { | 611 | list_for_each_entry(ep, &chip->ep_list, list) { |
@@ -620,8 +616,8 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
620 | snd_usbmidi_disconnect(p); | 616 | snd_usbmidi_disconnect(p); |
621 | } | 617 | } |
622 | /* release mixer resources */ | 618 | /* release mixer resources */ |
623 | list_for_each(p, &chip->mixer_list) { | 619 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
624 | snd_usb_mixer_disconnect(p); | 620 | snd_usb_mixer_disconnect(mixer); |
625 | } | 621 | } |
626 | } | 622 | } |
627 | 623 | ||
@@ -635,27 +631,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
635 | } | 631 | } |
636 | } | 632 | } |
637 | 633 | ||
638 | /* | ||
639 | * new 2.5 USB kernel API | ||
640 | */ | ||
641 | static int usb_audio_probe(struct usb_interface *intf, | ||
642 | const struct usb_device_id *id) | ||
643 | { | ||
644 | struct snd_usb_audio *chip; | ||
645 | chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); | ||
646 | if (chip) { | ||
647 | usb_set_intfdata(intf, chip); | ||
648 | return 0; | ||
649 | } else | ||
650 | return -EIO; | ||
651 | } | ||
652 | |||
653 | static void usb_audio_disconnect(struct usb_interface *intf) | ||
654 | { | ||
655 | snd_usb_audio_disconnect(interface_to_usbdev(intf), | ||
656 | usb_get_intfdata(intf)); | ||
657 | } | ||
658 | |||
659 | #ifdef CONFIG_PM | 634 | #ifdef CONFIG_PM |
660 | 635 | ||
661 | int snd_usb_autoresume(struct snd_usb_audio *chip) | 636 | int snd_usb_autoresume(struct snd_usb_audio *chip) |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 114e3e7ff511..03b074419964 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -348,6 +348,8 @@ static void snd_complete_urb(struct urb *urb) | |||
348 | { | 348 | { |
349 | struct snd_urb_ctx *ctx = urb->context; | 349 | struct snd_urb_ctx *ctx = urb->context; |
350 | struct snd_usb_endpoint *ep = ctx->ep; | 350 | struct snd_usb_endpoint *ep = ctx->ep; |
351 | struct snd_pcm_substream *substream; | ||
352 | unsigned long flags; | ||
351 | int err; | 353 | int err; |
352 | 354 | ||
353 | if (unlikely(urb->status == -ENOENT || /* unlinked */ | 355 | if (unlikely(urb->status == -ENOENT || /* unlinked */ |
@@ -364,8 +366,6 @@ static void snd_complete_urb(struct urb *urb) | |||
364 | goto exit_clear; | 366 | goto exit_clear; |
365 | 367 | ||
366 | if (snd_usb_endpoint_implicit_feedback_sink(ep)) { | 368 | if (snd_usb_endpoint_implicit_feedback_sink(ep)) { |
367 | unsigned long flags; | ||
368 | |||
369 | spin_lock_irqsave(&ep->lock, flags); | 369 | spin_lock_irqsave(&ep->lock, flags); |
370 | list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); | 370 | list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); |
371 | spin_unlock_irqrestore(&ep->lock, flags); | 371 | spin_unlock_irqrestore(&ep->lock, flags); |
@@ -389,7 +389,10 @@ static void snd_complete_urb(struct urb *urb) | |||
389 | return; | 389 | return; |
390 | 390 | ||
391 | usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); | 391 | usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); |
392 | //snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | 392 | if (ep->data_subs && ep->data_subs->pcm_substream) { |
393 | substream = ep->data_subs->pcm_substream; | ||
394 | snd_pcm_stop_xrun(substream); | ||
395 | } | ||
393 | 396 | ||
394 | exit_clear: | 397 | exit_clear: |
395 | clear_bit(ctx->index, &ep->active_mask); | 398 | clear_bit(ctx->index, &ep->active_mask); |
@@ -1002,15 +1005,12 @@ void snd_usb_endpoint_release(struct snd_usb_endpoint *ep) | |||
1002 | /** | 1005 | /** |
1003 | * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint | 1006 | * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint |
1004 | * | 1007 | * |
1005 | * @ep: the list header of the endpoint to free | 1008 | * @ep: the endpoint to free |
1006 | * | 1009 | * |
1007 | * This free all resources of the given ep. | 1010 | * This free all resources of the given ep. |
1008 | */ | 1011 | */ |
1009 | void snd_usb_endpoint_free(struct list_head *head) | 1012 | void snd_usb_endpoint_free(struct snd_usb_endpoint *ep) |
1010 | { | 1013 | { |
1011 | struct snd_usb_endpoint *ep; | ||
1012 | |||
1013 | ep = list_entry(head, struct snd_usb_endpoint, list); | ||
1014 | kfree(ep); | 1014 | kfree(ep); |
1015 | } | 1015 | } |
1016 | 1016 | ||
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index e61ee5c356a3..6428392d8f62 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h | |||
@@ -24,7 +24,7 @@ void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); | |||
24 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); | 24 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); |
25 | void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); | 25 | void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); |
26 | void snd_usb_endpoint_release(struct snd_usb_endpoint *ep); | 26 | void snd_usb_endpoint_release(struct snd_usb_endpoint *ep); |
27 | void snd_usb_endpoint_free(struct list_head *head); | 27 | void snd_usb_endpoint_free(struct snd_usb_endpoint *ep); |
28 | 28 | ||
29 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); | 29 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); |
30 | int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep); | 30 | int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep); |
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index a1bab149df4d..9581089c28c5 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c | |||
@@ -613,24 +613,14 @@ static int start_usb_playback(struct ua101 *ua) | |||
613 | 613 | ||
614 | static void abort_alsa_capture(struct ua101 *ua) | 614 | static void abort_alsa_capture(struct ua101 *ua) |
615 | { | 615 | { |
616 | unsigned long flags; | 616 | if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) |
617 | 617 | snd_pcm_stop_xrun(ua->capture.substream); | |
618 | if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) { | ||
619 | snd_pcm_stream_lock_irqsave(ua->capture.substream, flags); | ||
620 | snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN); | ||
621 | snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags); | ||
622 | } | ||
623 | } | 618 | } |
624 | 619 | ||
625 | static void abort_alsa_playback(struct ua101 *ua) | 620 | static void abort_alsa_playback(struct ua101 *ua) |
626 | { | 621 | { |
627 | unsigned long flags; | 622 | if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) |
628 | 623 | snd_pcm_stop_xrun(ua->playback.substream); | |
629 | if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) { | ||
630 | snd_pcm_stream_lock_irqsave(ua->playback.substream, flags); | ||
631 | snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN); | ||
632 | snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags); | ||
633 | } | ||
634 | } | 624 | } |
635 | 625 | ||
636 | static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, | 626 | static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 6e354d326858..41650d5b93b7 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -136,6 +136,10 @@ check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen) | |||
136 | return strlcpy(buf, p->name, buflen); | 136 | return strlcpy(buf, p->name, buflen); |
137 | } | 137 | } |
138 | 138 | ||
139 | /* ignore the error value if ignore_ctl_error flag is set */ | ||
140 | #define filter_error(cval, err) \ | ||
141 | ((cval)->head.mixer->ignore_ctl_error ? 0 : (err)) | ||
142 | |||
139 | /* check whether the control should be ignored */ | 143 | /* check whether the control should be ignored */ |
140 | static inline int | 144 | static inline int |
141 | check_ignored_ctl(const struct usbmix_name_map *p) | 145 | check_ignored_ctl(const struct usbmix_name_map *p) |
@@ -286,13 +290,13 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val) | |||
286 | static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, | 290 | static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, |
287 | int validx, int *value_ret) | 291 | int validx, int *value_ret) |
288 | { | 292 | { |
289 | struct snd_usb_audio *chip = cval->mixer->chip; | 293 | struct snd_usb_audio *chip = cval->head.mixer->chip; |
290 | unsigned char buf[2]; | 294 | unsigned char buf[2]; |
291 | int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 295 | int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
292 | int timeout = 10; | 296 | int timeout = 10; |
293 | int idx = 0, err; | 297 | int idx = 0, err; |
294 | 298 | ||
295 | err = snd_usb_autoresume(cval->mixer->chip); | 299 | err = snd_usb_autoresume(chip); |
296 | if (err < 0) | 300 | if (err < 0) |
297 | return -EIO; | 301 | return -EIO; |
298 | 302 | ||
@@ -300,7 +304,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, | |||
300 | while (timeout-- > 0) { | 304 | while (timeout-- > 0) { |
301 | if (chip->shutdown) | 305 | if (chip->shutdown) |
302 | break; | 306 | break; |
303 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | 307 | idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); |
304 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, | 308 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, |
305 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 309 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
306 | validx, idx, buf, val_len) >= val_len) { | 310 | validx, idx, buf, val_len) >= val_len) { |
@@ -316,14 +320,14 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, | |||
316 | 320 | ||
317 | out: | 321 | out: |
318 | up_read(&chip->shutdown_rwsem); | 322 | up_read(&chip->shutdown_rwsem); |
319 | snd_usb_autosuspend(cval->mixer->chip); | 323 | snd_usb_autosuspend(chip); |
320 | return err; | 324 | return err; |
321 | } | 325 | } |
322 | 326 | ||
323 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, | 327 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, |
324 | int validx, int *value_ret) | 328 | int validx, int *value_ret) |
325 | { | 329 | { |
326 | struct snd_usb_audio *chip = cval->mixer->chip; | 330 | struct snd_usb_audio *chip = cval->head.mixer->chip; |
327 | unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */ | 331 | unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */ |
328 | unsigned char *val; | 332 | unsigned char *val; |
329 | int idx = 0, ret, size; | 333 | int idx = 0, ret, size; |
@@ -347,7 +351,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, | |||
347 | if (chip->shutdown) { | 351 | if (chip->shutdown) { |
348 | ret = -ENODEV; | 352 | ret = -ENODEV; |
349 | } else { | 353 | } else { |
350 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | 354 | idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); |
351 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, | 355 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, |
352 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 356 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
353 | validx, idx, buf, size); | 357 | validx, idx, buf, size); |
@@ -392,7 +396,7 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, | |||
392 | { | 396 | { |
393 | validx += cval->idx_off; | 397 | validx += cval->idx_off; |
394 | 398 | ||
395 | return (cval->mixer->protocol == UAC_VERSION_1) ? | 399 | return (cval->head.mixer->protocol == UAC_VERSION_1) ? |
396 | get_ctl_value_v1(cval, request, validx, value_ret) : | 400 | get_ctl_value_v1(cval, request, validx, value_ret) : |
397 | get_ctl_value_v2(cval, request, validx, value_ret); | 401 | get_ctl_value_v2(cval, request, validx, value_ret); |
398 | } | 402 | } |
@@ -412,7 +416,7 @@ static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval, | |||
412 | value); | 416 | value); |
413 | } | 417 | } |
414 | 418 | ||
415 | static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | 419 | int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, |
416 | int channel, int index, int *value) | 420 | int channel, int index, int *value) |
417 | { | 421 | { |
418 | int err; | 422 | int err; |
@@ -423,8 +427,8 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | |||
423 | } | 427 | } |
424 | err = get_cur_mix_raw(cval, channel, value); | 428 | err = get_cur_mix_raw(cval, channel, value); |
425 | if (err < 0) { | 429 | if (err < 0) { |
426 | if (!cval->mixer->ignore_ctl_error) | 430 | if (!cval->head.mixer->ignore_ctl_error) |
427 | usb_audio_dbg(cval->mixer->chip, | 431 | usb_audio_dbg(cval->head.mixer->chip, |
428 | "cannot get current value for control %d ch %d: err = %d\n", | 432 | "cannot get current value for control %d ch %d: err = %d\n", |
429 | cval->control, channel, err); | 433 | cval->control, channel, err); |
430 | return err; | 434 | return err; |
@@ -441,13 +445,13 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | |||
441 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | 445 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, |
442 | int request, int validx, int value_set) | 446 | int request, int validx, int value_set) |
443 | { | 447 | { |
444 | struct snd_usb_audio *chip = cval->mixer->chip; | 448 | struct snd_usb_audio *chip = cval->head.mixer->chip; |
445 | unsigned char buf[2]; | 449 | unsigned char buf[2]; |
446 | int idx = 0, val_len, err, timeout = 10; | 450 | int idx = 0, val_len, err, timeout = 10; |
447 | 451 | ||
448 | validx += cval->idx_off; | 452 | validx += cval->idx_off; |
449 | 453 | ||
450 | if (cval->mixer->protocol == UAC_VERSION_1) { | 454 | if (cval->head.mixer->protocol == UAC_VERSION_1) { |
451 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 455 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
452 | } else { /* UAC_VERSION_2 */ | 456 | } else { /* UAC_VERSION_2 */ |
453 | /* audio class v2 controls are always 2 bytes in size */ | 457 | /* audio class v2 controls are always 2 bytes in size */ |
@@ -472,7 +476,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
472 | while (timeout-- > 0) { | 476 | while (timeout-- > 0) { |
473 | if (chip->shutdown) | 477 | if (chip->shutdown) |
474 | break; | 478 | break; |
475 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | 479 | idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); |
476 | if (snd_usb_ctl_msg(chip->dev, | 480 | if (snd_usb_ctl_msg(chip->dev, |
477 | usb_sndctrlpipe(chip->dev, 0), request, | 481 | usb_sndctrlpipe(chip->dev, 0), request, |
478 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | 482 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, |
@@ -497,7 +501,7 @@ static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, | |||
497 | return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value); | 501 | return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value); |
498 | } | 502 | } |
499 | 503 | ||
500 | static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, | 504 | int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, |
501 | int index, int value) | 505 | int index, int value) |
502 | { | 506 | { |
503 | int err; | 507 | int err; |
@@ -506,7 +510,7 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, | |||
506 | cval->ch_readonly & (1 << (channel - 1)); | 510 | cval->ch_readonly & (1 << (channel - 1)); |
507 | 511 | ||
508 | if (read_only) { | 512 | if (read_only) { |
509 | usb_audio_dbg(cval->mixer->chip, | 513 | usb_audio_dbg(cval->head.mixer->chip, |
510 | "%s(): channel %d of control %d is read_only\n", | 514 | "%s(): channel %d of control %d is read_only\n", |
511 | __func__, channel, cval->control); | 515 | __func__, channel, cval->control); |
512 | return 0; | 516 | return 0; |
@@ -565,10 +569,10 @@ static int check_matrix_bitmap(unsigned char *bmap, | |||
565 | * if failed, give up and free the control instance. | 569 | * if failed, give up and free the control instance. |
566 | */ | 570 | */ |
567 | 571 | ||
568 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | 572 | int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list, |
569 | struct snd_kcontrol *kctl) | 573 | struct snd_kcontrol *kctl) |
570 | { | 574 | { |
571 | struct usb_mixer_elem_info *cval = kctl->private_data; | 575 | struct usb_mixer_interface *mixer = list->mixer; |
572 | int err; | 576 | int err; |
573 | 577 | ||
574 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) | 578 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) |
@@ -578,9 +582,9 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | |||
578 | err); | 582 | err); |
579 | return err; | 583 | return err; |
580 | } | 584 | } |
581 | cval->elem_id = &kctl->id; | 585 | list->kctl = kctl; |
582 | cval->next_id_elem = mixer->id_elems[cval->id]; | 586 | list->next_id_elem = mixer->id_elems[list->id]; |
583 | mixer->id_elems[cval->id] = cval; | 587 | mixer->id_elems[list->id] = list; |
584 | return 0; | 588 | return 0; |
585 | } | 589 | } |
586 | 590 | ||
@@ -815,7 +819,7 @@ static struct usb_feature_control_info audio_feature_info[] = { | |||
815 | }; | 819 | }; |
816 | 820 | ||
817 | /* private_free callback */ | 821 | /* private_free callback */ |
818 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | 822 | void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl) |
819 | { | 823 | { |
820 | kfree(kctl->private_data); | 824 | kfree(kctl->private_data); |
821 | kctl->private_data = NULL; | 825 | kctl->private_data = NULL; |
@@ -829,7 +833,7 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |||
829 | static void volume_control_quirks(struct usb_mixer_elem_info *cval, | 833 | static void volume_control_quirks(struct usb_mixer_elem_info *cval, |
830 | struct snd_kcontrol *kctl) | 834 | struct snd_kcontrol *kctl) |
831 | { | 835 | { |
832 | struct snd_usb_audio *chip = cval->mixer->chip; | 836 | struct snd_usb_audio *chip = cval->head.mixer->chip; |
833 | switch (chip->usb_id) { | 837 | switch (chip->usb_id) { |
834 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ | 838 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ |
835 | case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ | 839 | case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ |
@@ -954,10 +958,10 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, | |||
954 | } | 958 | } |
955 | if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || | 959 | if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || |
956 | get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { | 960 | get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { |
957 | usb_audio_err(cval->mixer->chip, | 961 | usb_audio_err(cval->head.mixer->chip, |
958 | "%d:%d: cannot get min/max values for control %d (id %d)\n", | 962 | "%d:%d: cannot get min/max values for control %d (id %d)\n", |
959 | cval->id, snd_usb_ctrl_intf(cval->mixer->chip), | 963 | cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip), |
960 | cval->control, cval->id); | 964 | cval->control, cval->head.id); |
961 | return -EINVAL; | 965 | return -EINVAL; |
962 | } | 966 | } |
963 | if (get_ctl_value(cval, UAC_GET_RES, | 967 | if (get_ctl_value(cval, UAC_GET_RES, |
@@ -998,7 +1002,7 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, | |||
998 | else | 1002 | else |
999 | test -= cval->res; | 1003 | test -= cval->res; |
1000 | if (test < cval->min || test > cval->max || | 1004 | if (test < cval->min || test > cval->max || |
1001 | set_cur_mix_value(cval, minchn, 0, test) || | 1005 | snd_usb_set_cur_mix_value(cval, minchn, 0, test) || |
1002 | get_cur_mix_raw(cval, minchn, &check)) { | 1006 | get_cur_mix_raw(cval, minchn, &check)) { |
1003 | cval->res = last_valid_res; | 1007 | cval->res = last_valid_res; |
1004 | break; | 1008 | break; |
@@ -1007,7 +1011,7 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, | |||
1007 | break; | 1011 | break; |
1008 | cval->res *= 2; | 1012 | cval->res *= 2; |
1009 | } | 1013 | } |
1010 | set_cur_mix_value(cval, minchn, 0, saved); | 1014 | snd_usb_set_cur_mix_value(cval, minchn, 0, saved); |
1011 | } | 1015 | } |
1012 | 1016 | ||
1013 | cval->initialized = 1; | 1017 | cval->initialized = 1; |
@@ -1061,7 +1065,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, | |||
1061 | kcontrol->vd[0].access &= | 1065 | kcontrol->vd[0].access &= |
1062 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 1066 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
1063 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); | 1067 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); |
1064 | snd_ctl_notify(cval->mixer->chip->card, | 1068 | snd_ctl_notify(cval->head.mixer->chip->card, |
1065 | SNDRV_CTL_EVENT_MASK_INFO, | 1069 | SNDRV_CTL_EVENT_MASK_INFO, |
1066 | &kcontrol->id); | 1070 | &kcontrol->id); |
1067 | } | 1071 | } |
@@ -1086,9 +1090,9 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, | |||
1086 | for (c = 0; c < MAX_CHANNELS; c++) { | 1090 | for (c = 0; c < MAX_CHANNELS; c++) { |
1087 | if (!(cval->cmask & (1 << c))) | 1091 | if (!(cval->cmask & (1 << c))) |
1088 | continue; | 1092 | continue; |
1089 | err = get_cur_mix_value(cval, c + 1, cnt, &val); | 1093 | err = snd_usb_get_cur_mix_value(cval, c + 1, cnt, &val); |
1090 | if (err < 0) | 1094 | if (err < 0) |
1091 | return cval->mixer->ignore_ctl_error ? 0 : err; | 1095 | return filter_error(cval, err); |
1092 | val = get_relative_value(cval, val); | 1096 | val = get_relative_value(cval, val); |
1093 | ucontrol->value.integer.value[cnt] = val; | 1097 | ucontrol->value.integer.value[cnt] = val; |
1094 | cnt++; | 1098 | cnt++; |
@@ -1096,9 +1100,9 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, | |||
1096 | return 0; | 1100 | return 0; |
1097 | } else { | 1101 | } else { |
1098 | /* master channel */ | 1102 | /* master channel */ |
1099 | err = get_cur_mix_value(cval, 0, 0, &val); | 1103 | err = snd_usb_get_cur_mix_value(cval, 0, 0, &val); |
1100 | if (err < 0) | 1104 | if (err < 0) |
1101 | return cval->mixer->ignore_ctl_error ? 0 : err; | 1105 | return filter_error(cval, err); |
1102 | val = get_relative_value(cval, val); | 1106 | val = get_relative_value(cval, val); |
1103 | ucontrol->value.integer.value[0] = val; | 1107 | ucontrol->value.integer.value[0] = val; |
1104 | } | 1108 | } |
@@ -1118,26 +1122,26 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, | |||
1118 | for (c = 0; c < MAX_CHANNELS; c++) { | 1122 | for (c = 0; c < MAX_CHANNELS; c++) { |
1119 | if (!(cval->cmask & (1 << c))) | 1123 | if (!(cval->cmask & (1 << c))) |
1120 | continue; | 1124 | continue; |
1121 | err = get_cur_mix_value(cval, c + 1, cnt, &oval); | 1125 | err = snd_usb_get_cur_mix_value(cval, c + 1, cnt, &oval); |
1122 | if (err < 0) | 1126 | if (err < 0) |
1123 | return cval->mixer->ignore_ctl_error ? 0 : err; | 1127 | return filter_error(cval, err); |
1124 | val = ucontrol->value.integer.value[cnt]; | 1128 | val = ucontrol->value.integer.value[cnt]; |
1125 | val = get_abs_value(cval, val); | 1129 | val = get_abs_value(cval, val); |
1126 | if (oval != val) { | 1130 | if (oval != val) { |
1127 | set_cur_mix_value(cval, c + 1, cnt, val); | 1131 | snd_usb_set_cur_mix_value(cval, c + 1, cnt, val); |
1128 | changed = 1; | 1132 | changed = 1; |
1129 | } | 1133 | } |
1130 | cnt++; | 1134 | cnt++; |
1131 | } | 1135 | } |
1132 | } else { | 1136 | } else { |
1133 | /* master channel */ | 1137 | /* master channel */ |
1134 | err = get_cur_mix_value(cval, 0, 0, &oval); | 1138 | err = snd_usb_get_cur_mix_value(cval, 0, 0, &oval); |
1135 | if (err < 0) | 1139 | if (err < 0) |
1136 | return cval->mixer->ignore_ctl_error ? 0 : err; | 1140 | return filter_error(cval, err); |
1137 | val = ucontrol->value.integer.value[0]; | 1141 | val = ucontrol->value.integer.value[0]; |
1138 | val = get_abs_value(cval, val); | 1142 | val = get_abs_value(cval, val); |
1139 | if (val != oval) { | 1143 | if (val != oval) { |
1140 | set_cur_mix_value(cval, 0, 0, val); | 1144 | snd_usb_set_cur_mix_value(cval, 0, 0, val); |
1141 | changed = 1; | 1145 | changed = 1; |
1142 | } | 1146 | } |
1143 | } | 1147 | } |
@@ -1231,8 +1235,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1231 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1235 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1232 | if (!cval) | 1236 | if (!cval) |
1233 | return; | 1237 | return; |
1234 | cval->mixer = state->mixer; | 1238 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); |
1235 | cval->id = unitid; | ||
1236 | cval->control = control; | 1239 | cval->control = control; |
1237 | cval->cmask = ctl_mask; | 1240 | cval->cmask = ctl_mask; |
1238 | cval->val_type = audio_feature_info[control-1].type; | 1241 | cval->val_type = audio_feature_info[control-1].type; |
@@ -1250,7 +1253,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1250 | 1253 | ||
1251 | /* | 1254 | /* |
1252 | * If all channels in the mask are marked read-only, make the control | 1255 | * If all channels in the mask are marked read-only, make the control |
1253 | * read-only. set_cur_mix_value() will check the mask again and won't | 1256 | * read-only. snd_usb_set_cur_mix_value() will check the mask again and won't |
1254 | * issue write commands to read-only channels. | 1257 | * issue write commands to read-only channels. |
1255 | */ | 1258 | */ |
1256 | if (cval->channels == readonly_mask) | 1259 | if (cval->channels == readonly_mask) |
@@ -1263,7 +1266,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1263 | kfree(cval); | 1266 | kfree(cval); |
1264 | return; | 1267 | return; |
1265 | } | 1268 | } |
1266 | kctl->private_free = usb_mixer_elem_free; | 1269 | kctl->private_free = snd_usb_mixer_elem_free; |
1267 | 1270 | ||
1268 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); | 1271 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
1269 | mapped_name = len != 0; | 1272 | mapped_name = len != 0; |
@@ -1290,9 +1293,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1290 | kctl->id.name, | 1293 | kctl->id.name, |
1291 | sizeof(kctl->id.name), 1); | 1294 | sizeof(kctl->id.name), 1); |
1292 | if (!len) | 1295 | if (!len) |
1293 | len = snprintf(kctl->id.name, | 1296 | snprintf(kctl->id.name, sizeof(kctl->id.name), |
1294 | sizeof(kctl->id.name), | 1297 | "Feature %d", unitid); |
1295 | "Feature %d", unitid); | ||
1296 | } | 1298 | } |
1297 | 1299 | ||
1298 | if (!mapped_name) | 1300 | if (!mapped_name) |
@@ -1305,9 +1307,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1305 | */ | 1307 | */ |
1306 | if (!mapped_name && !(state->oterm.type >> 16)) { | 1308 | if (!mapped_name && !(state->oterm.type >> 16)) { |
1307 | if ((state->oterm.type & 0xff00) == 0x0100) | 1309 | if ((state->oterm.type & 0xff00) == 0x0100) |
1308 | len = append_ctl_name(kctl, " Capture"); | 1310 | append_ctl_name(kctl, " Capture"); |
1309 | else | 1311 | else |
1310 | len = append_ctl_name(kctl, " Playback"); | 1312 | append_ctl_name(kctl, " Playback"); |
1311 | } | 1313 | } |
1312 | append_ctl_name(kctl, control == UAC_FU_MUTE ? | 1314 | append_ctl_name(kctl, control == UAC_FU_MUTE ? |
1313 | " Switch" : " Volume"); | 1315 | " Switch" : " Volume"); |
@@ -1344,14 +1346,14 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1344 | range); | 1346 | range); |
1345 | usb_audio_warn(state->chip, | 1347 | usb_audio_warn(state->chip, |
1346 | "[%d] FU [%s] ch = %d, val = %d/%d/%d", | 1348 | "[%d] FU [%s] ch = %d, val = %d/%d/%d", |
1347 | cval->id, kctl->id.name, cval->channels, | 1349 | cval->head.id, kctl->id.name, cval->channels, |
1348 | cval->min, cval->max, cval->res); | 1350 | cval->min, cval->max, cval->res); |
1349 | } | 1351 | } |
1350 | 1352 | ||
1351 | usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", | 1353 | usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", |
1352 | cval->id, kctl->id.name, cval->channels, | 1354 | cval->head.id, kctl->id.name, cval->channels, |
1353 | cval->min, cval->max, cval->res); | 1355 | cval->min, cval->max, cval->res); |
1354 | snd_usb_mixer_add_control(state->mixer, kctl); | 1356 | snd_usb_mixer_add_control(&cval->head, kctl); |
1355 | } | 1357 | } |
1356 | 1358 | ||
1357 | /* | 1359 | /* |
@@ -1525,8 +1527,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1525 | if (!cval) | 1527 | if (!cval) |
1526 | return; | 1528 | return; |
1527 | 1529 | ||
1528 | cval->mixer = state->mixer; | 1530 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); |
1529 | cval->id = unitid; | ||
1530 | cval->control = in_ch + 1; /* based on 1 */ | 1531 | cval->control = in_ch + 1; /* based on 1 */ |
1531 | cval->val_type = USB_MIXER_S16; | 1532 | cval->val_type = USB_MIXER_S16; |
1532 | for (i = 0; i < num_outs; i++) { | 1533 | for (i = 0; i < num_outs; i++) { |
@@ -1547,7 +1548,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1547 | kfree(cval); | 1548 | kfree(cval); |
1548 | return; | 1549 | return; |
1549 | } | 1550 | } |
1550 | kctl->private_free = usb_mixer_elem_free; | 1551 | kctl->private_free = snd_usb_mixer_elem_free; |
1551 | 1552 | ||
1552 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); | 1553 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
1553 | if (!len) | 1554 | if (!len) |
@@ -1558,8 +1559,8 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1558 | append_ctl_name(kctl, " Volume"); | 1559 | append_ctl_name(kctl, " Volume"); |
1559 | 1560 | ||
1560 | usb_audio_dbg(state->chip, "[%d] MU [%s] ch = %d, val = %d/%d\n", | 1561 | usb_audio_dbg(state->chip, "[%d] MU [%s] ch = %d, val = %d/%d\n", |
1561 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); | 1562 | cval->head.id, kctl->id.name, cval->channels, cval->min, cval->max); |
1562 | snd_usb_mixer_add_control(state->mixer, kctl); | 1563 | snd_usb_mixer_add_control(&cval->head, kctl); |
1563 | } | 1564 | } |
1564 | 1565 | ||
1565 | /* | 1566 | /* |
@@ -1629,12 +1630,10 @@ static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, | |||
1629 | int err, val; | 1630 | int err, val; |
1630 | 1631 | ||
1631 | err = get_cur_ctl_value(cval, cval->control << 8, &val); | 1632 | err = get_cur_ctl_value(cval, cval->control << 8, &val); |
1632 | if (err < 0 && cval->mixer->ignore_ctl_error) { | 1633 | if (err < 0) { |
1633 | ucontrol->value.integer.value[0] = cval->min; | 1634 | ucontrol->value.integer.value[0] = cval->min; |
1634 | return 0; | 1635 | return filter_error(cval, err); |
1635 | } | 1636 | } |
1636 | if (err < 0) | ||
1637 | return err; | ||
1638 | val = get_relative_value(cval, val); | 1637 | val = get_relative_value(cval, val); |
1639 | ucontrol->value.integer.value[0] = val; | 1638 | ucontrol->value.integer.value[0] = val; |
1640 | return 0; | 1639 | return 0; |
@@ -1648,11 +1647,8 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, | |||
1648 | int val, oval, err; | 1647 | int val, oval, err; |
1649 | 1648 | ||
1650 | err = get_cur_ctl_value(cval, cval->control << 8, &oval); | 1649 | err = get_cur_ctl_value(cval, cval->control << 8, &oval); |
1651 | if (err < 0) { | 1650 | if (err < 0) |
1652 | if (cval->mixer->ignore_ctl_error) | 1651 | return filter_error(cval, err); |
1653 | return 0; | ||
1654 | return err; | ||
1655 | } | ||
1656 | val = ucontrol->value.integer.value[0]; | 1652 | val = ucontrol->value.integer.value[0]; |
1657 | val = get_abs_value(cval, val); | 1653 | val = get_abs_value(cval, val); |
1658 | if (val != oval) { | 1654 | if (val != oval) { |
@@ -1814,8 +1810,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, | |||
1814 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1810 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1815 | if (!cval) | 1811 | if (!cval) |
1816 | return -ENOMEM; | 1812 | return -ENOMEM; |
1817 | cval->mixer = state->mixer; | 1813 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); |
1818 | cval->id = unitid; | ||
1819 | cval->control = valinfo->control; | 1814 | cval->control = valinfo->control; |
1820 | cval->val_type = valinfo->val_type; | 1815 | cval->val_type = valinfo->val_type; |
1821 | cval->channels = 1; | 1816 | cval->channels = 1; |
@@ -1847,7 +1842,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, | |||
1847 | kfree(cval); | 1842 | kfree(cval); |
1848 | return -ENOMEM; | 1843 | return -ENOMEM; |
1849 | } | 1844 | } |
1850 | kctl->private_free = usb_mixer_elem_free; | 1845 | kctl->private_free = snd_usb_mixer_elem_free; |
1851 | 1846 | ||
1852 | if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name))) { | 1847 | if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name))) { |
1853 | /* nothing */ ; | 1848 | /* nothing */ ; |
@@ -1868,10 +1863,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, | |||
1868 | 1863 | ||
1869 | usb_audio_dbg(state->chip, | 1864 | usb_audio_dbg(state->chip, |
1870 | "[%d] PU [%s] ch = %d, val = %d/%d\n", | 1865 | "[%d] PU [%s] ch = %d, val = %d/%d\n", |
1871 | cval->id, kctl->id.name, cval->channels, | 1866 | cval->head.id, kctl->id.name, cval->channels, |
1872 | cval->min, cval->max); | 1867 | cval->min, cval->max); |
1873 | 1868 | ||
1874 | err = snd_usb_mixer_add_control(state->mixer, kctl); | 1869 | err = snd_usb_mixer_add_control(&cval->head, kctl); |
1875 | if (err < 0) | 1870 | if (err < 0) |
1876 | return err; | 1871 | return err; |
1877 | } | 1872 | } |
@@ -1924,11 +1919,8 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, | |||
1924 | 1919 | ||
1925 | err = get_cur_ctl_value(cval, cval->control << 8, &val); | 1920 | err = get_cur_ctl_value(cval, cval->control << 8, &val); |
1926 | if (err < 0) { | 1921 | if (err < 0) { |
1927 | if (cval->mixer->ignore_ctl_error) { | 1922 | ucontrol->value.enumerated.item[0] = 0; |
1928 | ucontrol->value.enumerated.item[0] = 0; | 1923 | return filter_error(cval, err); |
1929 | return 0; | ||
1930 | } | ||
1931 | return err; | ||
1932 | } | 1924 | } |
1933 | val = get_relative_value(cval, val); | 1925 | val = get_relative_value(cval, val); |
1934 | ucontrol->value.enumerated.item[0] = val; | 1926 | ucontrol->value.enumerated.item[0] = val; |
@@ -1943,11 +1935,8 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, | |||
1943 | int val, oval, err; | 1935 | int val, oval, err; |
1944 | 1936 | ||
1945 | err = get_cur_ctl_value(cval, cval->control << 8, &oval); | 1937 | err = get_cur_ctl_value(cval, cval->control << 8, &oval); |
1946 | if (err < 0) { | 1938 | if (err < 0) |
1947 | if (cval->mixer->ignore_ctl_error) | 1939 | return filter_error(cval, err); |
1948 | return 0; | ||
1949 | return err; | ||
1950 | } | ||
1951 | val = ucontrol->value.enumerated.item[0]; | 1940 | val = ucontrol->value.enumerated.item[0]; |
1952 | val = get_abs_value(cval, val); | 1941 | val = get_abs_value(cval, val); |
1953 | if (val != oval) { | 1942 | if (val != oval) { |
@@ -2024,8 +2013,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2024 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 2013 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
2025 | if (!cval) | 2014 | if (!cval) |
2026 | return -ENOMEM; | 2015 | return -ENOMEM; |
2027 | cval->mixer = state->mixer; | 2016 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); |
2028 | cval->id = unitid; | ||
2029 | cval->val_type = USB_MIXER_U8; | 2017 | cval->val_type = USB_MIXER_U8; |
2030 | cval->channels = 1; | 2018 | cval->channels = 1; |
2031 | cval->min = 1; | 2019 | cval->min = 1; |
@@ -2096,11 +2084,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2096 | } | 2084 | } |
2097 | 2085 | ||
2098 | usb_audio_dbg(state->chip, "[%d] SU [%s] items = %d\n", | 2086 | usb_audio_dbg(state->chip, "[%d] SU [%s] items = %d\n", |
2099 | cval->id, kctl->id.name, desc->bNrInPins); | 2087 | cval->head.id, kctl->id.name, desc->bNrInPins); |
2100 | if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) | 2088 | return snd_usb_mixer_add_control(&cval->head, kctl); |
2101 | return err; | ||
2102 | |||
2103 | return 0; | ||
2104 | } | 2089 | } |
2105 | 2090 | ||
2106 | /* | 2091 | /* |
@@ -2245,25 +2230,21 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2245 | 2230 | ||
2246 | void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) | 2231 | void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) |
2247 | { | 2232 | { |
2248 | struct usb_mixer_elem_info *info; | 2233 | struct usb_mixer_elem_list *list; |
2249 | 2234 | ||
2250 | for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) | 2235 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) |
2251 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | 2236 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, |
2252 | info->elem_id); | 2237 | &list->kctl->id); |
2253 | } | 2238 | } |
2254 | 2239 | ||
2255 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, | 2240 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, |
2256 | int unitid, | 2241 | struct usb_mixer_elem_list *list) |
2257 | struct usb_mixer_elem_info *cval) | ||
2258 | { | 2242 | { |
2243 | struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; | ||
2259 | static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", | 2244 | static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", |
2260 | "S8", "U8", "S16", "U16"}; | 2245 | "S8", "U8", "S16", "U16"}; |
2261 | snd_iprintf(buffer, " Unit: %i\n", unitid); | ||
2262 | if (cval->elem_id) | ||
2263 | snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n", | ||
2264 | cval->elem_id->name, cval->elem_id->index); | ||
2265 | snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " | 2246 | snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " |
2266 | "channels=%i, type=\"%s\"\n", cval->id, | 2247 | "channels=%i, type=\"%s\"\n", cval->head.id, |
2267 | cval->control, cval->cmask, cval->channels, | 2248 | cval->control, cval->cmask, cval->channels, |
2268 | val_types[cval->val_type]); | 2249 | val_types[cval->val_type]); |
2269 | snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n", | 2250 | snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n", |
@@ -2275,7 +2256,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, | |||
2275 | { | 2256 | { |
2276 | struct snd_usb_audio *chip = entry->private_data; | 2257 | struct snd_usb_audio *chip = entry->private_data; |
2277 | struct usb_mixer_interface *mixer; | 2258 | struct usb_mixer_interface *mixer; |
2278 | struct usb_mixer_elem_info *cval; | 2259 | struct usb_mixer_elem_list *list; |
2279 | int unitid; | 2260 | int unitid; |
2280 | 2261 | ||
2281 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 2262 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
@@ -2285,9 +2266,17 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, | |||
2285 | mixer->ignore_ctl_error); | 2266 | mixer->ignore_ctl_error); |
2286 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); | 2267 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); |
2287 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { | 2268 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { |
2288 | for (cval = mixer->id_elems[unitid]; cval; | 2269 | for (list = mixer->id_elems[unitid]; list; |
2289 | cval = cval->next_id_elem) | 2270 | list = list->next_id_elem) { |
2290 | snd_usb_mixer_dump_cval(buffer, unitid, cval); | 2271 | snd_iprintf(buffer, " Unit: %i\n", list->id); |
2272 | if (list->kctl) | ||
2273 | snd_iprintf(buffer, | ||
2274 | " Control: name=\"%s\", index=%i\n", | ||
2275 | list->kctl->id.name, | ||
2276 | list->kctl->id.index); | ||
2277 | if (list->dump) | ||
2278 | list->dump(buffer, list); | ||
2279 | } | ||
2291 | } | 2280 | } |
2292 | } | 2281 | } |
2293 | } | 2282 | } |
@@ -2295,7 +2284,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, | |||
2295 | static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, | 2284 | static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, |
2296 | int attribute, int value, int index) | 2285 | int attribute, int value, int index) |
2297 | { | 2286 | { |
2298 | struct usb_mixer_elem_info *info; | 2287 | struct usb_mixer_elem_list *list; |
2299 | __u8 unitid = (index >> 8) & 0xff; | 2288 | __u8 unitid = (index >> 8) & 0xff; |
2300 | __u8 control = (value >> 8) & 0xff; | 2289 | __u8 control = (value >> 8) & 0xff; |
2301 | __u8 channel = value & 0xff; | 2290 | __u8 channel = value & 0xff; |
@@ -2307,7 +2296,13 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, | |||
2307 | return; | 2296 | return; |
2308 | } | 2297 | } |
2309 | 2298 | ||
2310 | for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) { | 2299 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { |
2300 | struct usb_mixer_elem_info *info; | ||
2301 | |||
2302 | if (!list->kctl) | ||
2303 | continue; | ||
2304 | |||
2305 | info = (struct usb_mixer_elem_info *)list; | ||
2311 | if (info->control != control) | 2306 | if (info->control != control) |
2312 | continue; | 2307 | continue; |
2313 | 2308 | ||
@@ -2320,7 +2315,7 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, | |||
2320 | info->cached = 0; | 2315 | info->cached = 0; |
2321 | 2316 | ||
2322 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | 2317 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, |
2323 | info->elem_id); | 2318 | &info->head.kctl->id); |
2324 | break; | 2319 | break; |
2325 | 2320 | ||
2326 | case UAC2_CS_RANGE: | 2321 | case UAC2_CS_RANGE: |
@@ -2485,11 +2480,8 @@ _error: | |||
2485 | return err; | 2480 | return err; |
2486 | } | 2481 | } |
2487 | 2482 | ||
2488 | void snd_usb_mixer_disconnect(struct list_head *p) | 2483 | void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) |
2489 | { | 2484 | { |
2490 | struct usb_mixer_interface *mixer; | ||
2491 | |||
2492 | mixer = list_entry(p, struct usb_mixer_interface, list); | ||
2493 | usb_kill_urb(mixer->urb); | 2485 | usb_kill_urb(mixer->urb); |
2494 | usb_kill_urb(mixer->rc_urb); | 2486 | usb_kill_urb(mixer->rc_urb); |
2495 | } | 2487 | } |
@@ -2521,8 +2513,9 @@ int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer) | |||
2521 | return 0; | 2513 | return 0; |
2522 | } | 2514 | } |
2523 | 2515 | ||
2524 | static int restore_mixer_value(struct usb_mixer_elem_info *cval) | 2516 | static int restore_mixer_value(struct usb_mixer_elem_list *list) |
2525 | { | 2517 | { |
2518 | struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; | ||
2526 | int c, err, idx; | 2519 | int c, err, idx; |
2527 | 2520 | ||
2528 | if (cval->cmask) { | 2521 | if (cval->cmask) { |
@@ -2531,7 +2524,7 @@ static int restore_mixer_value(struct usb_mixer_elem_info *cval) | |||
2531 | if (!(cval->cmask & (1 << c))) | 2524 | if (!(cval->cmask & (1 << c))) |
2532 | continue; | 2525 | continue; |
2533 | if (cval->cached & (1 << c)) { | 2526 | if (cval->cached & (1 << c)) { |
2534 | err = set_cur_mix_value(cval, c + 1, idx, | 2527 | err = snd_usb_set_cur_mix_value(cval, c + 1, idx, |
2535 | cval->cache_val[idx]); | 2528 | cval->cache_val[idx]); |
2536 | if (err < 0) | 2529 | if (err < 0) |
2537 | return err; | 2530 | return err; |
@@ -2541,7 +2534,7 @@ static int restore_mixer_value(struct usb_mixer_elem_info *cval) | |||
2541 | } else { | 2534 | } else { |
2542 | /* master */ | 2535 | /* master */ |
2543 | if (cval->cached) { | 2536 | if (cval->cached) { |
2544 | err = set_cur_mix_value(cval, 0, 0, *cval->cache_val); | 2537 | err = snd_usb_set_cur_mix_value(cval, 0, 0, *cval->cache_val); |
2545 | if (err < 0) | 2538 | if (err < 0) |
2546 | return err; | 2539 | return err; |
2547 | } | 2540 | } |
@@ -2552,19 +2545,19 @@ static int restore_mixer_value(struct usb_mixer_elem_info *cval) | |||
2552 | 2545 | ||
2553 | int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) | 2546 | int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) |
2554 | { | 2547 | { |
2555 | struct usb_mixer_elem_info *cval; | 2548 | struct usb_mixer_elem_list *list; |
2556 | int id, err; | 2549 | int id, err; |
2557 | 2550 | ||
2558 | /* FIXME: any mixer quirks? */ | ||
2559 | |||
2560 | if (reset_resume) { | 2551 | if (reset_resume) { |
2561 | /* restore cached mixer values */ | 2552 | /* restore cached mixer values */ |
2562 | for (id = 0; id < MAX_ID_ELEMS; id++) { | 2553 | for (id = 0; id < MAX_ID_ELEMS; id++) { |
2563 | for (cval = mixer->id_elems[id]; cval; | 2554 | for (list = mixer->id_elems[id]; list; |
2564 | cval = cval->next_id_elem) { | 2555 | list = list->next_id_elem) { |
2565 | err = restore_mixer_value(cval); | 2556 | if (list->resume) { |
2566 | if (err < 0) | 2557 | err = list->resume(list); |
2567 | return err; | 2558 | if (err < 0) |
2559 | return err; | ||
2560 | } | ||
2568 | } | 2561 | } |
2569 | } | 2562 | } |
2570 | } | 2563 | } |
@@ -2572,3 +2565,15 @@ int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) | |||
2572 | return snd_usb_mixer_activate(mixer); | 2565 | return snd_usb_mixer_activate(mixer); |
2573 | } | 2566 | } |
2574 | #endif | 2567 | #endif |
2568 | |||
2569 | void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, | ||
2570 | struct usb_mixer_interface *mixer, | ||
2571 | int unitid) | ||
2572 | { | ||
2573 | list->mixer = mixer; | ||
2574 | list->id = unitid; | ||
2575 | list->dump = snd_usb_mixer_dump_cval; | ||
2576 | #ifdef CONFIG_PM | ||
2577 | list->resume = restore_mixer_value; | ||
2578 | #endif | ||
2579 | } | ||
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 73b1f649447b..d3268f0ee2b3 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef __USBMIXER_H | 1 | #ifndef __USBMIXER_H |
2 | #define __USBMIXER_H | 2 | #define __USBMIXER_H |
3 | 3 | ||
4 | #include <sound/info.h> | ||
5 | |||
4 | struct usb_mixer_interface { | 6 | struct usb_mixer_interface { |
5 | struct snd_usb_audio *chip; | 7 | struct snd_usb_audio *chip; |
6 | struct usb_host_interface *hostif; | 8 | struct usb_host_interface *hostif; |
@@ -8,7 +10,7 @@ struct usb_mixer_interface { | |||
8 | unsigned int ignore_ctl_error; | 10 | unsigned int ignore_ctl_error; |
9 | struct urb *urb; | 11 | struct urb *urb; |
10 | /* array[MAX_ID_ELEMS], indexed by unit id */ | 12 | /* array[MAX_ID_ELEMS], indexed by unit id */ |
11 | struct usb_mixer_elem_info **id_elems; | 13 | struct usb_mixer_elem_list **id_elems; |
12 | 14 | ||
13 | /* the usb audio specification version this interface complies to */ | 15 | /* the usb audio specification version this interface complies to */ |
14 | int protocol; | 16 | int protocol; |
@@ -20,9 +22,6 @@ struct usb_mixer_interface { | |||
20 | struct urb *rc_urb; | 22 | struct urb *rc_urb; |
21 | struct usb_ctrlrequest *rc_setup_packet; | 23 | struct usb_ctrlrequest *rc_setup_packet; |
22 | u8 rc_buffer[6]; | 24 | u8 rc_buffer[6]; |
23 | |||
24 | u8 audigy2nx_leds[3]; | ||
25 | u8 xonar_u1_status; | ||
26 | }; | 25 | }; |
27 | 26 | ||
28 | #define MAX_CHANNELS 16 /* max logical channels */ | 27 | #define MAX_CHANNELS 16 /* max logical channels */ |
@@ -36,11 +35,21 @@ enum { | |||
36 | USB_MIXER_U16, | 35 | USB_MIXER_U16, |
37 | }; | 36 | }; |
38 | 37 | ||
39 | struct usb_mixer_elem_info { | 38 | typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, |
39 | struct usb_mixer_elem_list *list); | ||
40 | typedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); | ||
41 | |||
42 | struct usb_mixer_elem_list { | ||
40 | struct usb_mixer_interface *mixer; | 43 | struct usb_mixer_interface *mixer; |
41 | struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */ | 44 | struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ |
42 | struct snd_ctl_elem_id *elem_id; | 45 | struct snd_kcontrol *kctl; |
43 | unsigned int id; | 46 | unsigned int id; |
47 | usb_mixer_elem_dump_func_t dump; | ||
48 | usb_mixer_elem_resume_func_t resume; | ||
49 | }; | ||
50 | |||
51 | struct usb_mixer_elem_info { | ||
52 | struct usb_mixer_elem_list head; | ||
44 | unsigned int control; /* CS or ICN (high byte) */ | 53 | unsigned int control; /* CS or ICN (high byte) */ |
45 | unsigned int cmask; /* channel mask bitmap: 0 = master */ | 54 | unsigned int cmask; /* channel mask bitmap: 0 = master */ |
46 | unsigned int idx_off; /* Control index offset */ | 55 | unsigned int idx_off; /* Control index offset */ |
@@ -53,20 +62,25 @@ struct usb_mixer_elem_info { | |||
53 | int cached; | 62 | int cached; |
54 | int cache_val[MAX_CHANNELS]; | 63 | int cache_val[MAX_CHANNELS]; |
55 | u8 initialized; | 64 | u8 initialized; |
65 | void *private_data; | ||
56 | }; | 66 | }; |
57 | 67 | ||
58 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | 68 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
59 | int ignore_error); | 69 | int ignore_error); |
60 | void snd_usb_mixer_disconnect(struct list_head *p); | 70 | void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); |
61 | 71 | ||
62 | void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); | 72 | void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); |
63 | 73 | ||
64 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | 74 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, |
65 | int request, int validx, int value_set); | 75 | int request, int validx, int value_set); |
66 | 76 | ||
67 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | 77 | int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list, |
68 | struct snd_kcontrol *kctl); | 78 | struct snd_kcontrol *kctl); |
69 | 79 | ||
80 | void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, | ||
81 | struct usb_mixer_interface *mixer, | ||
82 | int unitid); | ||
83 | |||
70 | int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | 84 | int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, |
71 | unsigned int size, unsigned int __user *_tlv); | 85 | unsigned int size, unsigned int __user *_tlv); |
72 | 86 | ||
@@ -75,4 +89,12 @@ int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); | |||
75 | int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume); | 89 | int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume); |
76 | #endif | 90 | #endif |
77 | 91 | ||
92 | int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, | ||
93 | int index, int value); | ||
94 | |||
95 | int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, | ||
96 | int channel, int index, int *value); | ||
97 | |||
98 | extern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl); | ||
99 | |||
78 | #endif /* __USBMIXER_H */ | 100 | #endif /* __USBMIXER_H */ |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index d1d72ff50347..1994d41348f8 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -179,6 +179,11 @@ static struct usbmix_name_map audigy2nx_map[] = { | |||
179 | { 0 } /* terminator */ | 179 | { 0 } /* terminator */ |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static struct usbmix_name_map mbox1_map[] = { | ||
183 | { 1, "Clock" }, | ||
184 | { 0 } /* terminator */ | ||
185 | }; | ||
186 | |||
182 | static struct usbmix_selector_map c400_selectors[] = { | 187 | static struct usbmix_selector_map c400_selectors[] = { |
183 | { | 188 | { |
184 | .id = 0x80, | 189 | .id = 0x80, |
@@ -416,6 +421,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
416 | .map = aureon_51_2_map, | 421 | .map = aureon_51_2_map, |
417 | }, | 422 | }, |
418 | { | 423 | { |
424 | .id = USB_ID(0x0dba, 0x1000), | ||
425 | .map = mbox1_map, | ||
426 | }, | ||
427 | { | ||
419 | .id = USB_ID(0x13e5, 0x0001), | 428 | .id = USB_ID(0x13e5, 0x0001), |
420 | .map = scratch_live_map, | 429 | .map = scratch_live_map, |
421 | .ignore_ctl_error = 1, | 430 | .ignore_ctl_error = 1, |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 8c9bf4b7aaf0..dc9df007d3e3 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "usbaudio.h" | 41 | #include "usbaudio.h" |
42 | #include "mixer.h" | 42 | #include "mixer.h" |
43 | #include "mixer_quirks.h" | 43 | #include "mixer_quirks.h" |
44 | #include "mixer_scarlett.h" | ||
44 | #include "helper.h" | 45 | #include "helper.h" |
45 | 46 | ||
46 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; | 47 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; |
@@ -52,13 +53,6 @@ struct std_mono_table { | |||
52 | snd_kcontrol_tlv_rw_t *tlv_callback; | 53 | snd_kcontrol_tlv_rw_t *tlv_callback; |
53 | }; | 54 | }; |
54 | 55 | ||
55 | /* private_free callback */ | ||
56 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | ||
57 | { | ||
58 | kfree(kctl->private_data); | ||
59 | kctl->private_data = NULL; | ||
60 | } | ||
61 | |||
62 | /* This function allows for the creation of standard UAC controls. | 56 | /* This function allows for the creation of standard UAC controls. |
63 | * See the quirks for M-Audio FTUs or Ebox-44. | 57 | * See the quirks for M-Audio FTUs or Ebox-44. |
64 | * If you don't want to set a TLV callback pass NULL. | 58 | * If you don't want to set a TLV callback pass NULL. |
@@ -75,7 +69,6 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, | |||
75 | const char *name, | 69 | const char *name, |
76 | snd_kcontrol_tlv_rw_t *tlv_callback) | 70 | snd_kcontrol_tlv_rw_t *tlv_callback) |
77 | { | 71 | { |
78 | int err; | ||
79 | struct usb_mixer_elem_info *cval; | 72 | struct usb_mixer_elem_info *cval; |
80 | struct snd_kcontrol *kctl; | 73 | struct snd_kcontrol *kctl; |
81 | 74 | ||
@@ -83,8 +76,7 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, | |||
83 | if (!cval) | 76 | if (!cval) |
84 | return -ENOMEM; | 77 | return -ENOMEM; |
85 | 78 | ||
86 | cval->id = unitid; | 79 | snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); |
87 | cval->mixer = mixer; | ||
88 | cval->val_type = val_type; | 80 | cval->val_type = val_type; |
89 | cval->channels = 1; | 81 | cval->channels = 1; |
90 | cval->control = control; | 82 | cval->control = control; |
@@ -108,7 +100,7 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, | |||
108 | 100 | ||
109 | /* Set name */ | 101 | /* Set name */ |
110 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); | 102 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); |
111 | kctl->private_free = usb_mixer_elem_free; | 103 | kctl->private_free = snd_usb_mixer_elem_free; |
112 | 104 | ||
113 | /* set TLV */ | 105 | /* set TLV */ |
114 | if (tlv_callback) { | 106 | if (tlv_callback) { |
@@ -118,11 +110,7 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, | |||
118 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | 110 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; |
119 | } | 111 | } |
120 | /* Add control to mixer */ | 112 | /* Add control to mixer */ |
121 | err = snd_usb_mixer_add_control(mixer, kctl); | 113 | return snd_usb_mixer_add_control(&cval->head, kctl); |
122 | if (err < 0) | ||
123 | return err; | ||
124 | |||
125 | return 0; | ||
126 | } | 114 | } |
127 | 115 | ||
128 | static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, | 116 | static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, |
@@ -156,6 +144,32 @@ static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, | |||
156 | return 0; | 144 | return 0; |
157 | } | 145 | } |
158 | 146 | ||
147 | static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer, | ||
148 | int id, | ||
149 | usb_mixer_elem_resume_func_t resume, | ||
150 | const struct snd_kcontrol_new *knew, | ||
151 | struct usb_mixer_elem_list **listp) | ||
152 | { | ||
153 | struct usb_mixer_elem_list *list; | ||
154 | struct snd_kcontrol *kctl; | ||
155 | |||
156 | list = kzalloc(sizeof(*list), GFP_KERNEL); | ||
157 | if (!list) | ||
158 | return -ENOMEM; | ||
159 | if (listp) | ||
160 | *listp = list; | ||
161 | list->mixer = mixer; | ||
162 | list->id = id; | ||
163 | list->resume = resume; | ||
164 | kctl = snd_ctl_new1(knew, list); | ||
165 | if (!kctl) { | ||
166 | kfree(list); | ||
167 | return -ENOMEM; | ||
168 | } | ||
169 | kctl->private_free = snd_usb_mixer_elem_free; | ||
170 | return snd_usb_mixer_add_control(list, kctl); | ||
171 | } | ||
172 | |||
159 | /* | 173 | /* |
160 | * Sound Blaster remote control configuration | 174 | * Sound Blaster remote control configuration |
161 | * | 175 | * |
@@ -283,84 +297,90 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) | |||
283 | 297 | ||
284 | static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 298 | static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
285 | { | 299 | { |
286 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 300 | ucontrol->value.integer.value[0] = kcontrol->private_value >> 8; |
287 | int index = kcontrol->private_value; | ||
288 | |||
289 | ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index]; | ||
290 | return 0; | 301 | return 0; |
291 | } | 302 | } |
292 | 303 | ||
293 | static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 304 | static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer, |
305 | int value, int index) | ||
294 | { | 306 | { |
295 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 307 | struct snd_usb_audio *chip = mixer->chip; |
296 | int index = kcontrol->private_value; | 308 | int err; |
297 | int value = ucontrol->value.integer.value[0]; | ||
298 | int err, changed; | ||
299 | 309 | ||
300 | if (value > 1) | 310 | down_read(&chip->shutdown_rwsem); |
301 | return -EINVAL; | 311 | if (chip->shutdown) { |
302 | changed = value != mixer->audigy2nx_leds[index]; | ||
303 | down_read(&mixer->chip->shutdown_rwsem); | ||
304 | if (mixer->chip->shutdown) { | ||
305 | err = -ENODEV; | 312 | err = -ENODEV; |
306 | goto out; | 313 | goto out; |
307 | } | 314 | } |
308 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) | 315 | if (chip->usb_id == USB_ID(0x041e, 0x3042)) |
309 | err = snd_usb_ctl_msg(mixer->chip->dev, | 316 | err = snd_usb_ctl_msg(chip->dev, |
310 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 317 | usb_sndctrlpipe(chip->dev, 0), 0x24, |
311 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 318 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
312 | !value, 0, NULL, 0); | 319 | !value, 0, NULL, 0); |
313 | /* USB X-Fi S51 Pro */ | 320 | /* USB X-Fi S51 Pro */ |
314 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) | 321 | if (chip->usb_id == USB_ID(0x041e, 0x30df)) |
315 | err = snd_usb_ctl_msg(mixer->chip->dev, | 322 | err = snd_usb_ctl_msg(chip->dev, |
316 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 323 | usb_sndctrlpipe(chip->dev, 0), 0x24, |
317 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 324 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
318 | !value, 0, NULL, 0); | 325 | !value, 0, NULL, 0); |
319 | else | 326 | else |
320 | err = snd_usb_ctl_msg(mixer->chip->dev, | 327 | err = snd_usb_ctl_msg(chip->dev, |
321 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 328 | usb_sndctrlpipe(chip->dev, 0), 0x24, |
322 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 329 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
323 | value, index + 2, NULL, 0); | 330 | value, index + 2, NULL, 0); |
324 | out: | 331 | out: |
325 | up_read(&mixer->chip->shutdown_rwsem); | 332 | up_read(&chip->shutdown_rwsem); |
326 | if (err < 0) | 333 | return err; |
327 | return err; | ||
328 | mixer->audigy2nx_leds[index] = value; | ||
329 | return changed; | ||
330 | } | 334 | } |
331 | 335 | ||
332 | static struct snd_kcontrol_new snd_audigy2nx_controls[] = { | 336 | static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, |
333 | { | 337 | struct snd_ctl_elem_value *ucontrol) |
334 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 338 | { |
335 | .name = "CMSS LED Switch", | 339 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); |
336 | .info = snd_audigy2nx_led_info, | 340 | struct usb_mixer_interface *mixer = list->mixer; |
337 | .get = snd_audigy2nx_led_get, | 341 | int index = kcontrol->private_value & 0xff; |
338 | .put = snd_audigy2nx_led_put, | 342 | int value = ucontrol->value.integer.value[0]; |
339 | .private_value = 0, | 343 | int old_value = kcontrol->private_value >> 8; |
340 | }, | 344 | int err; |
341 | { | 345 | |
342 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 346 | if (value > 1) |
343 | .name = "Power LED Switch", | 347 | return -EINVAL; |
344 | .info = snd_audigy2nx_led_info, | 348 | if (value == old_value) |
345 | .get = snd_audigy2nx_led_get, | 349 | return 0; |
346 | .put = snd_audigy2nx_led_put, | 350 | kcontrol->private_value = (value << 8) | index; |
347 | .private_value = 1, | 351 | err = snd_audigy2nx_led_update(mixer, value, index); |
348 | }, | 352 | return err < 0 ? err : 1; |
349 | { | 353 | } |
350 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 354 | |
351 | .name = "Dolby Digital LED Switch", | 355 | static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list) |
352 | .info = snd_audigy2nx_led_info, | 356 | { |
353 | .get = snd_audigy2nx_led_get, | 357 | int priv_value = list->kctl->private_value; |
354 | .put = snd_audigy2nx_led_put, | 358 | |
355 | .private_value = 2, | 359 | return snd_audigy2nx_led_update(list->mixer, priv_value >> 8, |
356 | }, | 360 | priv_value & 0xff); |
361 | } | ||
362 | |||
363 | /* name and private_value are set dynamically */ | ||
364 | static struct snd_kcontrol_new snd_audigy2nx_control = { | ||
365 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
366 | .info = snd_audigy2nx_led_info, | ||
367 | .get = snd_audigy2nx_led_get, | ||
368 | .put = snd_audigy2nx_led_put, | ||
369 | }; | ||
370 | |||
371 | static const char * const snd_audigy2nx_led_names[] = { | ||
372 | "CMSS LED Switch", | ||
373 | "Power LED Switch", | ||
374 | "Dolby Digital LED Switch", | ||
357 | }; | 375 | }; |
358 | 376 | ||
359 | static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) | 377 | static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) |
360 | { | 378 | { |
361 | int i, err; | 379 | int i, err; |
362 | 380 | ||
363 | for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { | 381 | for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_led_names); ++i) { |
382 | struct snd_kcontrol_new knew; | ||
383 | |||
364 | /* USB X-Fi S51 doesn't have a CMSS LED */ | 384 | /* USB X-Fi S51 doesn't have a CMSS LED */ |
365 | if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) | 385 | if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) |
366 | continue; | 386 | continue; |
@@ -373,12 +393,16 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) | |||
373 | mixer->chip->usb_id == USB_ID(0x041e, 0x30df) || | 393 | mixer->chip->usb_id == USB_ID(0x041e, 0x30df) || |
374 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) | 394 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) |
375 | break; | 395 | break; |
376 | err = snd_ctl_add(mixer->chip->card, | 396 | |
377 | snd_ctl_new1(&snd_audigy2nx_controls[i], mixer)); | 397 | knew = snd_audigy2nx_control; |
398 | knew.name = snd_audigy2nx_led_names[i]; | ||
399 | knew.private_value = (1 << 8) | i; /* LED on as default */ | ||
400 | err = add_single_ctl_with_resume(mixer, 0, | ||
401 | snd_audigy2nx_led_resume, | ||
402 | &knew, NULL); | ||
378 | if (err < 0) | 403 | if (err < 0) |
379 | return err; | 404 | return err; |
380 | } | 405 | } |
381 | mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */ | ||
382 | return 0; | 406 | return 0; |
383 | } | 407 | } |
384 | 408 | ||
@@ -437,19 +461,9 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, | |||
437 | static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol, | 461 | static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol, |
438 | struct snd_ctl_elem_info *uinfo) | 462 | struct snd_ctl_elem_info *uinfo) |
439 | { | 463 | { |
440 | static const char *texts[2] = {"1/2", | 464 | static const char * const texts[2] = {"1/2", "3/4"}; |
441 | "3/4" | ||
442 | }; | ||
443 | 465 | ||
444 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 466 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); |
445 | uinfo->count = 1; | ||
446 | uinfo->value.enumerated.items = 2; | ||
447 | if (uinfo->value.enumerated.item > 1) | ||
448 | uinfo->value.enumerated.item = 1; | ||
449 | strcpy(uinfo->value.enumerated.name, | ||
450 | texts[uinfo->value.enumerated.item]); | ||
451 | |||
452 | return 0; | ||
453 | } | 467 | } |
454 | 468 | ||
455 | static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, | 469 | static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, |
@@ -459,100 +473,122 @@ static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, | |||
459 | return 0; | 473 | return 0; |
460 | } | 474 | } |
461 | 475 | ||
462 | static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, | 476 | static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer, |
463 | struct snd_ctl_elem_value *ucontrol) | 477 | int value) |
464 | { | 478 | { |
465 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 479 | struct snd_usb_audio *chip = mixer->chip; |
466 | unsigned int value = ucontrol->value.enumerated.item[0]; | 480 | int err; |
467 | int err, changed; | ||
468 | unsigned char buf[2]; | 481 | unsigned char buf[2]; |
469 | 482 | ||
470 | if (value > 1) | 483 | down_read(&chip->shutdown_rwsem); |
471 | return -EINVAL; | ||
472 | |||
473 | buf[0] = 0x01; | ||
474 | buf[1] = value ? 0x02 : 0x01; | ||
475 | |||
476 | changed = value != kcontrol->private_value; | ||
477 | down_read(&mixer->chip->shutdown_rwsem); | ||
478 | if (mixer->chip->shutdown) { | 484 | if (mixer->chip->shutdown) { |
479 | err = -ENODEV; | 485 | err = -ENODEV; |
480 | goto out; | 486 | goto out; |
481 | } | 487 | } |
482 | err = snd_usb_ctl_msg(mixer->chip->dev, | 488 | |
483 | usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, | 489 | buf[0] = 0x01; |
490 | buf[1] = value ? 0x02 : 0x01; | ||
491 | err = snd_usb_ctl_msg(chip->dev, | ||
492 | usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, | ||
484 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | 493 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, |
485 | 0x0400, 0x0e00, buf, 2); | 494 | 0x0400, 0x0e00, buf, 2); |
486 | out: | 495 | out: |
487 | up_read(&mixer->chip->shutdown_rwsem); | 496 | up_read(&chip->shutdown_rwsem); |
488 | if (err < 0) | 497 | return err; |
489 | return err; | 498 | } |
499 | |||
500 | static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, | ||
501 | struct snd_ctl_elem_value *ucontrol) | ||
502 | { | ||
503 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); | ||
504 | struct usb_mixer_interface *mixer = list->mixer; | ||
505 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
506 | int err; | ||
507 | |||
508 | if (value > 1) | ||
509 | return -EINVAL; | ||
510 | |||
511 | if (value == kcontrol->private_value) | ||
512 | return 0; | ||
513 | |||
490 | kcontrol->private_value = value; | 514 | kcontrol->private_value = value; |
491 | return changed; | 515 | err = snd_emu0204_ch_switch_update(mixer, value); |
516 | return err < 0 ? err : 1; | ||
492 | } | 517 | } |
493 | 518 | ||
519 | static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list) | ||
520 | { | ||
521 | return snd_emu0204_ch_switch_update(list->mixer, | ||
522 | list->kctl->private_value); | ||
523 | } | ||
494 | 524 | ||
495 | static struct snd_kcontrol_new snd_emu0204_controls[] = { | 525 | static struct snd_kcontrol_new snd_emu0204_control = { |
496 | { | 526 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
497 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 527 | .name = "Front Jack Channels", |
498 | .name = "Front Jack Channels", | 528 | .info = snd_emu0204_ch_switch_info, |
499 | .info = snd_emu0204_ch_switch_info, | 529 | .get = snd_emu0204_ch_switch_get, |
500 | .get = snd_emu0204_ch_switch_get, | 530 | .put = snd_emu0204_ch_switch_put, |
501 | .put = snd_emu0204_ch_switch_put, | 531 | .private_value = 0, |
502 | .private_value = 0, | ||
503 | }, | ||
504 | }; | 532 | }; |
505 | 533 | ||
506 | static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) | 534 | static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) |
507 | { | 535 | { |
508 | int i, err; | 536 | return add_single_ctl_with_resume(mixer, 0, |
509 | 537 | snd_emu0204_ch_switch_resume, | |
510 | for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { | 538 | &snd_emu0204_control, NULL); |
511 | err = snd_ctl_add(mixer->chip->card, | ||
512 | snd_ctl_new1(&snd_emu0204_controls[i], mixer)); | ||
513 | if (err < 0) | ||
514 | return err; | ||
515 | } | ||
516 | |||
517 | return 0; | ||
518 | } | 539 | } |
540 | |||
519 | /* ASUS Xonar U1 / U3 controls */ | 541 | /* ASUS Xonar U1 / U3 controls */ |
520 | 542 | ||
521 | static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, | 543 | static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, |
522 | struct snd_ctl_elem_value *ucontrol) | 544 | struct snd_ctl_elem_value *ucontrol) |
523 | { | 545 | { |
524 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 546 | ucontrol->value.integer.value[0] = !!(kcontrol->private_value & 0x02); |
525 | |||
526 | ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02); | ||
527 | return 0; | 547 | return 0; |
528 | } | 548 | } |
529 | 549 | ||
550 | static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer, | ||
551 | unsigned char status) | ||
552 | { | ||
553 | struct snd_usb_audio *chip = mixer->chip; | ||
554 | int err; | ||
555 | |||
556 | down_read(&chip->shutdown_rwsem); | ||
557 | if (chip->shutdown) | ||
558 | err = -ENODEV; | ||
559 | else | ||
560 | err = snd_usb_ctl_msg(chip->dev, | ||
561 | usb_sndctrlpipe(chip->dev, 0), 0x08, | ||
562 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | ||
563 | 50, 0, &status, 1); | ||
564 | up_read(&chip->shutdown_rwsem); | ||
565 | return err; | ||
566 | } | ||
567 | |||
530 | static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, | 568 | static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, |
531 | struct snd_ctl_elem_value *ucontrol) | 569 | struct snd_ctl_elem_value *ucontrol) |
532 | { | 570 | { |
533 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 571 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); |
534 | u8 old_status, new_status; | 572 | u8 old_status, new_status; |
535 | int err, changed; | 573 | int err; |
536 | 574 | ||
537 | old_status = mixer->xonar_u1_status; | 575 | old_status = kcontrol->private_value; |
538 | if (ucontrol->value.integer.value[0]) | 576 | if (ucontrol->value.integer.value[0]) |
539 | new_status = old_status | 0x02; | 577 | new_status = old_status | 0x02; |
540 | else | 578 | else |
541 | new_status = old_status & ~0x02; | 579 | new_status = old_status & ~0x02; |
542 | changed = new_status != old_status; | 580 | if (new_status == old_status) |
543 | down_read(&mixer->chip->shutdown_rwsem); | 581 | return 0; |
544 | if (mixer->chip->shutdown) | 582 | |
545 | err = -ENODEV; | 583 | kcontrol->private_value = new_status; |
546 | else | 584 | err = snd_xonar_u1_switch_update(list->mixer, new_status); |
547 | err = snd_usb_ctl_msg(mixer->chip->dev, | 585 | return err < 0 ? err : 1; |
548 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, | 586 | } |
549 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 587 | |
550 | 50, 0, &new_status, 1); | 588 | static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list) |
551 | up_read(&mixer->chip->shutdown_rwsem); | 589 | { |
552 | if (err < 0) | 590 | return snd_xonar_u1_switch_update(list->mixer, |
553 | return err; | 591 | list->kctl->private_value); |
554 | mixer->xonar_u1_status = new_status; | ||
555 | return changed; | ||
556 | } | 592 | } |
557 | 593 | ||
558 | static struct snd_kcontrol_new snd_xonar_u1_output_switch = { | 594 | static struct snd_kcontrol_new snd_xonar_u1_output_switch = { |
@@ -561,82 +597,213 @@ static struct snd_kcontrol_new snd_xonar_u1_output_switch = { | |||
561 | .info = snd_ctl_boolean_mono_info, | 597 | .info = snd_ctl_boolean_mono_info, |
562 | .get = snd_xonar_u1_switch_get, | 598 | .get = snd_xonar_u1_switch_get, |
563 | .put = snd_xonar_u1_switch_put, | 599 | .put = snd_xonar_u1_switch_put, |
600 | .private_value = 0x05, | ||
564 | }; | 601 | }; |
565 | 602 | ||
566 | static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) | 603 | static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) |
567 | { | 604 | { |
605 | return add_single_ctl_with_resume(mixer, 0, | ||
606 | snd_xonar_u1_switch_resume, | ||
607 | &snd_xonar_u1_output_switch, NULL); | ||
608 | } | ||
609 | |||
610 | /* Digidesign Mbox 1 clock source switch (internal/spdif) */ | ||
611 | |||
612 | static int snd_mbox1_switch_get(struct snd_kcontrol *kctl, | ||
613 | struct snd_ctl_elem_value *ucontrol) | ||
614 | { | ||
615 | ucontrol->value.enumerated.item[0] = kctl->private_value; | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val) | ||
620 | { | ||
621 | struct snd_usb_audio *chip = mixer->chip; | ||
568 | int err; | 622 | int err; |
623 | unsigned char buff[3]; | ||
624 | |||
625 | down_read(&chip->shutdown_rwsem); | ||
626 | if (chip->shutdown) { | ||
627 | err = -ENODEV; | ||
628 | goto err; | ||
629 | } | ||
569 | 630 | ||
570 | err = snd_ctl_add(mixer->chip->card, | 631 | /* Prepare for magic command to toggle clock source */ |
571 | snd_ctl_new1(&snd_xonar_u1_output_switch, mixer)); | 632 | err = snd_usb_ctl_msg(chip->dev, |
633 | usb_rcvctrlpipe(chip->dev, 0), 0x81, | ||
634 | USB_DIR_IN | | ||
635 | USB_TYPE_CLASS | | ||
636 | USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1); | ||
572 | if (err < 0) | 637 | if (err < 0) |
573 | return err; | 638 | goto err; |
574 | mixer->xonar_u1_status = 0x05; | 639 | err = snd_usb_ctl_msg(chip->dev, |
575 | return 0; | 640 | usb_rcvctrlpipe(chip->dev, 0), 0x81, |
641 | USB_DIR_IN | | ||
642 | USB_TYPE_CLASS | | ||
643 | USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3); | ||
644 | if (err < 0) | ||
645 | goto err; | ||
646 | |||
647 | /* 2 possibilities: Internal -> send sample rate | ||
648 | * S/PDIF sync -> send zeroes | ||
649 | * NB: Sample rate locked to 48kHz on purpose to | ||
650 | * prevent user from resetting the sample rate | ||
651 | * while S/PDIF sync is enabled and confusing | ||
652 | * this configuration. | ||
653 | */ | ||
654 | if (val == 0) { | ||
655 | buff[0] = 0x80; | ||
656 | buff[1] = 0xbb; | ||
657 | buff[2] = 0x00; | ||
658 | } else { | ||
659 | buff[0] = buff[1] = buff[2] = 0x00; | ||
660 | } | ||
661 | |||
662 | /* Send the magic command to toggle the clock source */ | ||
663 | err = snd_usb_ctl_msg(chip->dev, | ||
664 | usb_sndctrlpipe(chip->dev, 0), 0x1, | ||
665 | USB_TYPE_CLASS | | ||
666 | USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3); | ||
667 | if (err < 0) | ||
668 | goto err; | ||
669 | err = snd_usb_ctl_msg(chip->dev, | ||
670 | usb_rcvctrlpipe(chip->dev, 0), 0x81, | ||
671 | USB_DIR_IN | | ||
672 | USB_TYPE_CLASS | | ||
673 | USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3); | ||
674 | if (err < 0) | ||
675 | goto err; | ||
676 | err = snd_usb_ctl_msg(chip->dev, | ||
677 | usb_rcvctrlpipe(chip->dev, 0), 0x81, | ||
678 | USB_DIR_IN | | ||
679 | USB_TYPE_CLASS | | ||
680 | USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3); | ||
681 | if (err < 0) | ||
682 | goto err; | ||
683 | |||
684 | err: | ||
685 | up_read(&chip->shutdown_rwsem); | ||
686 | return err; | ||
687 | } | ||
688 | |||
689 | static int snd_mbox1_switch_put(struct snd_kcontrol *kctl, | ||
690 | struct snd_ctl_elem_value *ucontrol) | ||
691 | { | ||
692 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); | ||
693 | struct usb_mixer_interface *mixer = list->mixer; | ||
694 | int err; | ||
695 | bool cur_val, new_val; | ||
696 | |||
697 | cur_val = kctl->private_value; | ||
698 | new_val = ucontrol->value.enumerated.item[0]; | ||
699 | if (cur_val == new_val) | ||
700 | return 0; | ||
701 | |||
702 | kctl->private_value = new_val; | ||
703 | err = snd_mbox1_switch_update(mixer, new_val); | ||
704 | return err < 0 ? err : 1; | ||
705 | } | ||
706 | |||
707 | static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol, | ||
708 | struct snd_ctl_elem_info *uinfo) | ||
709 | { | ||
710 | static const char *const texts[2] = { | ||
711 | "Internal", | ||
712 | "S/PDIF" | ||
713 | }; | ||
714 | |||
715 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); | ||
716 | } | ||
717 | |||
718 | static int snd_mbox1_switch_resume(struct usb_mixer_elem_list *list) | ||
719 | { | ||
720 | return snd_mbox1_switch_update(list->mixer, list->kctl->private_value); | ||
721 | } | ||
722 | |||
723 | static struct snd_kcontrol_new snd_mbox1_switch = { | ||
724 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
725 | .name = "Clock Source", | ||
726 | .index = 0, | ||
727 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
728 | .info = snd_mbox1_switch_info, | ||
729 | .get = snd_mbox1_switch_get, | ||
730 | .put = snd_mbox1_switch_put, | ||
731 | .private_value = 0 | ||
732 | }; | ||
733 | |||
734 | static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer) | ||
735 | { | ||
736 | return add_single_ctl_with_resume(mixer, 0, | ||
737 | snd_mbox1_switch_resume, | ||
738 | &snd_mbox1_switch, NULL); | ||
576 | } | 739 | } |
577 | 740 | ||
578 | /* Native Instruments device quirks */ | 741 | /* Native Instruments device quirks */ |
579 | 742 | ||
580 | #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex)) | 743 | #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex)) |
581 | 744 | ||
582 | static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, | 745 | static int snd_ni_control_init_val(struct usb_mixer_interface *mixer, |
583 | struct snd_ctl_elem_value *ucontrol) | 746 | struct snd_kcontrol *kctl) |
584 | { | 747 | { |
585 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | ||
586 | struct usb_device *dev = mixer->chip->dev; | 748 | struct usb_device *dev = mixer->chip->dev; |
587 | u8 bRequest = (kcontrol->private_value >> 16) & 0xff; | 749 | unsigned int pval = kctl->private_value; |
588 | u16 wIndex = kcontrol->private_value & 0xffff; | 750 | u8 value; |
589 | u8 tmp; | 751 | int err; |
590 | int ret; | ||
591 | |||
592 | down_read(&mixer->chip->shutdown_rwsem); | ||
593 | if (mixer->chip->shutdown) | ||
594 | ret = -ENODEV; | ||
595 | else | ||
596 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, | ||
597 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | ||
598 | 0, wIndex, | ||
599 | &tmp, sizeof(tmp)); | ||
600 | up_read(&mixer->chip->shutdown_rwsem); | ||
601 | 752 | ||
602 | if (ret < 0) { | 753 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), |
754 | (pval >> 16) & 0xff, | ||
755 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | ||
756 | 0, pval & 0xffff, &value, 1); | ||
757 | if (err < 0) { | ||
603 | dev_err(&dev->dev, | 758 | dev_err(&dev->dev, |
604 | "unable to issue vendor read request (ret = %d)", ret); | 759 | "unable to issue vendor read request (ret = %d)", err); |
605 | return ret; | 760 | return err; |
606 | } | 761 | } |
607 | 762 | ||
608 | ucontrol->value.integer.value[0] = tmp; | 763 | kctl->private_value |= (value << 24); |
764 | return 0; | ||
765 | } | ||
609 | 766 | ||
767 | static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, | ||
768 | struct snd_ctl_elem_value *ucontrol) | ||
769 | { | ||
770 | ucontrol->value.integer.value[0] = kcontrol->private_value >> 24; | ||
610 | return 0; | 771 | return 0; |
611 | } | 772 | } |
612 | 773 | ||
774 | static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list) | ||
775 | { | ||
776 | struct snd_usb_audio *chip = list->mixer->chip; | ||
777 | unsigned int pval = list->kctl->private_value; | ||
778 | int err; | ||
779 | |||
780 | down_read(&chip->shutdown_rwsem); | ||
781 | if (chip->shutdown) | ||
782 | err = -ENODEV; | ||
783 | else | ||
784 | err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), | ||
785 | (pval >> 16) & 0xff, | ||
786 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
787 | pval >> 24, pval & 0xffff, NULL, 0, 1000); | ||
788 | up_read(&chip->shutdown_rwsem); | ||
789 | return err; | ||
790 | } | ||
791 | |||
613 | static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, | 792 | static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, |
614 | struct snd_ctl_elem_value *ucontrol) | 793 | struct snd_ctl_elem_value *ucontrol) |
615 | { | 794 | { |
616 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 795 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); |
617 | struct usb_device *dev = mixer->chip->dev; | 796 | u8 oldval = (kcontrol->private_value >> 24) & 0xff; |
618 | u8 bRequest = (kcontrol->private_value >> 16) & 0xff; | 797 | u8 newval = ucontrol->value.integer.value[0]; |
619 | u16 wIndex = kcontrol->private_value & 0xffff; | 798 | int err; |
620 | u16 wValue = ucontrol->value.integer.value[0]; | ||
621 | int ret; | ||
622 | |||
623 | down_read(&mixer->chip->shutdown_rwsem); | ||
624 | if (mixer->chip->shutdown) | ||
625 | ret = -ENODEV; | ||
626 | else | ||
627 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, | ||
628 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
629 | wValue, wIndex, | ||
630 | NULL, 0, 1000); | ||
631 | up_read(&mixer->chip->shutdown_rwsem); | ||
632 | 799 | ||
633 | if (ret < 0) { | 800 | if (oldval == newval) |
634 | dev_err(&dev->dev, | 801 | return 0; |
635 | "unable to issue vendor write request (ret = %d)", ret); | ||
636 | return ret; | ||
637 | } | ||
638 | 802 | ||
639 | return 0; | 803 | kcontrol->private_value &= ~(0xff << 24); |
804 | kcontrol->private_value |= newval; | ||
805 | err = snd_ni_update_cur_val(list); | ||
806 | return err < 0 ? err : 1; | ||
640 | } | 807 | } |
641 | 808 | ||
642 | static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = { | 809 | static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = { |
@@ -707,16 +874,17 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, | |||
707 | }; | 874 | }; |
708 | 875 | ||
709 | for (i = 0; i < count; i++) { | 876 | for (i = 0; i < count; i++) { |
710 | struct snd_kcontrol *c; | 877 | struct usb_mixer_elem_list *list; |
711 | 878 | ||
712 | template.name = kc[i].name; | 879 | template.name = kc[i].name; |
713 | template.private_value = kc[i].private_value; | 880 | template.private_value = kc[i].private_value; |
714 | 881 | ||
715 | c = snd_ctl_new1(&template, mixer); | 882 | err = add_single_ctl_with_resume(mixer, 0, |
716 | err = snd_ctl_add(mixer->chip->card, c); | 883 | snd_ni_update_cur_val, |
717 | 884 | &template, &list); | |
718 | if (err < 0) | 885 | if (err < 0) |
719 | break; | 886 | break; |
887 | snd_ni_control_init_val(mixer, list->kctl); | ||
720 | } | 888 | } |
721 | 889 | ||
722 | return err; | 890 | return err; |
@@ -724,170 +892,88 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, | |||
724 | 892 | ||
725 | /* M-Audio FastTrack Ultra quirks */ | 893 | /* M-Audio FastTrack Ultra quirks */ |
726 | /* FTU Effect switch (also used by C400/C600) */ | 894 | /* FTU Effect switch (also used by C400/C600) */ |
727 | struct snd_ftu_eff_switch_priv_val { | ||
728 | struct usb_mixer_interface *mixer; | ||
729 | int cached_value; | ||
730 | int is_cached; | ||
731 | int bUnitID; | ||
732 | int validx; | ||
733 | }; | ||
734 | |||
735 | static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, | 895 | static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, |
736 | struct snd_ctl_elem_info *uinfo) | 896 | struct snd_ctl_elem_info *uinfo) |
737 | { | 897 | { |
738 | static const char *texts[8] = {"Room 1", | 898 | static const char *const texts[8] = { |
739 | "Room 2", | 899 | "Room 1", "Room 2", "Room 3", "Hall 1", |
740 | "Room 3", | 900 | "Hall 2", "Plate", "Delay", "Echo" |
741 | "Hall 1", | ||
742 | "Hall 2", | ||
743 | "Plate", | ||
744 | "Delay", | ||
745 | "Echo" | ||
746 | }; | 901 | }; |
747 | 902 | ||
748 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 903 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); |
749 | uinfo->count = 1; | ||
750 | uinfo->value.enumerated.items = 8; | ||
751 | if (uinfo->value.enumerated.item > 7) | ||
752 | uinfo->value.enumerated.item = 7; | ||
753 | strcpy(uinfo->value.enumerated.name, | ||
754 | texts[uinfo->value.enumerated.item]); | ||
755 | |||
756 | return 0; | ||
757 | } | 904 | } |
758 | 905 | ||
759 | static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, | 906 | static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer, |
760 | struct snd_ctl_elem_value *ucontrol) | 907 | struct snd_kcontrol *kctl) |
761 | { | 908 | { |
762 | struct snd_usb_audio *chip; | 909 | struct usb_device *dev = mixer->chip->dev; |
763 | struct usb_mixer_interface *mixer; | 910 | unsigned int pval = kctl->private_value; |
764 | struct snd_ftu_eff_switch_priv_val *pval; | ||
765 | int err; | 911 | int err; |
766 | unsigned char value[2]; | 912 | unsigned char value[2]; |
767 | int id, validx; | ||
768 | |||
769 | const int val_len = 2; | ||
770 | 913 | ||
771 | value[0] = 0x00; | 914 | value[0] = 0x00; |
772 | value[1] = 0x00; | 915 | value[1] = 0x00; |
773 | 916 | ||
774 | pval = (struct snd_ftu_eff_switch_priv_val *) | 917 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, |
775 | kctl->private_value; | 918 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
919 | pval & 0xff00, | ||
920 | snd_usb_ctrl_intf(mixer->chip) | ((pval & 0xff) << 8), | ||
921 | value, 2); | ||
922 | if (err < 0) | ||
923 | return err; | ||
776 | 924 | ||
777 | if (pval->is_cached) { | 925 | kctl->private_value |= value[0] << 24; |
778 | ucontrol->value.enumerated.item[0] = pval->cached_value; | 926 | return 0; |
779 | return 0; | 927 | } |
780 | } | ||
781 | 928 | ||
782 | mixer = (struct usb_mixer_interface *) pval->mixer; | 929 | static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, |
783 | if (snd_BUG_ON(!mixer)) | 930 | struct snd_ctl_elem_value *ucontrol) |
784 | return -EINVAL; | 931 | { |
932 | ucontrol->value.enumerated.item[0] = kctl->private_value >> 24; | ||
933 | return 0; | ||
934 | } | ||
785 | 935 | ||
786 | chip = (struct snd_usb_audio *) mixer->chip; | 936 | static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list) |
787 | if (snd_BUG_ON(!chip)) | 937 | { |
788 | return -EINVAL; | 938 | struct snd_usb_audio *chip = list->mixer->chip; |
939 | unsigned int pval = list->kctl->private_value; | ||
940 | unsigned char value[2]; | ||
941 | int err; | ||
789 | 942 | ||
790 | id = pval->bUnitID; | 943 | value[0] = pval >> 24; |
791 | validx = pval->validx; | 944 | value[1] = 0; |
792 | 945 | ||
793 | down_read(&mixer->chip->shutdown_rwsem); | 946 | down_read(&chip->shutdown_rwsem); |
794 | if (mixer->chip->shutdown) | 947 | if (chip->shutdown) |
795 | err = -ENODEV; | 948 | err = -ENODEV; |
796 | else | 949 | else |
797 | err = snd_usb_ctl_msg(chip->dev, | 950 | err = snd_usb_ctl_msg(chip->dev, |
798 | usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, | 951 | usb_sndctrlpipe(chip->dev, 0), |
799 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 952 | UAC_SET_CUR, |
800 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | 953 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, |
801 | value, val_len); | 954 | pval & 0xff00, |
802 | up_read(&mixer->chip->shutdown_rwsem); | 955 | snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8), |
803 | if (err < 0) | 956 | value, 2); |
804 | return err; | 957 | up_read(&chip->shutdown_rwsem); |
805 | 958 | return err; | |
806 | ucontrol->value.enumerated.item[0] = value[0]; | ||
807 | pval->cached_value = value[0]; | ||
808 | pval->is_cached = 1; | ||
809 | |||
810 | return 0; | ||
811 | } | 959 | } |
812 | 960 | ||
813 | static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, | 961 | static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, |
814 | struct snd_ctl_elem_value *ucontrol) | 962 | struct snd_ctl_elem_value *ucontrol) |
815 | { | 963 | { |
816 | struct snd_usb_audio *chip; | 964 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); |
817 | struct snd_ftu_eff_switch_priv_val *pval; | 965 | unsigned int pval = list->kctl->private_value; |
966 | int cur_val, err, new_val; | ||
818 | 967 | ||
819 | struct usb_mixer_interface *mixer; | 968 | cur_val = pval >> 24; |
820 | int changed, cur_val, err, new_val; | ||
821 | unsigned char value[2]; | ||
822 | int id, validx; | ||
823 | |||
824 | const int val_len = 2; | ||
825 | |||
826 | changed = 0; | ||
827 | |||
828 | pval = (struct snd_ftu_eff_switch_priv_val *) | ||
829 | kctl->private_value; | ||
830 | cur_val = pval->cached_value; | ||
831 | new_val = ucontrol->value.enumerated.item[0]; | 969 | new_val = ucontrol->value.enumerated.item[0]; |
970 | if (cur_val == new_val) | ||
971 | return 0; | ||
832 | 972 | ||
833 | mixer = (struct usb_mixer_interface *) pval->mixer; | 973 | kctl->private_value &= ~(0xff << 24); |
834 | if (snd_BUG_ON(!mixer)) | 974 | kctl->private_value |= new_val << 24; |
835 | return -EINVAL; | 975 | err = snd_ftu_eff_switch_update(list); |
836 | 976 | return err < 0 ? err : 1; | |
837 | chip = (struct snd_usb_audio *) mixer->chip; | ||
838 | if (snd_BUG_ON(!chip)) | ||
839 | return -EINVAL; | ||
840 | |||
841 | id = pval->bUnitID; | ||
842 | validx = pval->validx; | ||
843 | |||
844 | if (!pval->is_cached) { | ||
845 | /* Read current value */ | ||
846 | down_read(&mixer->chip->shutdown_rwsem); | ||
847 | if (mixer->chip->shutdown) | ||
848 | err = -ENODEV; | ||
849 | else | ||
850 | err = snd_usb_ctl_msg(chip->dev, | ||
851 | usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, | ||
852 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
853 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
854 | value, val_len); | ||
855 | up_read(&mixer->chip->shutdown_rwsem); | ||
856 | if (err < 0) | ||
857 | return err; | ||
858 | |||
859 | cur_val = value[0]; | ||
860 | pval->cached_value = cur_val; | ||
861 | pval->is_cached = 1; | ||
862 | } | ||
863 | /* update value if needed */ | ||
864 | if (cur_val != new_val) { | ||
865 | value[0] = new_val; | ||
866 | value[1] = 0; | ||
867 | down_read(&mixer->chip->shutdown_rwsem); | ||
868 | if (mixer->chip->shutdown) | ||
869 | err = -ENODEV; | ||
870 | else | ||
871 | err = snd_usb_ctl_msg(chip->dev, | ||
872 | usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, | ||
873 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | ||
874 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
875 | value, val_len); | ||
876 | up_read(&mixer->chip->shutdown_rwsem); | ||
877 | if (err < 0) | ||
878 | return err; | ||
879 | |||
880 | pval->cached_value = new_val; | ||
881 | pval->is_cached = 1; | ||
882 | changed = 1; | ||
883 | } | ||
884 | |||
885 | return changed; | ||
886 | } | ||
887 | |||
888 | static void kctl_private_value_free(struct snd_kcontrol *kctl) | ||
889 | { | ||
890 | kfree((void *)kctl->private_value); | ||
891 | } | 977 | } |
892 | 978 | ||
893 | static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, | 979 | static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, |
@@ -902,33 +988,16 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, | |||
902 | .get = snd_ftu_eff_switch_get, | 988 | .get = snd_ftu_eff_switch_get, |
903 | .put = snd_ftu_eff_switch_put | 989 | .put = snd_ftu_eff_switch_put |
904 | }; | 990 | }; |
905 | 991 | struct usb_mixer_elem_list *list; | |
906 | int err; | 992 | int err; |
907 | struct snd_kcontrol *kctl; | ||
908 | struct snd_ftu_eff_switch_priv_val *pval; | ||
909 | |||
910 | pval = kzalloc(sizeof(*pval), GFP_KERNEL); | ||
911 | if (!pval) | ||
912 | return -ENOMEM; | ||
913 | |||
914 | pval->cached_value = 0; | ||
915 | pval->is_cached = 0; | ||
916 | pval->mixer = mixer; | ||
917 | pval->bUnitID = bUnitID; | ||
918 | pval->validx = validx; | ||
919 | |||
920 | template.private_value = (unsigned long) pval; | ||
921 | kctl = snd_ctl_new1(&template, mixer->chip); | ||
922 | if (!kctl) { | ||
923 | kfree(pval); | ||
924 | return -ENOMEM; | ||
925 | } | ||
926 | 993 | ||
927 | kctl->private_free = kctl_private_value_free; | 994 | err = add_single_ctl_with_resume(mixer, bUnitID, |
928 | err = snd_ctl_add(mixer->chip->card, kctl); | 995 | snd_ftu_eff_switch_update, |
996 | &template, &list); | ||
929 | if (err < 0) | 997 | if (err < 0) |
930 | return err; | 998 | return err; |
931 | 999 | list->kctl->private_value = (validx << 8) | bUnitID; | |
1000 | snd_ftu_eff_switch_init(mixer, list->kctl); | ||
932 | return 0; | 1001 | return 0; |
933 | } | 1002 | } |
934 | 1003 | ||
@@ -1110,7 +1179,7 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | |||
1110 | int unitid = 12; /* SamleRate ExtensionUnit ID */ | 1179 | int unitid = 12; /* SamleRate ExtensionUnit ID */ |
1111 | 1180 | ||
1112 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 1181 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
1113 | cval = mixer->id_elems[unitid]; | 1182 | cval = (struct usb_mixer_elem_info *)mixer->id_elems[unitid]; |
1114 | if (cval) { | 1183 | if (cval) { |
1115 | snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, | 1184 | snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, |
1116 | cval->control << 8, | 1185 | cval->control << 8, |
@@ -1440,7 +1509,8 @@ static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol, | |||
1440 | static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, | 1509 | static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, |
1441 | struct snd_ctl_elem_value *ucontrol) | 1510 | struct snd_ctl_elem_value *ucontrol) |
1442 | { | 1511 | { |
1443 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 1512 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); |
1513 | struct snd_usb_audio *chip = list->mixer->chip; | ||
1444 | int err; | 1514 | int err; |
1445 | struct usb_interface *iface; | 1515 | struct usb_interface *iface; |
1446 | struct usb_host_interface *alts; | 1516 | struct usb_host_interface *alts; |
@@ -1448,17 +1518,23 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, | |||
1448 | unsigned char data[3]; | 1518 | unsigned char data[3]; |
1449 | int rate; | 1519 | int rate; |
1450 | 1520 | ||
1521 | down_read(&chip->shutdown_rwsem); | ||
1522 | if (chip->shutdown) { | ||
1523 | err = -ENODEV; | ||
1524 | goto end; | ||
1525 | } | ||
1526 | |||
1451 | ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff; | 1527 | ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff; |
1452 | ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff; | 1528 | ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff; |
1453 | ucontrol->value.iec958.status[2] = 0x00; | 1529 | ucontrol->value.iec958.status[2] = 0x00; |
1454 | 1530 | ||
1455 | /* use known values for that card: interface#1 altsetting#1 */ | 1531 | /* use known values for that card: interface#1 altsetting#1 */ |
1456 | iface = usb_ifnum_to_if(mixer->chip->dev, 1); | 1532 | iface = usb_ifnum_to_if(chip->dev, 1); |
1457 | alts = &iface->altsetting[1]; | 1533 | alts = &iface->altsetting[1]; |
1458 | ep = get_endpoint(alts, 0)->bEndpointAddress; | 1534 | ep = get_endpoint(alts, 0)->bEndpointAddress; |
1459 | 1535 | ||
1460 | err = snd_usb_ctl_msg(mixer->chip->dev, | 1536 | err = snd_usb_ctl_msg(chip->dev, |
1461 | usb_rcvctrlpipe(mixer->chip->dev, 0), | 1537 | usb_rcvctrlpipe(chip->dev, 0), |
1462 | UAC_GET_CUR, | 1538 | UAC_GET_CUR, |
1463 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, | 1539 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, |
1464 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, | 1540 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, |
@@ -1473,22 +1549,27 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, | |||
1473 | IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100; | 1549 | IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100; |
1474 | 1550 | ||
1475 | err = 0; | 1551 | err = 0; |
1476 | end: | 1552 | end: |
1553 | up_read(&chip->shutdown_rwsem); | ||
1477 | return err; | 1554 | return err; |
1478 | } | 1555 | } |
1479 | 1556 | ||
1480 | static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, | 1557 | static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list) |
1481 | struct snd_ctl_elem_value *ucontrol) | ||
1482 | { | 1558 | { |
1483 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 1559 | struct snd_usb_audio *chip = list->mixer->chip; |
1484 | int err; | 1560 | unsigned int pval = list->kctl->private_value; |
1485 | u8 reg; | 1561 | u8 reg; |
1486 | unsigned long priv_backup = kcontrol->private_value; | 1562 | int err; |
1487 | 1563 | ||
1488 | reg = ((ucontrol->value.iec958.status[1] & 0x0f) << 4) | | 1564 | down_read(&chip->shutdown_rwsem); |
1489 | (ucontrol->value.iec958.status[0] & 0x0f); | 1565 | if (chip->shutdown) { |
1490 | err = snd_usb_ctl_msg(mixer->chip->dev, | 1566 | err = -ENODEV; |
1491 | usb_sndctrlpipe(mixer->chip->dev, 0), | 1567 | goto end; |
1568 | } | ||
1569 | |||
1570 | reg = ((pval >> 4) & 0xf0) | (pval & 0x0f); | ||
1571 | err = snd_usb_ctl_msg(chip->dev, | ||
1572 | usb_sndctrlpipe(chip->dev, 0), | ||
1492 | UAC_SET_CUR, | 1573 | UAC_SET_CUR, |
1493 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 1574 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
1494 | reg, | 1575 | reg, |
@@ -1498,15 +1579,10 @@ static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
1498 | if (err < 0) | 1579 | if (err < 0) |
1499 | goto end; | 1580 | goto end; |
1500 | 1581 | ||
1501 | kcontrol->private_value &= 0xfffff0f0; | 1582 | reg = (pval & IEC958_AES0_NONAUDIO) ? 0xa0 : 0x20; |
1502 | kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0x0f) << 8; | 1583 | reg |= (pval >> 12) & 0x0f; |
1503 | kcontrol->private_value |= (ucontrol->value.iec958.status[0] & 0x0f); | 1584 | err = snd_usb_ctl_msg(chip->dev, |
1504 | 1585 | usb_sndctrlpipe(chip->dev, 0), | |
1505 | reg = (ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO) ? | ||
1506 | 0xa0 : 0x20; | ||
1507 | reg |= (ucontrol->value.iec958.status[1] >> 4) & 0x0f; | ||
1508 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
1509 | usb_sndctrlpipe(mixer->chip->dev, 0), | ||
1510 | UAC_SET_CUR, | 1586 | UAC_SET_CUR, |
1511 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 1587 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
1512 | reg, | 1588 | reg, |
@@ -1516,16 +1592,36 @@ static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
1516 | if (err < 0) | 1592 | if (err < 0) |
1517 | goto end; | 1593 | goto end; |
1518 | 1594 | ||
1519 | kcontrol->private_value &= 0xffff0fff; | 1595 | end: |
1520 | kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0xf0) << 8; | 1596 | up_read(&chip->shutdown_rwsem); |
1597 | return err; | ||
1598 | } | ||
1599 | |||
1600 | static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, | ||
1601 | struct snd_ctl_elem_value *ucontrol) | ||
1602 | { | ||
1603 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); | ||
1604 | unsigned int pval, pval_old; | ||
1605 | int err; | ||
1606 | |||
1607 | pval = pval_old = kcontrol->private_value; | ||
1608 | pval &= 0xfffff0f0; | ||
1609 | pval |= (ucontrol->value.iec958.status[1] & 0x0f) << 8; | ||
1610 | pval |= (ucontrol->value.iec958.status[0] & 0x0f); | ||
1611 | |||
1612 | pval &= 0xffff0fff; | ||
1613 | pval |= (ucontrol->value.iec958.status[1] & 0xf0) << 8; | ||
1521 | 1614 | ||
1522 | /* The frequency bits in AES3 cannot be set via register access. */ | 1615 | /* The frequency bits in AES3 cannot be set via register access. */ |
1523 | 1616 | ||
1524 | /* Silently ignore any bits from the request that cannot be set. */ | 1617 | /* Silently ignore any bits from the request that cannot be set. */ |
1525 | 1618 | ||
1526 | err = (priv_backup != kcontrol->private_value); | 1619 | if (pval == pval_old) |
1527 | end: | 1620 | return 0; |
1528 | return err; | 1621 | |
1622 | kcontrol->private_value = pval; | ||
1623 | err = snd_microii_spdif_default_update(list); | ||
1624 | return err < 0 ? err : 1; | ||
1529 | } | 1625 | } |
1530 | 1626 | ||
1531 | static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol, | 1627 | static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol, |
@@ -1547,15 +1643,20 @@ static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol, | |||
1547 | return 0; | 1643 | return 0; |
1548 | } | 1644 | } |
1549 | 1645 | ||
1550 | static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol, | 1646 | static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list) |
1551 | struct snd_ctl_elem_value *ucontrol) | ||
1552 | { | 1647 | { |
1553 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | 1648 | struct snd_usb_audio *chip = list->mixer->chip; |
1649 | u8 reg = list->kctl->private_value; | ||
1554 | int err; | 1650 | int err; |
1555 | u8 reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a; | ||
1556 | 1651 | ||
1557 | err = snd_usb_ctl_msg(mixer->chip->dev, | 1652 | down_read(&chip->shutdown_rwsem); |
1558 | usb_sndctrlpipe(mixer->chip->dev, 0), | 1653 | if (chip->shutdown) { |
1654 | err = -ENODEV; | ||
1655 | goto end; | ||
1656 | } | ||
1657 | |||
1658 | err = snd_usb_ctl_msg(chip->dev, | ||
1659 | usb_sndctrlpipe(chip->dev, 0), | ||
1559 | UAC_SET_CUR, | 1660 | UAC_SET_CUR, |
1560 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 1661 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
1561 | reg, | 1662 | reg, |
@@ -1563,15 +1664,27 @@ static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol, | |||
1563 | NULL, | 1664 | NULL, |
1564 | 0); | 1665 | 0); |
1565 | 1666 | ||
1566 | if (!err) { | 1667 | end: |
1567 | err = (reg != (kcontrol->private_value & 0x0ff)); | 1668 | up_read(&chip->shutdown_rwsem); |
1568 | if (err) | ||
1569 | kcontrol->private_value = reg; | ||
1570 | } | ||
1571 | |||
1572 | return err; | 1669 | return err; |
1573 | } | 1670 | } |
1574 | 1671 | ||
1672 | static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol, | ||
1673 | struct snd_ctl_elem_value *ucontrol) | ||
1674 | { | ||
1675 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); | ||
1676 | u8 reg; | ||
1677 | int err; | ||
1678 | |||
1679 | reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a; | ||
1680 | if (reg != list->kctl->private_value) | ||
1681 | return 0; | ||
1682 | |||
1683 | kcontrol->private_value = reg; | ||
1684 | err = snd_microii_spdif_switch_update(list); | ||
1685 | return err < 0 ? err : 1; | ||
1686 | } | ||
1687 | |||
1575 | static struct snd_kcontrol_new snd_microii_mixer_spdif[] = { | 1688 | static struct snd_kcontrol_new snd_microii_mixer_spdif[] = { |
1576 | { | 1689 | { |
1577 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1690 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -1601,10 +1714,17 @@ static struct snd_kcontrol_new snd_microii_mixer_spdif[] = { | |||
1601 | static int snd_microii_controls_create(struct usb_mixer_interface *mixer) | 1714 | static int snd_microii_controls_create(struct usb_mixer_interface *mixer) |
1602 | { | 1715 | { |
1603 | int err, i; | 1716 | int err, i; |
1717 | static usb_mixer_elem_resume_func_t resume_funcs[] = { | ||
1718 | snd_microii_spdif_default_update, | ||
1719 | NULL, | ||
1720 | snd_microii_spdif_switch_update | ||
1721 | }; | ||
1604 | 1722 | ||
1605 | for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) { | 1723 | for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) { |
1606 | err = snd_ctl_add(mixer->chip->card, | 1724 | err = add_single_ctl_with_resume(mixer, 0, |
1607 | snd_ctl_new1(&snd_microii_mixer_spdif[i], mixer)); | 1725 | resume_funcs[i], |
1726 | &snd_microii_mixer_spdif[i], | ||
1727 | NULL); | ||
1608 | if (err < 0) | 1728 | if (err < 0) |
1609 | return err; | 1729 | return err; |
1610 | } | 1730 | } |
@@ -1661,6 +1781,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1661 | err = snd_microii_controls_create(mixer); | 1781 | err = snd_microii_controls_create(mixer); |
1662 | break; | 1782 | break; |
1663 | 1783 | ||
1784 | case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */ | ||
1785 | err = snd_mbox1_create_sync_switch(mixer); | ||
1786 | break; | ||
1787 | |||
1664 | case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */ | 1788 | case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */ |
1665 | err = snd_nativeinstruments_create_mixer(mixer, | 1789 | err = snd_nativeinstruments_create_mixer(mixer, |
1666 | snd_nativeinstruments_ta6_mixers, | 1790 | snd_nativeinstruments_ta6_mixers, |
@@ -1677,6 +1801,14 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1677 | /* detection is disabled in mixer_maps.c */ | 1801 | /* detection is disabled in mixer_maps.c */ |
1678 | err = snd_create_std_mono_table(mixer, ebox44_table); | 1802 | err = snd_create_std_mono_table(mixer, ebox44_table); |
1679 | break; | 1803 | break; |
1804 | |||
1805 | case USB_ID(0x1235, 0x8012): /* Focusrite Scarlett 6i6 */ | ||
1806 | case USB_ID(0x1235, 0x8002): /* Focusrite Scarlett 8i6 */ | ||
1807 | case USB_ID(0x1235, 0x8004): /* Focusrite Scarlett 18i6 */ | ||
1808 | case USB_ID(0x1235, 0x8014): /* Focusrite Scarlett 18i8 */ | ||
1809 | case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */ | ||
1810 | err = snd_scarlett_controls_create(mixer); | ||
1811 | break; | ||
1680 | } | 1812 | } |
1681 | 1813 | ||
1682 | return err; | 1814 | return err; |
diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c new file mode 100644 index 000000000000..9109652b88b9 --- /dev/null +++ b/sound/usb/mixer_scarlett.c | |||
@@ -0,0 +1,1004 @@ | |||
1 | /* | ||
2 | * Scarlett Driver for ALSA | ||
3 | * | ||
4 | * Copyright (c) 2013 by Tobias Hoffmann | ||
5 | * Copyright (c) 2013 by Robin Gareus <robin at gareus.org> | ||
6 | * Copyright (c) 2002 by Takashi Iwai <tiwai at suse.de> | ||
7 | * Copyright (c) 2014 by Chris J Arges <chris.j.arges at canonical.com> | ||
8 | * | ||
9 | * Many codes borrowed from audio.c by | ||
10 | * Alan Cox (alan at lxorguk.ukuu.org.uk) | ||
11 | * Thomas Sailer (sailer at ife.ee.ethz.ch) | ||
12 | * | ||
13 | * Code cleanup: | ||
14 | * David Henningsson <david.henningsson at canonical.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Rewritten and extended to support more models, e.g. Scarlett 18i8. | ||
30 | * | ||
31 | * Auto-detection via UAC2 is not feasible to properly discover the vast | ||
32 | * majority of features. It's related to both Linux/ALSA's UAC2 as well as | ||
33 | * Focusrite's implementation of it. Eventually quirks may be sufficient but | ||
34 | * right now it's a major headache to work arount these things. | ||
35 | * | ||
36 | * NB. Neither the OSX nor the win driver provided by Focusrite performs | ||
37 | * discovery, they seem to operate the same as this driver. | ||
38 | */ | ||
39 | |||
40 | /* Mixer Interface for the Focusrite Scarlett 18i6 audio interface. | ||
41 | * | ||
42 | * The protocol was reverse engineered by looking at communication between | ||
43 | * Scarlett MixControl (v 1.2.128.0) and the Focusrite(R) Scarlett 18i6 | ||
44 | * (firmware v305) using wireshark and usbmon in January 2013. | ||
45 | * Extended in July 2013. | ||
46 | * | ||
47 | * this mixer gives complete access to all features of the device: | ||
48 | * - change Impedance of inputs (Line-in, Mic / Instrument, Hi-Z) | ||
49 | * - select clock source | ||
50 | * - dynamic input to mixer-matrix assignment | ||
51 | * - 18 x 6 mixer-matrix gain stages | ||
52 | * - bus routing & volume control | ||
53 | * - automatic re-initialization on connect if device was power-cycled | ||
54 | * | ||
55 | * USB URB commands overview (bRequest = 0x01 = UAC2_CS_CUR) | ||
56 | * wIndex | ||
57 | * 0x01 Analog Input line/instrument impedance switch, wValue=0x0901 + | ||
58 | * channel, data=Line/Inst (2bytes) | ||
59 | * pad (-10dB) switch, wValue=0x0b01 + channel, data=Off/On (2bytes) | ||
60 | * ?? wValue=0x0803/04, ?? (2bytes) | ||
61 | * 0x0a Master Volume, wValue=0x0200+bus[0:all + only 1..4?] data(2bytes) | ||
62 | * Bus Mute/Unmute wValue=0x0100+bus[0:all + only 1..4?], data(2bytes) | ||
63 | * 0x28 Clock source, wValue=0x0100, data={1:int,2:spdif,3:adat} (1byte) | ||
64 | * 0x29 Set Sample-rate, wValue=0x0100, data=sample-rate(4bytes) | ||
65 | * 0x32 Mixer mux, wValue=0x0600 + mixer-channel, data=input-to-connect(2bytes) | ||
66 | * 0x33 Output mux, wValue=bus, data=input-to-connect(2bytes) | ||
67 | * 0x34 Capture mux, wValue=0...18, data=input-to-connect(2bytes) | ||
68 | * 0x3c Matrix Mixer gains, wValue=mixer-node data=gain(2bytes) | ||
69 | * ?? [sometimes](4bytes, e.g 0x000003be 0x000003bf ...03ff) | ||
70 | * | ||
71 | * USB reads: (i.e. actually issued by original software) | ||
72 | * 0x01 wValue=0x0901+channel (1byte!!), wValue=0x0b01+channed (1byte!!) | ||
73 | * 0x29 wValue=0x0100 sample-rate(4bytes) | ||
74 | * wValue=0x0200 ?? 1byte (only once) | ||
75 | * 0x2a wValue=0x0100 ?? 4bytes, sample-rate2 ?? | ||
76 | * | ||
77 | * USB reads with bRequest = 0x03 = UAC2_CS_MEM | ||
78 | * 0x3c wValue=0x0002 1byte: sync status (locked=1) | ||
79 | * wValue=0x0000 18*2byte: peak meter (inputs) | ||
80 | * wValue=0x0001 8(?)*2byte: peak meter (mix) | ||
81 | * wValue=0x0003 6*2byte: peak meter (pcm/daw) | ||
82 | * | ||
83 | * USB write with bRequest = 0x03 | ||
84 | * 0x3c Save settings to hardware: wValue=0x005a, data=0xa5 | ||
85 | * | ||
86 | * | ||
87 | * <ditaa> | ||
88 | * /--------------\ 18chn 6chn /--------------\ | ||
89 | * | Hardware in +--+-------\ /------+--+ ALSA PCM out | | ||
90 | * \--------------/ | | | | \--------------/ | ||
91 | * | | | | | ||
92 | * | v v | | ||
93 | * | +---------------+ | | ||
94 | * | \ Matrix Mux / | | ||
95 | * | +-----+-----+ | | ||
96 | * | | | | ||
97 | * | | 18chn | | ||
98 | * | v | | ||
99 | * | +-----------+ | | ||
100 | * | | Mixer | | | ||
101 | * | | Matrix | | | ||
102 | * | | | | | ||
103 | * | | 18x6 Gain | | | ||
104 | * | | stages | | | ||
105 | * | +-----+-----+ | | ||
106 | * | | | | ||
107 | * | | | | ||
108 | * | 18chn | 6chn | 6chn | ||
109 | * v v v | ||
110 | * ========================= | ||
111 | * +---------------+ +--—------------+ | ||
112 | * \ Output Mux / \ Capture Mux / | ||
113 | * +-----+-----+ +-----+-----+ | ||
114 | * | | | ||
115 | * | 6chn | | ||
116 | * v | | ||
117 | * +-------------+ | | ||
118 | * | Master Gain | | | ||
119 | * +------+------+ | | ||
120 | * | | | ||
121 | * | 6chn | 18chn | ||
122 | * | (3 stereo pairs) | | ||
123 | * /--------------\ | | /--------------\ | ||
124 | * | Hardware out |<--/ \-->| ALSA PCM in | | ||
125 | * \--------------/ \--------------/ | ||
126 | * </ditaa> | ||
127 | * | ||
128 | */ | ||
129 | |||
130 | #include <linux/slab.h> | ||
131 | #include <linux/usb.h> | ||
132 | #include <linux/usb/audio-v2.h> | ||
133 | |||
134 | #include <sound/core.h> | ||
135 | #include <sound/control.h> | ||
136 | #include <sound/tlv.h> | ||
137 | |||
138 | #include "usbaudio.h" | ||
139 | #include "mixer.h" | ||
140 | #include "helper.h" | ||
141 | #include "power.h" | ||
142 | |||
143 | #include "mixer_scarlett.h" | ||
144 | |||
145 | /* some gui mixers can't handle negative ctl values */ | ||
146 | #define SND_SCARLETT_LEVEL_BIAS 128 | ||
147 | #define SND_SCARLETT_MATRIX_IN_MAX 18 | ||
148 | #define SND_SCARLETT_CONTROLS_MAX 10 | ||
149 | #define SND_SCARLETT_OFFSETS_MAX 5 | ||
150 | |||
151 | enum { | ||
152 | SCARLETT_OUTPUTS, | ||
153 | SCARLETT_SWITCH_IMPEDANCE, | ||
154 | SCARLETT_SWITCH_PAD, | ||
155 | }; | ||
156 | |||
157 | enum { | ||
158 | SCARLETT_OFFSET_PCM = 0, | ||
159 | SCARLETT_OFFSET_ANALOG = 1, | ||
160 | SCARLETT_OFFSET_SPDIF = 2, | ||
161 | SCARLETT_OFFSET_ADAT = 3, | ||
162 | SCARLETT_OFFSET_MIX = 4, | ||
163 | }; | ||
164 | |||
165 | struct scarlett_mixer_elem_enum_info { | ||
166 | int start; | ||
167 | int len; | ||
168 | int offsets[SND_SCARLETT_OFFSETS_MAX]; | ||
169 | char const * const *names; | ||
170 | }; | ||
171 | |||
172 | struct scarlett_mixer_control { | ||
173 | unsigned char num; | ||
174 | unsigned char type; | ||
175 | const char *name; | ||
176 | }; | ||
177 | |||
178 | struct scarlett_device_info { | ||
179 | int matrix_in; | ||
180 | int matrix_out; | ||
181 | int input_len; | ||
182 | int output_len; | ||
183 | |||
184 | struct scarlett_mixer_elem_enum_info opt_master; | ||
185 | struct scarlett_mixer_elem_enum_info opt_matrix; | ||
186 | |||
187 | /* initial values for matrix mux */ | ||
188 | int matrix_mux_init[SND_SCARLETT_MATRIX_IN_MAX]; | ||
189 | |||
190 | int num_controls; /* number of items in controls */ | ||
191 | const struct scarlett_mixer_control controls[SND_SCARLETT_CONTROLS_MAX]; | ||
192 | }; | ||
193 | |||
194 | /********************** Enum Strings *************************/ | ||
195 | |||
196 | static const struct scarlett_mixer_elem_enum_info opt_pad = { | ||
197 | .start = 0, | ||
198 | .len = 2, | ||
199 | .offsets = {}, | ||
200 | .names = (char const * const []){ | ||
201 | "0dB", "-10dB" | ||
202 | } | ||
203 | }; | ||
204 | |||
205 | static const struct scarlett_mixer_elem_enum_info opt_impedance = { | ||
206 | .start = 0, | ||
207 | .len = 2, | ||
208 | .offsets = {}, | ||
209 | .names = (char const * const []){ | ||
210 | "Line", "Hi-Z" | ||
211 | } | ||
212 | }; | ||
213 | |||
214 | static const struct scarlett_mixer_elem_enum_info opt_clock = { | ||
215 | .start = 1, | ||
216 | .len = 3, | ||
217 | .offsets = {}, | ||
218 | .names = (char const * const []){ | ||
219 | "Internal", "SPDIF", "ADAT" | ||
220 | } | ||
221 | }; | ||
222 | |||
223 | static const struct scarlett_mixer_elem_enum_info opt_sync = { | ||
224 | .start = 0, | ||
225 | .len = 2, | ||
226 | .offsets = {}, | ||
227 | .names = (char const * const []){ | ||
228 | "No Lock", "Locked" | ||
229 | } | ||
230 | }; | ||
231 | |||
232 | static int scarlett_ctl_switch_info(struct snd_kcontrol *kctl, | ||
233 | struct snd_ctl_elem_info *uinfo) | ||
234 | { | ||
235 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
236 | |||
237 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
238 | uinfo->count = elem->channels; | ||
239 | uinfo->value.integer.min = 0; | ||
240 | uinfo->value.integer.max = 1; | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int scarlett_ctl_switch_get(struct snd_kcontrol *kctl, | ||
245 | struct snd_ctl_elem_value *ucontrol) | ||
246 | { | ||
247 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
248 | int i, err, val; | ||
249 | |||
250 | for (i = 0; i < elem->channels; i++) { | ||
251 | err = snd_usb_get_cur_mix_value(elem, i, i, &val); | ||
252 | if (err < 0) | ||
253 | return err; | ||
254 | |||
255 | val = !val; /* invert mute logic for mixer */ | ||
256 | ucontrol->value.integer.value[i] = val; | ||
257 | } | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl, | ||
263 | struct snd_ctl_elem_value *ucontrol) | ||
264 | { | ||
265 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
266 | int i, changed = 0; | ||
267 | int err, oval, val; | ||
268 | |||
269 | for (i = 0; i < elem->channels; i++) { | ||
270 | err = snd_usb_get_cur_mix_value(elem, i, i, &oval); | ||
271 | if (err < 0) | ||
272 | return err; | ||
273 | |||
274 | val = ucontrol->value.integer.value[i]; | ||
275 | val = !val; | ||
276 | if (oval != val) { | ||
277 | err = snd_usb_set_cur_mix_value(elem, i, i, val); | ||
278 | if (err < 0) | ||
279 | return err; | ||
280 | |||
281 | changed = 1; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | return changed; | ||
286 | } | ||
287 | |||
288 | static int scarlett_ctl_resume(struct usb_mixer_elem_list *list) | ||
289 | { | ||
290 | struct usb_mixer_elem_info *elem = | ||
291 | container_of(list, struct usb_mixer_elem_info, head); | ||
292 | int i; | ||
293 | |||
294 | for (i = 0; i < elem->channels; i++) | ||
295 | if (elem->cached & (1 << i)) | ||
296 | snd_usb_set_cur_mix_value(elem, i, i, | ||
297 | elem->cache_val[i]); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int scarlett_ctl_info(struct snd_kcontrol *kctl, | ||
302 | struct snd_ctl_elem_info *uinfo) | ||
303 | { | ||
304 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
305 | |||
306 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
307 | uinfo->count = elem->channels; | ||
308 | uinfo->value.integer.min = 0; | ||
309 | uinfo->value.integer.max = (int)kctl->private_value + | ||
310 | SND_SCARLETT_LEVEL_BIAS; | ||
311 | uinfo->value.integer.step = 1; | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int scarlett_ctl_get(struct snd_kcontrol *kctl, | ||
316 | struct snd_ctl_elem_value *ucontrol) | ||
317 | { | ||
318 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
319 | int i, err, val; | ||
320 | |||
321 | for (i = 0; i < elem->channels; i++) { | ||
322 | err = snd_usb_get_cur_mix_value(elem, i, i, &val); | ||
323 | if (err < 0) | ||
324 | return err; | ||
325 | |||
326 | val = clamp(val / 256, -128, (int)kctl->private_value) + | ||
327 | SND_SCARLETT_LEVEL_BIAS; | ||
328 | ucontrol->value.integer.value[i] = val; | ||
329 | } | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static int scarlett_ctl_put(struct snd_kcontrol *kctl, | ||
335 | struct snd_ctl_elem_value *ucontrol) | ||
336 | { | ||
337 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
338 | int i, changed = 0; | ||
339 | int err, oval, val; | ||
340 | |||
341 | for (i = 0; i < elem->channels; i++) { | ||
342 | err = snd_usb_get_cur_mix_value(elem, i, i, &oval); | ||
343 | if (err < 0) | ||
344 | return err; | ||
345 | |||
346 | val = ucontrol->value.integer.value[i] - | ||
347 | SND_SCARLETT_LEVEL_BIAS; | ||
348 | val = val * 256; | ||
349 | if (oval != val) { | ||
350 | err = snd_usb_set_cur_mix_value(elem, i, i, val); | ||
351 | if (err < 0) | ||
352 | return err; | ||
353 | |||
354 | changed = 1; | ||
355 | } | ||
356 | } | ||
357 | |||
358 | return changed; | ||
359 | } | ||
360 | |||
361 | static void scarlett_generate_name(int i, char *dst, int offsets[]) | ||
362 | { | ||
363 | if (i > offsets[SCARLETT_OFFSET_MIX]) | ||
364 | sprintf(dst, "Mix %c", | ||
365 | 'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1)); | ||
366 | else if (i > offsets[SCARLETT_OFFSET_ADAT]) | ||
367 | sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]); | ||
368 | else if (i > offsets[SCARLETT_OFFSET_SPDIF]) | ||
369 | sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]); | ||
370 | else if (i > offsets[SCARLETT_OFFSET_ANALOG]) | ||
371 | sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]); | ||
372 | else if (i > offsets[SCARLETT_OFFSET_PCM]) | ||
373 | sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]); | ||
374 | else | ||
375 | sprintf(dst, "Off"); | ||
376 | } | ||
377 | |||
378 | static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl, | ||
379 | struct snd_ctl_elem_info *uinfo) | ||
380 | { | ||
381 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
382 | struct scarlett_mixer_elem_enum_info *opt = elem->private_data; | ||
383 | unsigned int items = opt->len; | ||
384 | |||
385 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
386 | uinfo->count = elem->channels; | ||
387 | uinfo->value.enumerated.items = items; | ||
388 | |||
389 | if (uinfo->value.enumerated.item >= items) | ||
390 | uinfo->value.enumerated.item = items - 1; | ||
391 | |||
392 | /* generate name dynamically based on item number and offset info */ | ||
393 | scarlett_generate_name(uinfo->value.enumerated.item, | ||
394 | uinfo->value.enumerated.name, | ||
395 | opt->offsets); | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int scarlett_ctl_enum_info(struct snd_kcontrol *kctl, | ||
401 | struct snd_ctl_elem_info *uinfo) | ||
402 | { | ||
403 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
404 | struct scarlett_mixer_elem_enum_info *opt = elem->private_data; | ||
405 | |||
406 | return snd_ctl_enum_info(uinfo, elem->channels, opt->len, | ||
407 | (const char * const *)opt->names); | ||
408 | } | ||
409 | |||
410 | static int scarlett_ctl_enum_get(struct snd_kcontrol *kctl, | ||
411 | struct snd_ctl_elem_value *ucontrol) | ||
412 | { | ||
413 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
414 | struct scarlett_mixer_elem_enum_info *opt = elem->private_data; | ||
415 | int err, val; | ||
416 | |||
417 | err = snd_usb_get_cur_mix_value(elem, 0, 0, &val); | ||
418 | if (err < 0) | ||
419 | return err; | ||
420 | |||
421 | val = clamp(val - opt->start, 0, opt->len-1); | ||
422 | |||
423 | ucontrol->value.enumerated.item[0] = val; | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl, | ||
429 | struct snd_ctl_elem_value *ucontrol) | ||
430 | { | ||
431 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
432 | struct scarlett_mixer_elem_enum_info *opt = elem->private_data; | ||
433 | int err, oval, val; | ||
434 | |||
435 | err = snd_usb_get_cur_mix_value(elem, 0, 0, &oval); | ||
436 | if (err < 0) | ||
437 | return err; | ||
438 | |||
439 | val = ucontrol->value.integer.value[0]; | ||
440 | val = val + opt->start; | ||
441 | if (val != oval) { | ||
442 | snd_usb_set_cur_mix_value(elem, 0, 0, val); | ||
443 | return 1; | ||
444 | } | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list) | ||
449 | { | ||
450 | struct usb_mixer_elem_info *elem = | ||
451 | container_of(list, struct usb_mixer_elem_info, head); | ||
452 | |||
453 | if (elem->cached) | ||
454 | snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val); | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl, | ||
459 | struct snd_ctl_elem_value *ucontrol) | ||
460 | { | ||
461 | struct usb_mixer_elem_info *elem = kctl->private_data; | ||
462 | struct snd_usb_audio *chip = elem->head.mixer->chip; | ||
463 | unsigned char buf[2 * MAX_CHANNELS] = {0, }; | ||
464 | int wValue = (elem->control << 8) | elem->idx_off; | ||
465 | int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8); | ||
466 | int err; | ||
467 | |||
468 | err = snd_usb_ctl_msg(chip->dev, | ||
469 | usb_rcvctrlpipe(chip->dev, 0), | ||
470 | UAC2_CS_MEM, | ||
471 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | | ||
472 | USB_DIR_IN, wValue, idx, buf, elem->channels); | ||
473 | if (err < 0) | ||
474 | return err; | ||
475 | |||
476 | ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static struct snd_kcontrol_new usb_scarlett_ctl_switch = { | ||
481 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
482 | .name = "", | ||
483 | .info = scarlett_ctl_switch_info, | ||
484 | .get = scarlett_ctl_switch_get, | ||
485 | .put = scarlett_ctl_switch_put, | ||
486 | }; | ||
487 | |||
488 | static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0); | ||
489 | |||
490 | static struct snd_kcontrol_new usb_scarlett_ctl = { | ||
491 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
492 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
493 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
494 | .name = "", | ||
495 | .info = scarlett_ctl_info, | ||
496 | .get = scarlett_ctl_get, | ||
497 | .put = scarlett_ctl_put, | ||
498 | .private_value = 6, /* max value */ | ||
499 | .tlv = { .p = db_scale_scarlett_gain } | ||
500 | }; | ||
501 | |||
502 | static struct snd_kcontrol_new usb_scarlett_ctl_master = { | ||
503 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
504 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
505 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
506 | .name = "", | ||
507 | .info = scarlett_ctl_info, | ||
508 | .get = scarlett_ctl_get, | ||
509 | .put = scarlett_ctl_put, | ||
510 | .private_value = 6, /* max value */ | ||
511 | .tlv = { .p = db_scale_scarlett_gain } | ||
512 | }; | ||
513 | |||
514 | static struct snd_kcontrol_new usb_scarlett_ctl_enum = { | ||
515 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
516 | .name = "", | ||
517 | .info = scarlett_ctl_enum_info, | ||
518 | .get = scarlett_ctl_enum_get, | ||
519 | .put = scarlett_ctl_enum_put, | ||
520 | }; | ||
521 | |||
522 | static struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = { | ||
523 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
524 | .name = "", | ||
525 | .info = scarlett_ctl_enum_dynamic_info, | ||
526 | .get = scarlett_ctl_enum_get, | ||
527 | .put = scarlett_ctl_enum_put, | ||
528 | }; | ||
529 | |||
530 | static struct snd_kcontrol_new usb_scarlett_ctl_sync = { | ||
531 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
532 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
533 | .name = "", | ||
534 | .info = scarlett_ctl_enum_info, | ||
535 | .get = scarlett_ctl_meter_get, | ||
536 | }; | ||
537 | |||
538 | static int add_new_ctl(struct usb_mixer_interface *mixer, | ||
539 | const struct snd_kcontrol_new *ncontrol, | ||
540 | usb_mixer_elem_resume_func_t resume, | ||
541 | int index, int offset, int num, | ||
542 | int val_type, int channels, const char *name, | ||
543 | const struct scarlett_mixer_elem_enum_info *opt, | ||
544 | struct usb_mixer_elem_info **elem_ret | ||
545 | ) | ||
546 | { | ||
547 | struct snd_kcontrol *kctl; | ||
548 | struct usb_mixer_elem_info *elem; | ||
549 | int err; | ||
550 | |||
551 | elem = kzalloc(sizeof(*elem), GFP_KERNEL); | ||
552 | if (!elem) | ||
553 | return -ENOMEM; | ||
554 | |||
555 | elem->head.mixer = mixer; | ||
556 | elem->head.resume = resume; | ||
557 | elem->control = offset; | ||
558 | elem->idx_off = num; | ||
559 | elem->head.id = index; | ||
560 | elem->val_type = val_type; | ||
561 | |||
562 | elem->channels = channels; | ||
563 | |||
564 | /* add scarlett_mixer_elem_enum_info struct */ | ||
565 | elem->private_data = (void *)opt; | ||
566 | |||
567 | kctl = snd_ctl_new1(ncontrol, elem); | ||
568 | if (!kctl) { | ||
569 | kfree(elem); | ||
570 | return -ENOMEM; | ||
571 | } | ||
572 | kctl->private_free = snd_usb_mixer_elem_free; | ||
573 | |||
574 | strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); | ||
575 | |||
576 | err = snd_usb_mixer_add_control(&elem->head, kctl); | ||
577 | if (err < 0) | ||
578 | return err; | ||
579 | |||
580 | if (elem_ret) | ||
581 | *elem_ret = elem; | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int add_output_ctls(struct usb_mixer_interface *mixer, | ||
587 | int index, const char *name, | ||
588 | const struct scarlett_device_info *info) | ||
589 | { | ||
590 | int err; | ||
591 | char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; | ||
592 | struct usb_mixer_elem_info *elem; | ||
593 | |||
594 | /* Add mute switch */ | ||
595 | snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch", | ||
596 | index + 1, name); | ||
597 | err = add_new_ctl(mixer, &usb_scarlett_ctl_switch, | ||
598 | scarlett_ctl_resume, 0x0a, 0x01, | ||
599 | 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem); | ||
600 | if (err < 0) | ||
601 | return err; | ||
602 | |||
603 | /* Add volume control and initialize to 0 */ | ||
604 | snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume", | ||
605 | index + 1, name); | ||
606 | err = add_new_ctl(mixer, &usb_scarlett_ctl_master, | ||
607 | scarlett_ctl_resume, 0x0a, 0x02, | ||
608 | 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem); | ||
609 | if (err < 0) | ||
610 | return err; | ||
611 | |||
612 | /* Add L channel source playback enumeration */ | ||
613 | snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum", | ||
614 | index + 1, name); | ||
615 | err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, | ||
616 | scarlett_ctl_enum_resume, 0x33, 0x00, | ||
617 | 2*index, USB_MIXER_S16, 1, mx, &info->opt_master, | ||
618 | &elem); | ||
619 | if (err < 0) | ||
620 | return err; | ||
621 | |||
622 | /* Add R channel source playback enumeration */ | ||
623 | snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum", | ||
624 | index + 1, name); | ||
625 | err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, | ||
626 | scarlett_ctl_enum_resume, 0x33, 0x00, | ||
627 | 2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master, | ||
628 | &elem); | ||
629 | if (err < 0) | ||
630 | return err; | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | /********************** device-specific config *************************/ | ||
636 | |||
637 | /* untested... */ | ||
638 | static struct scarlett_device_info s6i6_info = { | ||
639 | .matrix_in = 18, | ||
640 | .matrix_out = 8, | ||
641 | .input_len = 6, | ||
642 | .output_len = 6, | ||
643 | |||
644 | .opt_master = { | ||
645 | .start = -1, | ||
646 | .len = 27, | ||
647 | .offsets = {0, 12, 16, 18, 18}, | ||
648 | .names = NULL | ||
649 | }, | ||
650 | |||
651 | .opt_matrix = { | ||
652 | .start = -1, | ||
653 | .len = 19, | ||
654 | .offsets = {0, 12, 16, 18, 18}, | ||
655 | .names = NULL | ||
656 | }, | ||
657 | |||
658 | .num_controls = 0, | ||
659 | .controls = { | ||
660 | { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" }, | ||
661 | { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" }, | ||
662 | { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" }, | ||
663 | { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
664 | { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
665 | { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
666 | { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
667 | { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
668 | { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
669 | }, | ||
670 | |||
671 | .matrix_mux_init = { | ||
672 | 12, 13, 14, 15, /* Analog -> 1..4 */ | ||
673 | 16, 17, /* SPDIF -> 5,6 */ | ||
674 | 0, 1, 2, 3, 4, 5, 6, 7, /* PCM[1..12] -> 7..18 */ | ||
675 | 8, 9, 10, 11 | ||
676 | } | ||
677 | }; | ||
678 | |||
679 | /* untested... */ | ||
680 | static struct scarlett_device_info s8i6_info = { | ||
681 | .matrix_in = 18, | ||
682 | .matrix_out = 6, | ||
683 | .input_len = 8, | ||
684 | .output_len = 6, | ||
685 | |||
686 | .opt_master = { | ||
687 | .start = -1, | ||
688 | .len = 25, | ||
689 | .offsets = {0, 12, 16, 18, 18}, | ||
690 | .names = NULL | ||
691 | }, | ||
692 | |||
693 | .opt_matrix = { | ||
694 | .start = -1, | ||
695 | .len = 19, | ||
696 | .offsets = {0, 12, 16, 18, 18}, | ||
697 | .names = NULL | ||
698 | }, | ||
699 | |||
700 | .num_controls = 7, | ||
701 | .controls = { | ||
702 | { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" }, | ||
703 | { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" }, | ||
704 | { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" }, | ||
705 | { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
706 | { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
707 | { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
708 | { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
709 | }, | ||
710 | |||
711 | .matrix_mux_init = { | ||
712 | 12, 13, 14, 15, /* Analog -> 1..4 */ | ||
713 | 16, 17, /* SPDIF -> 5,6 */ | ||
714 | 0, 1, 2, 3, 4, 5, 6, 7, /* PCM[1..12] -> 7..18 */ | ||
715 | 8, 9, 10, 11 | ||
716 | } | ||
717 | }; | ||
718 | |||
719 | static struct scarlett_device_info s18i6_info = { | ||
720 | .matrix_in = 18, | ||
721 | .matrix_out = 6, | ||
722 | .input_len = 18, | ||
723 | .output_len = 6, | ||
724 | |||
725 | .opt_master = { | ||
726 | .start = -1, | ||
727 | .len = 31, | ||
728 | .offsets = {0, 6, 14, 16, 24}, | ||
729 | .names = NULL, | ||
730 | }, | ||
731 | |||
732 | .opt_matrix = { | ||
733 | .start = -1, | ||
734 | .len = 25, | ||
735 | .offsets = {0, 6, 14, 16, 24}, | ||
736 | .names = NULL, | ||
737 | }, | ||
738 | |||
739 | .num_controls = 5, | ||
740 | .controls = { | ||
741 | { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" }, | ||
742 | { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" }, | ||
743 | { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" }, | ||
744 | { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
745 | { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
746 | }, | ||
747 | |||
748 | .matrix_mux_init = { | ||
749 | 6, 7, 8, 9, 10, 11, 12, 13, /* Analog -> 1..8 */ | ||
750 | 16, 17, 18, 19, 20, 21, /* ADAT[1..6] -> 9..14 */ | ||
751 | 14, 15, /* SPDIF -> 15,16 */ | ||
752 | 0, 1 /* PCM[1,2] -> 17,18 */ | ||
753 | } | ||
754 | }; | ||
755 | |||
756 | static struct scarlett_device_info s18i8_info = { | ||
757 | .matrix_in = 18, | ||
758 | .matrix_out = 8, | ||
759 | .input_len = 18, | ||
760 | .output_len = 8, | ||
761 | |||
762 | .opt_master = { | ||
763 | .start = -1, | ||
764 | .len = 35, | ||
765 | .offsets = {0, 8, 16, 18, 26}, | ||
766 | .names = NULL | ||
767 | }, | ||
768 | |||
769 | .opt_matrix = { | ||
770 | .start = -1, | ||
771 | .len = 27, | ||
772 | .offsets = {0, 8, 16, 18, 26}, | ||
773 | .names = NULL | ||
774 | }, | ||
775 | |||
776 | .num_controls = 10, | ||
777 | .controls = { | ||
778 | { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" }, | ||
779 | { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" }, | ||
780 | { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" }, | ||
781 | { .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" }, | ||
782 | { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
783 | { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
784 | { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
785 | { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
786 | { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
787 | { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
788 | }, | ||
789 | |||
790 | .matrix_mux_init = { | ||
791 | 8, 9, 10, 11, 12, 13, 14, 15, /* Analog -> 1..8 */ | ||
792 | 18, 19, 20, 21, 22, 23, /* ADAT[1..6] -> 9..14 */ | ||
793 | 16, 17, /* SPDIF -> 15,16 */ | ||
794 | 0, 1 /* PCM[1,2] -> 17,18 */ | ||
795 | } | ||
796 | }; | ||
797 | |||
798 | static struct scarlett_device_info s18i20_info = { | ||
799 | .matrix_in = 18, | ||
800 | .matrix_out = 8, | ||
801 | .input_len = 18, | ||
802 | .output_len = 20, | ||
803 | |||
804 | .opt_master = { | ||
805 | .start = -1, | ||
806 | .len = 47, | ||
807 | .offsets = {0, 20, 28, 30, 38}, | ||
808 | .names = NULL | ||
809 | }, | ||
810 | |||
811 | .opt_matrix = { | ||
812 | .start = -1, | ||
813 | .len = 39, | ||
814 | .offsets = {0, 20, 28, 30, 38}, | ||
815 | .names = NULL | ||
816 | }, | ||
817 | |||
818 | .num_controls = 10, | ||
819 | .controls = { | ||
820 | { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" }, | ||
821 | { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" }, | ||
822 | { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" }, | ||
823 | { .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" }, | ||
824 | { .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" }, | ||
825 | { .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" }, | ||
826 | { .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" }, | ||
827 | { .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" }, | ||
828 | { .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" }, | ||
829 | { .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" }, | ||
830 | /*{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
831 | { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
832 | { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL}, | ||
833 | { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
834 | { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL}, | ||
835 | { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},*/ | ||
836 | }, | ||
837 | |||
838 | .matrix_mux_init = { | ||
839 | 20, 21, 22, 23, 24, 25, 26, 27, /* Analog -> 1..8 */ | ||
840 | 30, 31, 32, 33, 34, 35, /* ADAT[1..6] -> 9..14 */ | ||
841 | 28, 29, /* SPDIF -> 15,16 */ | ||
842 | 0, 1 /* PCM[1,2] -> 17,18 */ | ||
843 | } | ||
844 | }; | ||
845 | |||
846 | |||
847 | static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer, | ||
848 | struct scarlett_device_info *info) | ||
849 | { | ||
850 | int i, err; | ||
851 | char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; | ||
852 | const struct scarlett_mixer_control *ctl; | ||
853 | struct usb_mixer_elem_info *elem; | ||
854 | |||
855 | /* create master switch and playback volume */ | ||
856 | err = add_new_ctl(mixer, &usb_scarlett_ctl_switch, | ||
857 | scarlett_ctl_resume, 0x0a, 0x01, 0, | ||
858 | USB_MIXER_S16, 1, "Master Playback Switch", NULL, | ||
859 | &elem); | ||
860 | if (err < 0) | ||
861 | return err; | ||
862 | |||
863 | err = add_new_ctl(mixer, &usb_scarlett_ctl_master, | ||
864 | scarlett_ctl_resume, 0x0a, 0x02, 0, | ||
865 | USB_MIXER_S16, 1, "Master Playback Volume", NULL, | ||
866 | &elem); | ||
867 | if (err < 0) | ||
868 | return err; | ||
869 | |||
870 | /* iterate through controls in info struct and create each one */ | ||
871 | for (i = 0; i < info->num_controls; i++) { | ||
872 | ctl = &info->controls[i]; | ||
873 | |||
874 | switch (ctl->type) { | ||
875 | case SCARLETT_OUTPUTS: | ||
876 | err = add_output_ctls(mixer, ctl->num, ctl->name, info); | ||
877 | if (err < 0) | ||
878 | return err; | ||
879 | break; | ||
880 | case SCARLETT_SWITCH_IMPEDANCE: | ||
881 | sprintf(mx, "Input %d Impedance Switch", ctl->num); | ||
882 | err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, | ||
883 | scarlett_ctl_enum_resume, 0x01, | ||
884 | 0x09, ctl->num, USB_MIXER_S16, 1, mx, | ||
885 | &opt_impedance, &elem); | ||
886 | if (err < 0) | ||
887 | return err; | ||
888 | break; | ||
889 | case SCARLETT_SWITCH_PAD: | ||
890 | sprintf(mx, "Input %d Pad Switch", ctl->num); | ||
891 | err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, | ||
892 | scarlett_ctl_enum_resume, 0x01, | ||
893 | 0x0b, ctl->num, USB_MIXER_S16, 1, mx, | ||
894 | &opt_pad, &elem); | ||
895 | if (err < 0) | ||
896 | return err; | ||
897 | break; | ||
898 | } | ||
899 | } | ||
900 | |||
901 | return 0; | ||
902 | } | ||
903 | |||
904 | /* | ||
905 | * Create and initialize a mixer for the Focusrite(R) Scarlett | ||
906 | */ | ||
907 | int snd_scarlett_controls_create(struct usb_mixer_interface *mixer) | ||
908 | { | ||
909 | int err, i, o; | ||
910 | char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; | ||
911 | struct scarlett_device_info *info; | ||
912 | struct usb_mixer_elem_info *elem; | ||
913 | static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' }; | ||
914 | |||
915 | /* only use UAC_VERSION_2 */ | ||
916 | if (!mixer->protocol) | ||
917 | return 0; | ||
918 | |||
919 | switch (mixer->chip->usb_id) { | ||
920 | case USB_ID(0x1235, 0x8012): | ||
921 | info = &s6i6_info; | ||
922 | break; | ||
923 | case USB_ID(0x1235, 0x8002): | ||
924 | info = &s8i6_info; | ||
925 | break; | ||
926 | case USB_ID(0x1235, 0x8004): | ||
927 | info = &s18i6_info; | ||
928 | break; | ||
929 | case USB_ID(0x1235, 0x8014): | ||
930 | info = &s18i8_info; | ||
931 | break; | ||
932 | case USB_ID(0x1235, 0x800c): | ||
933 | info = &s18i20_info; | ||
934 | break; | ||
935 | default: /* device not (yet) supported */ | ||
936 | return -EINVAL; | ||
937 | } | ||
938 | |||
939 | /* generic function to create controls */ | ||
940 | err = scarlett_controls_create_generic(mixer, info); | ||
941 | if (err < 0) | ||
942 | return err; | ||
943 | |||
944 | /* setup matrix controls */ | ||
945 | for (i = 0; i < info->matrix_in; i++) { | ||
946 | snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route", | ||
947 | i+1); | ||
948 | err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, | ||
949 | scarlett_ctl_enum_resume, 0x32, | ||
950 | 0x06, i, USB_MIXER_S16, 1, mx, | ||
951 | &info->opt_matrix, &elem); | ||
952 | if (err < 0) | ||
953 | return err; | ||
954 | |||
955 | for (o = 0; o < info->matrix_out; o++) { | ||
956 | sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1, | ||
957 | o+'A'); | ||
958 | err = add_new_ctl(mixer, &usb_scarlett_ctl, | ||
959 | scarlett_ctl_resume, 0x3c, 0x00, | ||
960 | (i << 3) + (o & 0x07), USB_MIXER_S16, | ||
961 | 1, mx, NULL, &elem); | ||
962 | if (err < 0) | ||
963 | return err; | ||
964 | |||
965 | } | ||
966 | } | ||
967 | |||
968 | for (i = 0; i < info->input_len; i++) { | ||
969 | snprintf(mx, sizeof(mx), "Input Source %02d Capture Route", | ||
970 | i+1); | ||
971 | err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, | ||
972 | scarlett_ctl_enum_resume, 0x34, | ||
973 | 0x00, i, USB_MIXER_S16, 1, mx, | ||
974 | &info->opt_master, &elem); | ||
975 | if (err < 0) | ||
976 | return err; | ||
977 | } | ||
978 | |||
979 | /* val_len == 1 needed here */ | ||
980 | err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, | ||
981 | scarlett_ctl_enum_resume, 0x28, 0x01, 0, | ||
982 | USB_MIXER_U8, 1, "Sample Clock Source", | ||
983 | &opt_clock, &elem); | ||
984 | if (err < 0) | ||
985 | return err; | ||
986 | |||
987 | /* val_len == 1 and UAC2_CS_MEM */ | ||
988 | err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2, | ||
989 | USB_MIXER_U8, 1, "Sample Clock Sync Status", | ||
990 | &opt_sync, &elem); | ||
991 | if (err < 0) | ||
992 | return err; | ||
993 | |||
994 | /* initialize sampling rate to 48000 */ | ||
995 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
996 | usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR, | ||
997 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | | ||
998 | USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) | | ||
999 | (0x29 << 8), sample_rate_buffer, 4); | ||
1000 | if (err < 0) | ||
1001 | return err; | ||
1002 | |||
1003 | return err; | ||
1004 | } | ||
diff --git a/sound/usb/mixer_scarlett.h b/sound/usb/mixer_scarlett.h new file mode 100644 index 000000000000..19c592ab0332 --- /dev/null +++ b/sound/usb/mixer_scarlett.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __USB_MIXER_SCARLETT_H | ||
2 | #define __USB_MIXER_SCARLETT_H | ||
3 | |||
4 | int snd_scarlett_controls_create(struct usb_mixer_interface *mixer); | ||
5 | |||
6 | #endif /* __USB_MIXER_SCARLETT_H */ | ||
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index c62a1659106d..0d8aba5fe1a8 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -482,6 +482,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
482 | /* set interface */ | 482 | /* set interface */ |
483 | if (subs->interface != fmt->iface || | 483 | if (subs->interface != fmt->iface || |
484 | subs->altset_idx != fmt->altset_idx) { | 484 | subs->altset_idx != fmt->altset_idx) { |
485 | |||
486 | err = snd_usb_select_mode_quirk(subs, fmt); | ||
487 | if (err < 0) | ||
488 | return -EIO; | ||
489 | |||
485 | err = usb_set_interface(dev, fmt->iface, fmt->altsetting); | 490 | err = usb_set_interface(dev, fmt->iface, fmt->altsetting); |
486 | if (err < 0) { | 491 | if (err < 0) { |
487 | dev_err(&dev->dev, | 492 | dev_err(&dev->dev, |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c657752a420c..73d2ba47cc31 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -2667,57 +2667,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2667 | .type = QUIRK_MIDI_NOVATION | 2667 | .type = QUIRK_MIDI_NOVATION |
2668 | } | 2668 | } |
2669 | }, | 2669 | }, |
2670 | { | ||
2671 | /* | ||
2672 | * Focusrite Scarlett 18i6 | ||
2673 | * | ||
2674 | * Avoid mixer creation, which otherwise fails because some of | ||
2675 | * the interface descriptor subtypes for interface 0 are | ||
2676 | * unknown. That should be fixed or worked-around but this at | ||
2677 | * least allows the device to be used successfully with a DAW | ||
2678 | * and an external mixer. See comments below about other | ||
2679 | * ignored interfaces. | ||
2680 | */ | ||
2681 | USB_DEVICE(0x1235, 0x8004), | ||
2682 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
2683 | .vendor_name = "Focusrite", | ||
2684 | .product_name = "Scarlett 18i6", | ||
2685 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2686 | .type = QUIRK_COMPOSITE, | ||
2687 | .data = & (const struct snd_usb_audio_quirk[]) { | ||
2688 | { | ||
2689 | /* InterfaceSubClass 1 (Control Device) */ | ||
2690 | .ifnum = 0, | ||
2691 | .type = QUIRK_IGNORE_INTERFACE | ||
2692 | }, | ||
2693 | { | ||
2694 | .ifnum = 1, | ||
2695 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
2696 | }, | ||
2697 | { | ||
2698 | .ifnum = 2, | ||
2699 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
2700 | }, | ||
2701 | { | ||
2702 | /* InterfaceSubClass 1 (Control Device) */ | ||
2703 | .ifnum = 3, | ||
2704 | .type = QUIRK_IGNORE_INTERFACE | ||
2705 | }, | ||
2706 | { | ||
2707 | .ifnum = 4, | ||
2708 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
2709 | }, | ||
2710 | { | ||
2711 | /* InterfaceSubClass 1 (Device Firmware Update) */ | ||
2712 | .ifnum = 5, | ||
2713 | .type = QUIRK_IGNORE_INTERFACE | ||
2714 | }, | ||
2715 | { | ||
2716 | .ifnum = -1 | ||
2717 | } | ||
2718 | } | ||
2719 | } | ||
2720 | }, | ||
2721 | 2670 | ||
2722 | /* Access Music devices */ | 2671 | /* Access Music devices */ |
2723 | { | 2672 | { |
@@ -2944,7 +2893,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2944 | .data = (const struct snd_usb_audio_quirk[]){ | 2893 | .data = (const struct snd_usb_audio_quirk[]){ |
2945 | { | 2894 | { |
2946 | .ifnum = 0, | 2895 | .ifnum = 0, |
2947 | .type = QUIRK_IGNORE_INTERFACE, | 2896 | .type = QUIRK_AUDIO_STANDARD_MIXER, |
2948 | }, | 2897 | }, |
2949 | { | 2898 | { |
2950 | .ifnum = 1, | 2899 | .ifnum = 1, |
@@ -2955,16 +2904,40 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2955 | .iface = 1, | 2904 | .iface = 1, |
2956 | .altsetting = 1, | 2905 | .altsetting = 1, |
2957 | .altset_idx = 1, | 2906 | .altset_idx = 1, |
2958 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | 2907 | .attributes = 0x4, |
2959 | .endpoint = 0x02, | 2908 | .endpoint = 0x02, |
2960 | .ep_attr = 0x01, | 2909 | .ep_attr = USB_ENDPOINT_XFER_ISOC | |
2961 | .rates = SNDRV_PCM_RATE_44100 | | 2910 | USB_ENDPOINT_SYNC_SYNC, |
2962 | SNDRV_PCM_RATE_48000, | 2911 | .maxpacksize = 0x130, |
2963 | .rate_min = 44100, | 2912 | .rates = SNDRV_PCM_RATE_48000, |
2913 | .rate_min = 48000, | ||
2964 | .rate_max = 48000, | 2914 | .rate_max = 48000, |
2965 | .nr_rates = 2, | 2915 | .nr_rates = 1, |
2966 | .rate_table = (unsigned int[]) { | 2916 | .rate_table = (unsigned int[]) { |
2967 | 44100, 48000 | 2917 | 48000 |
2918 | } | ||
2919 | } | ||
2920 | }, | ||
2921 | { | ||
2922 | .ifnum = 1, | ||
2923 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2924 | .data = &(const struct audioformat) { | ||
2925 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | ||
2926 | .channels = 2, | ||
2927 | .iface = 1, | ||
2928 | .altsetting = 1, | ||
2929 | .altset_idx = 1, | ||
2930 | .attributes = 0x4, | ||
2931 | .endpoint = 0x81, | ||
2932 | .ep_attr = USB_ENDPOINT_XFER_ISOC | | ||
2933 | USB_ENDPOINT_SYNC_ASYNC, | ||
2934 | .maxpacksize = 0x130, | ||
2935 | .rates = SNDRV_PCM_RATE_48000, | ||
2936 | .rate_min = 48000, | ||
2937 | .rate_max = 48000, | ||
2938 | .nr_rates = 1, | ||
2939 | .rate_table = (unsigned int[]) { | ||
2940 | 48000 | ||
2968 | } | 2941 | } |
2969 | } | 2942 | } |
2970 | }, | 2943 | }, |
@@ -2972,7 +2945,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2972 | .ifnum = -1 | 2945 | .ifnum = -1 |
2973 | } | 2946 | } |
2974 | } | 2947 | } |
2975 | |||
2976 | } | 2948 | } |
2977 | }, | 2949 | }, |
2978 | 2950 | ||
@@ -3203,6 +3175,46 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
3203 | 3175 | ||
3204 | { | 3176 | { |
3205 | /* | 3177 | /* |
3178 | * ZOOM R16/24 in audio interface mode. | ||
3179 | * Mixer descriptors are garbage, further quirks will be needed | ||
3180 | * to make any of it functional, thus disabled for now. | ||
3181 | * Playback stream appears to start and run fine but no sound | ||
3182 | * is produced, so also disabled for now. | ||
3183 | */ | ||
3184 | USB_DEVICE(0x1686, 0x00dd), | ||
3185 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
3186 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3187 | .type = QUIRK_COMPOSITE, | ||
3188 | .data = (const struct snd_usb_audio_quirk[]) { | ||
3189 | { | ||
3190 | /* Mixer */ | ||
3191 | .ifnum = 0, | ||
3192 | .type = QUIRK_IGNORE_INTERFACE, | ||
3193 | }, | ||
3194 | { | ||
3195 | /* Playback */ | ||
3196 | .ifnum = 1, | ||
3197 | .type = QUIRK_IGNORE_INTERFACE, | ||
3198 | }, | ||
3199 | { | ||
3200 | /* Capture */ | ||
3201 | .ifnum = 2, | ||
3202 | .type = QUIRK_AUDIO_STANDARD_INTERFACE, | ||
3203 | }, | ||
3204 | { | ||
3205 | /* Midi */ | ||
3206 | .ifnum = 3, | ||
3207 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
3208 | }, | ||
3209 | { | ||
3210 | .ifnum = -1 | ||
3211 | }, | ||
3212 | } | ||
3213 | } | ||
3214 | }, | ||
3215 | |||
3216 | { | ||
3217 | /* | ||
3206 | * Some USB MIDI devices don't have an audio control interface, | 3218 | * Some USB MIDI devices don't have an audio control interface, |
3207 | * so we have to grab MIDI streaming interfaces here. | 3219 | * so we have to grab MIDI streaming interfaces here. |
3208 | */ | 3220 | */ |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 60dfe0d28771..4dbfb3d18ee2 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -43,12 +43,13 @@ | |||
43 | static int create_composite_quirk(struct snd_usb_audio *chip, | 43 | static int create_composite_quirk(struct snd_usb_audio *chip, |
44 | struct usb_interface *iface, | 44 | struct usb_interface *iface, |
45 | struct usb_driver *driver, | 45 | struct usb_driver *driver, |
46 | const struct snd_usb_audio_quirk *quirk) | 46 | const struct snd_usb_audio_quirk *quirk_comp) |
47 | { | 47 | { |
48 | int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber; | 48 | int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber; |
49 | const struct snd_usb_audio_quirk *quirk; | ||
49 | int err; | 50 | int err; |
50 | 51 | ||
51 | for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { | 52 | for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) { |
52 | iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); | 53 | iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); |
53 | if (!iface) | 54 | if (!iface) |
54 | continue; | 55 | continue; |
@@ -58,9 +59,17 @@ static int create_composite_quirk(struct snd_usb_audio *chip, | |||
58 | err = snd_usb_create_quirk(chip, iface, driver, quirk); | 59 | err = snd_usb_create_quirk(chip, iface, driver, quirk); |
59 | if (err < 0) | 60 | if (err < 0) |
60 | return err; | 61 | return err; |
61 | if (quirk->ifnum != probed_ifnum) | 62 | } |
63 | |||
64 | for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) { | ||
65 | iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); | ||
66 | if (!iface) | ||
67 | continue; | ||
68 | if (quirk->ifnum != probed_ifnum && | ||
69 | !usb_interface_claimed(iface)) | ||
62 | usb_driver_claim_interface(driver, iface, (void *)-1L); | 70 | usb_driver_claim_interface(driver, iface, (void *)-1L); |
63 | } | 71 | } |
72 | |||
64 | return 0; | 73 | return 0; |
65 | } | 74 | } |
66 | 75 | ||
@@ -1102,6 +1111,44 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, | |||
1102 | } | 1111 | } |
1103 | } | 1112 | } |
1104 | 1113 | ||
1114 | |||
1115 | /* Marantz/Denon USB DACs need a vendor cmd to switch | ||
1116 | * between PCM and native DSD mode | ||
1117 | */ | ||
1118 | int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, | ||
1119 | struct audioformat *fmt) | ||
1120 | { | ||
1121 | struct usb_device *dev = subs->dev; | ||
1122 | int err; | ||
1123 | |||
1124 | switch (subs->stream->chip->usb_id) { | ||
1125 | case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ | ||
1126 | case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ | ||
1127 | |||
1128 | /* First switch to alt set 0, otherwise the mode switch cmd | ||
1129 | * will not be accepted by the DAC | ||
1130 | */ | ||
1131 | err = usb_set_interface(dev, fmt->iface, 0); | ||
1132 | if (err < 0) | ||
1133 | return err; | ||
1134 | |||
1135 | mdelay(20); /* Delay needed after setting the interface */ | ||
1136 | |||
1137 | switch (fmt->altsetting) { | ||
1138 | case 2: /* DSD mode requested */ | ||
1139 | case 1: /* PCM mode requested */ | ||
1140 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, | ||
1141 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | ||
1142 | fmt->altsetting - 1, 1, NULL, 0); | ||
1143 | if (err < 0) | ||
1144 | return err; | ||
1145 | break; | ||
1146 | } | ||
1147 | mdelay(20); | ||
1148 | } | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1105 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | 1152 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) |
1106 | { | 1153 | { |
1107 | /* | 1154 | /* |
@@ -1160,6 +1207,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | |||
1160 | break; | 1207 | break; |
1161 | } | 1208 | } |
1162 | } | 1209 | } |
1210 | |||
1211 | /* Zoom R16/24 needs a tiny delay here, otherwise requests like | ||
1212 | * get/set frequency return as failed despite actually succeeding. | ||
1213 | */ | ||
1214 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1686) && | ||
1215 | (le16_to_cpu(dev->descriptor.idProduct) == 0x00dd) && | ||
1216 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | ||
1217 | mdelay(1); | ||
1163 | } | 1218 | } |
1164 | 1219 | ||
1165 | /* | 1220 | /* |
@@ -1204,5 +1259,16 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | |||
1204 | break; | 1259 | break; |
1205 | } | 1260 | } |
1206 | 1261 | ||
1262 | /* Denon/Marantz devices with USB DAC functionality */ | ||
1263 | switch (chip->usb_id) { | ||
1264 | case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ | ||
1265 | case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ | ||
1266 | if (fp->altsetting == 2) | ||
1267 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; | ||
1268 | break; | ||
1269 | default: | ||
1270 | break; | ||
1271 | } | ||
1272 | |||
1207 | return 0; | 1273 | return 0; |
1208 | } | 1274 | } |
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 665e972a1b40..1b862386577d 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h | |||
@@ -31,6 +31,9 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | |||
31 | __u8 request, __u8 requesttype, __u16 value, | 31 | __u8 request, __u8 requesttype, __u16 value, |
32 | __u16 index, void *data, __u16 size); | 32 | __u16 index, void *data, __u16 size); |
33 | 33 | ||
34 | int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, | ||
35 | struct audioformat *fmt); | ||
36 | |||
34 | u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | 37 | u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, |
35 | struct audioformat *fp, | 38 | struct audioformat *fp, |
36 | unsigned int sample_bytes); | 39 | unsigned int sample_bytes); |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index a63330dd1407..61d5dc2a3421 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -272,13 +272,8 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y) | |||
272 | for (s = 0; s < 4; s++) { | 272 | for (s = 0; s < 4; s++) { |
273 | struct snd_usX2Y_substream *subs = usX2Y->subs[s]; | 273 | struct snd_usX2Y_substream *subs = usX2Y->subs[s]; |
274 | if (subs) { | 274 | if (subs) { |
275 | if (atomic_read(&subs->state) >= state_PRERUNNING) { | 275 | if (atomic_read(&subs->state) >= state_PRERUNNING) |
276 | unsigned long flags; | 276 | snd_pcm_stop_xrun(subs->pcm_substream); |
277 | |||
278 | snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags); | ||
279 | snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); | ||
280 | snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags); | ||
281 | } | ||
282 | for (u = 0; u < NRURBS; u++) { | 277 | for (u = 0; u < NRURBS; u++) { |
283 | struct urb *urb = subs->urb[u]; | 278 | struct urb *urb = subs->urb[u]; |
284 | if (NULL != urb) | 279 | if (NULL != urb) |
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 3aaca49de325..aacdb59f30de 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -1933,7 +1933,7 @@ out: | |||
1933 | 1933 | ||
1934 | int kvm_vgic_create(struct kvm *kvm) | 1934 | int kvm_vgic_create(struct kvm *kvm) |
1935 | { | 1935 | { |
1936 | int i, vcpu_lock_idx = -1, ret = 0; | 1936 | int i, vcpu_lock_idx = -1, ret; |
1937 | struct kvm_vcpu *vcpu; | 1937 | struct kvm_vcpu *vcpu; |
1938 | 1938 | ||
1939 | mutex_lock(&kvm->lock); | 1939 | mutex_lock(&kvm->lock); |
@@ -1948,6 +1948,7 @@ int kvm_vgic_create(struct kvm *kvm) | |||
1948 | * vcpu->mutex. By grabbing the vcpu->mutex of all VCPUs we ensure | 1948 | * vcpu->mutex. By grabbing the vcpu->mutex of all VCPUs we ensure |
1949 | * that no other VCPUs are run while we create the vgic. | 1949 | * that no other VCPUs are run while we create the vgic. |
1950 | */ | 1950 | */ |
1951 | ret = -EBUSY; | ||
1951 | kvm_for_each_vcpu(i, vcpu, kvm) { | 1952 | kvm_for_each_vcpu(i, vcpu, kvm) { |
1952 | if (!mutex_trylock(&vcpu->mutex)) | 1953 | if (!mutex_trylock(&vcpu->mutex)) |
1953 | goto out_unlock; | 1954 | goto out_unlock; |
@@ -1955,11 +1956,10 @@ int kvm_vgic_create(struct kvm *kvm) | |||
1955 | } | 1956 | } |
1956 | 1957 | ||
1957 | kvm_for_each_vcpu(i, vcpu, kvm) { | 1958 | kvm_for_each_vcpu(i, vcpu, kvm) { |
1958 | if (vcpu->arch.has_run_once) { | 1959 | if (vcpu->arch.has_run_once) |
1959 | ret = -EBUSY; | ||
1960 | goto out_unlock; | 1960 | goto out_unlock; |
1961 | } | ||
1962 | } | 1961 | } |
1962 | ret = 0; | ||
1963 | 1963 | ||
1964 | spin_lock_init(&kvm->arch.vgic.lock); | 1964 | spin_lock_init(&kvm->arch.vgic.lock); |
1965 | kvm->arch.vgic.in_kernel = true; | 1965 | kvm->arch.vgic.in_kernel = true; |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 25ffac9e947d..3cee7b167052 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -107,10 +107,10 @@ EXPORT_SYMBOL_GPL(kvm_rebooting); | |||
107 | 107 | ||
108 | static bool largepages_enabled = true; | 108 | static bool largepages_enabled = true; |
109 | 109 | ||
110 | bool kvm_is_mmio_pfn(pfn_t pfn) | 110 | bool kvm_is_reserved_pfn(pfn_t pfn) |
111 | { | 111 | { |
112 | if (pfn_valid(pfn)) | 112 | if (pfn_valid(pfn)) |
113 | return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn)); | 113 | return PageReserved(pfn_to_page(pfn)); |
114 | 114 | ||
115 | return true; | 115 | return true; |
116 | } | 116 | } |
@@ -1321,7 +1321,7 @@ static pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async, | |||
1321 | else if ((vma->vm_flags & VM_PFNMAP)) { | 1321 | else if ((vma->vm_flags & VM_PFNMAP)) { |
1322 | pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + | 1322 | pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + |
1323 | vma->vm_pgoff; | 1323 | vma->vm_pgoff; |
1324 | BUG_ON(!kvm_is_mmio_pfn(pfn)); | 1324 | BUG_ON(!kvm_is_reserved_pfn(pfn)); |
1325 | } else { | 1325 | } else { |
1326 | if (async && vma_is_valid(vma, write_fault)) | 1326 | if (async && vma_is_valid(vma, write_fault)) |
1327 | *async = true; | 1327 | *async = true; |
@@ -1427,7 +1427,7 @@ static struct page *kvm_pfn_to_page(pfn_t pfn) | |||
1427 | if (is_error_noslot_pfn(pfn)) | 1427 | if (is_error_noslot_pfn(pfn)) |
1428 | return KVM_ERR_PTR_BAD_PAGE; | 1428 | return KVM_ERR_PTR_BAD_PAGE; |
1429 | 1429 | ||
1430 | if (kvm_is_mmio_pfn(pfn)) { | 1430 | if (kvm_is_reserved_pfn(pfn)) { |
1431 | WARN_ON(1); | 1431 | WARN_ON(1); |
1432 | return KVM_ERR_PTR_BAD_PAGE; | 1432 | return KVM_ERR_PTR_BAD_PAGE; |
1433 | } | 1433 | } |
@@ -1456,7 +1456,7 @@ EXPORT_SYMBOL_GPL(kvm_release_page_clean); | |||
1456 | 1456 | ||
1457 | void kvm_release_pfn_clean(pfn_t pfn) | 1457 | void kvm_release_pfn_clean(pfn_t pfn) |
1458 | { | 1458 | { |
1459 | if (!is_error_noslot_pfn(pfn) && !kvm_is_mmio_pfn(pfn)) | 1459 | if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn)) |
1460 | put_page(pfn_to_page(pfn)); | 1460 | put_page(pfn_to_page(pfn)); |
1461 | } | 1461 | } |
1462 | EXPORT_SYMBOL_GPL(kvm_release_pfn_clean); | 1462 | EXPORT_SYMBOL_GPL(kvm_release_pfn_clean); |
@@ -1477,7 +1477,7 @@ static void kvm_release_pfn_dirty(pfn_t pfn) | |||
1477 | 1477 | ||
1478 | void kvm_set_pfn_dirty(pfn_t pfn) | 1478 | void kvm_set_pfn_dirty(pfn_t pfn) |
1479 | { | 1479 | { |
1480 | if (!kvm_is_mmio_pfn(pfn)) { | 1480 | if (!kvm_is_reserved_pfn(pfn)) { |
1481 | struct page *page = pfn_to_page(pfn); | 1481 | struct page *page = pfn_to_page(pfn); |
1482 | if (!PageReserved(page)) | 1482 | if (!PageReserved(page)) |
1483 | SetPageDirty(page); | 1483 | SetPageDirty(page); |
@@ -1487,14 +1487,14 @@ EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty); | |||
1487 | 1487 | ||
1488 | void kvm_set_pfn_accessed(pfn_t pfn) | 1488 | void kvm_set_pfn_accessed(pfn_t pfn) |
1489 | { | 1489 | { |
1490 | if (!kvm_is_mmio_pfn(pfn)) | 1490 | if (!kvm_is_reserved_pfn(pfn)) |
1491 | mark_page_accessed(pfn_to_page(pfn)); | 1491 | mark_page_accessed(pfn_to_page(pfn)); |
1492 | } | 1492 | } |
1493 | EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed); | 1493 | EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed); |
1494 | 1494 | ||
1495 | void kvm_get_pfn(pfn_t pfn) | 1495 | void kvm_get_pfn(pfn_t pfn) |
1496 | { | 1496 | { |
1497 | if (!kvm_is_mmio_pfn(pfn)) | 1497 | if (!kvm_is_reserved_pfn(pfn)) |
1498 | get_page(pfn_to_page(pfn)); | 1498 | get_page(pfn_to_page(pfn)); |
1499 | } | 1499 | } |
1500 | EXPORT_SYMBOL_GPL(kvm_get_pfn); | 1500 | EXPORT_SYMBOL_GPL(kvm_get_pfn); |