Trivial conflict in CAN, keep the net-next + the byteswap wrapper. Conflicts: drivers/net/can/usb/gs_usb.c
Unified · Split
| @@ -290,6 +290,7 @@ Santosh Shilimkar <ssantosh@kernel.org> · 289 unmodified lines | |||
| 290 | Sarangdhar Joshi <spjoshi@codeaurora.org> | 290 | Sarangdhar Joshi <spjoshi@codeaurora.org> |
| 291 | Sascha Hauer <s.hauer@pengutronix.de> | 291 | Sascha Hauer <s.hauer@pengutronix.de> |
| 292 | S.Çağlar Onur <caglar@pardus.org.tr> | 292 | S.Çağlar Onur <caglar@pardus.org.tr> |
| 293 | Sean Christopherson <seanjc@google.com> <sean.j.christopherson@intel.com> | ||
| 293 | Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk> | 294 | Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk> |
| 294 | Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk> | 295 | Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk> |
| 295 | Sebastian Reichel <sre@kernel.org> <sre@debian.org> | 296 | Sebastian Reichel <sre@kernel.org> <sre@debian.org> |
| @@ -109,30 +109,6 @@ Description: · 108 unmodified lines | |||
| 109 | When counting down the counter start from preset value | 109 | When counting down the counter start from preset value |
| 110 | and fire event when reach 0. | 110 | and fire event when reach 0. |
| 111 | 111 | ||
| 112 | What: /sys/bus/iio/devices/iio:deviceX/in_count_quadrature_mode_available | ||
| 113 | KernelVersion: 4.12 | ||
| 114 | Contact: benjamin.gaignard@st.com | ||
| 115 | Description: | ||
| 116 | Reading returns the list possible quadrature modes. | ||
| 117 | |||
| 118 | What: /sys/bus/iio/devices/iio:deviceX/in_count0_quadrature_mode | ||
| 119 | KernelVersion: 4.12 | ||
| 120 | Contact: benjamin.gaignard@st.com | ||
| 121 | Description: | ||
| 122 | Configure the device counter quadrature modes: | ||
| 123 | |||
| 124 | channel_A: | ||
| 125 | Encoder A input servers as the count input and B as | ||
| 126 | the UP/DOWN direction control input. | ||
| 127 | |||
| 128 | channel_B: | ||
| 129 | Encoder B input serves as the count input and A as | ||
| 130 | the UP/DOWN direction control input. | ||
| 131 | |||
| 132 | quadrature: | ||
| 133 | Encoder A and B inputs are mixed to get direction | ||
| 134 | and count with a scale of 0.25. | ||
| 135 | |||
| 136 | What: /sys/bus/iio/devices/iio:deviceX/in_count_enable_mode_available | 112 | What: /sys/bus/iio/devices/iio:deviceX/in_count_enable_mode_available |
| 137 | KernelVersion: 4.12 | 113 | KernelVersion: 4.12 |
| 138 | Contact: benjamin.gaignard@st.com | 114 | Contact: benjamin.gaignard@st.com |
| @@ -76,6 +76,12 @@ properties: · 75 unmodified lines | |||
| 76 | resets: | 76 | resets: |
| 77 | maxItems: 1 | 77 | maxItems: 1 |
| 78 | 78 | ||
| 79 | wifi-2.4ghz-coexistence: | ||
| 80 | type: boolean | ||
| 81 | description: > | ||
| 82 | Should the pixel frequencies in the WiFi frequencies range be | ||
| 83 | avoided? | ||
| 84 | |||
| 79 | required: | 85 | required: |
| 80 | - compatible | 86 | - compatible |
| 81 | - reg | 87 | - reg |
| @@ -8,10 +8,16 @@ Required properties: · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | - reg : The I2C address of the device. | 9 | - reg : The I2C address of the device. |
| 10 | 10 | ||
| 11 | Optional properties: | ||
| 12 | |||
| 13 | - realtek,power-up-delay-ms | ||
| 14 | Set a delay time for flush work to be completed, | ||
| 15 | this value is adjustable depending on platform. | ||
| 11 | 16 | ||
| 12 | Example: | 17 | Example: |
| 13 | 18 | ||
| 14 | rt1015: codec@28 { | 19 | rt1015: codec@28 { |
| 15 | compatible = "realtek,rt1015"; | 20 | compatible = "realtek,rt1015"; |
| 16 | reg = <0x28>; | 21 | reg = <0x28>; |
| 22 | realtek,power-up-delay-ms = <50>; | ||
| 17 | }; | 23 | }; |
| @@ -149,11 +149,11 @@ vidtv_psi.[ch] · 148 unmodified lines | |||
| 149 | Because the generator is implemented in a separate file, it can be | 149 | Because the generator is implemented in a separate file, it can be |
| 150 | reused elsewhere in the media subsystem. | 150 | reused elsewhere in the media subsystem. |
| 151 | 151 | ||
| 152 | Currently vidtv supports working with 3 PSI tables: PAT, PMT and | 152 | Currently vidtv supports working with 5 PSI tables: PAT, PMT, |
| 153 | SDT. | 153 | SDT, NIT and EIT. |
| 154 | 154 | ||
| 155 | The specification for PAT and PMT can be found in *ISO 13818-1: | 155 | The specification for PAT and PMT can be found in *ISO 13818-1: |
| 156 | Systems*, while the specification for the SDT can be found in *ETSI | 156 | Systems*, while the specification for the SDT, NIT, EIT can be found in *ETSI |
| 157 | EN 300 468: Specification for Service Information (SI) in DVB | 157 | EN 300 468: Specification for Service Information (SI) in DVB |
| 158 | systems*. | 158 | systems*. |
| 159 | 159 | ||
| @@ -197,6 +197,8 @@ vidtv_channel.[ch] · 37 unmodified lines | |||
| 197 | 197 | ||
| 198 | #. Their programs will be concatenated to populate the PAT | 198 | #. Their programs will be concatenated to populate the PAT |
| 199 | 199 | ||
| 200 | #. Their events will be concatenated to populate the EIT | ||
| 201 | |||
| 200 | #. For each program in the PAT, a PMT section will be created | 202 | #. For each program in the PAT, a PMT section will be created |
| 201 | 203 | ||
| 202 | #. The PMT section for a channel will be assigned its streams. | 204 | #. The PMT section for a channel will be assigned its streams. |
| @@ -256,6 +258,42 @@ Using dvb-fe-tool · 53 unmodified lines | |||
| 256 | The first step to check whether the demod loaded successfully is to run:: | 258 | The first step to check whether the demod loaded successfully is to run:: |
| 257 | 259 | ||
| 258 | $ dvb-fe-tool | 260 | $ dvb-fe-tool |
| 261 | Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities: | ||
| 262 | CAN_FEC_1_2 | ||
| 263 | CAN_FEC_2_3 | ||
| 264 | CAN_FEC_3_4 | ||
| 265 | CAN_FEC_4_5 | ||
| 266 | CAN_FEC_5_6 | ||
| 267 | CAN_FEC_6_7 | ||
| 268 | CAN_FEC_7_8 | ||
| 269 | CAN_FEC_8_9 | ||
| 270 | CAN_FEC_AUTO | ||
| 271 | CAN_GUARD_INTERVAL_AUTO | ||
| 272 | CAN_HIERARCHY_AUTO | ||
| 273 | CAN_INVERSION_AUTO | ||
| 274 | CAN_QAM_16 | ||
| 275 | CAN_QAM_32 | ||
| 276 | CAN_QAM_64 | ||
| 277 | CAN_QAM_128 | ||
| 278 | CAN_QAM_256 | ||
| 279 | CAN_QAM_AUTO | ||
| 280 | CAN_QPSK | ||
| 281 | CAN_TRANSMISSION_MODE_AUTO | ||
| 282 | DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A | ||
| 283 | Supported delivery systems: | ||
| 284 | DVBT | ||
| 285 | DVBT2 | ||
| 286 | [DVBC/ANNEX_A] | ||
| 287 | DVBS | ||
| 288 | DVBS2 | ||
| 289 | Frequency range for the current standard: | ||
| 290 | From: 51.0 MHz | ||
| 291 | To: 2.15 GHz | ||
| 292 | Step: 62.5 kHz | ||
| 293 | Tolerance: 29.5 MHz | ||
| 294 | Symbol rate ranges for the current standard: | ||
| 295 | From: 1.00 MBauds | ||
| 296 | To: 45.0 MBauds | ||
| 259 | 297 | ||
| 260 | This should return what is currently set up at the demod struct, i.e.:: | 298 | This should return what is currently set up at the demod struct, i.e.:: |
| 261 | 299 | ||
| @@ -314,7 +352,7 @@ For this, one should provide a configuration file known as a 'scan file', · 52 unmodified lines | |||
| 314 | here's an example:: | 352 | here's an example:: |
| 315 | 353 | ||
| 316 | [Channel] | 354 | [Channel] |
| 317 | FREQUENCY = 330000000 | 355 | FREQUENCY = 474000000 |
| 318 | MODULATION = QAM/AUTO | 356 | MODULATION = QAM/AUTO |
| 319 | SYMBOL_RATE = 6940000 | 357 | SYMBOL_RATE = 6940000 |
| 320 | INNER_FEC = AUTO | 358 | INNER_FEC = AUTO |
| @@ -335,6 +373,14 @@ You can browse scan tables online here: `dvb-scan-tables · 14 unmodified lines | |||
| 335 | Assuming this channel is named 'channel.conf', you can then run:: | 373 | Assuming this channel is named 'channel.conf', you can then run:: |
| 336 | 374 | ||
| 337 | $ dvbv5-scan channel.conf | 375 | $ dvbv5-scan channel.conf |
| 376 | dvbv5-scan ~/vidtv.conf | ||
| 377 | ERROR command BANDWIDTH_HZ (5) not found during retrieve | ||
| 378 | Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet). | ||
| 379 | Scanning frequency #1 330000000 | ||
| 380 | (0x00) Signal= -68.00dBm | ||
| 381 | Scanning frequency #2 474000000 | ||
| 382 | Lock (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0 | ||
| 383 | Service Beethoven, provider LinuxTV.org: digital television | ||
| 338 | 384 | ||
| 339 | For more information on dvb-scan, check its documentation online here: | 385 | For more information on dvb-scan, check its documentation online here: |
| 340 | `dvb-scan Documentation <https://www.linuxtv.org/wiki/index.php/Dvbscan>`_. | 386 | `dvb-scan Documentation <https://www.linuxtv.org/wiki/index.php/Dvbscan>`_. |
| @@ -344,23 +390,38 @@ Using dvb-zap · 3 unmodified lines | |||
| 344 | 390 | ||
| 345 | dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The | 391 | dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The |
| 346 | typical use is to tune into a channel and put it into record mode. The example | 392 | typical use is to tune into a channel and put it into record mode. The example |
| 347 | below - which is taken from the documentation - illustrates that:: | 393 | below - which is taken from the documentation - illustrates that\ [1]_:: |
| 348 | 394 | ||
| 349 | $ dvbv5-zap -c dvb_channel.conf "trilhas sonoras" -r | 395 | $ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10 |
| 350 | using demux '/dev/dvb/adapter0/demux0' | 396 | using demux 'dvb0.demux0' |
| 351 | reading channels from file 'dvb_channel.conf' | 397 | reading channels from file 'dvb_channel.conf' |
| 352 | service has pid type 05: 204 | 398 | tuning to 474000000 Hz |
| 353 | tuning to 573000000 Hz | 399 | pass all PID's to TS |
| 354 | audio pid 104 | 400 | dvb_set_pesfilter 8192 |
| 355 | dvb_set_pesfilter 104 | 401 | dvb_dev_set_bufsize: buffer set to 6160384 |
| 356 | Lock (0x1f) Quality= Good Signal= 100.00% C/N= -13.80dB UCB= 70 postBER= 3.14x10^-3 PER= 0 | 402 | Lock (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0 |
| 357 | DVR interface '/dev/dvb/adapter0/dvr0' can now be opened | 403 | Lock (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0 |
| 404 | Record to file 'music.ts' started | ||
| 405 | received 24587768 bytes (2401 Kbytes/sec) | ||
| 406 | Lock (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0 | ||
| 407 | |||
| 408 | .. [1] In this example, it records 10 seconds with all program ID's stored | ||
| 409 | at the music.ts file. | ||
| 410 | |||
| 358 | 411 | ||
| 359 | The channel can be watched by playing the contents of the DVR interface, with | 412 | The channel can be watched by playing the contents of the stream with some |
| 360 | some player that recognizes the MPEG-TS format, such as *mplayer* or *vlc*. | 413 | player that recognizes the MPEG-TS format, such as ``mplayer`` or ``vlc``. |
| 361 | 414 | ||
| 362 | By playing the contents of the stream one can visually inspect the workings of | 415 | By playing the contents of the stream one can visually inspect the workings of |
| 363 | vidtv, e.g.:: | 416 | vidtv, e.g., to play a recorded TS file with:: |
| 417 | |||
| 418 | $ mplayer music.ts | ||
| 419 | |||
| 420 | or, alternatively, running this command on one terminal:: | ||
| 421 | |||
| 422 | $ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r & | ||
| 423 | |||
| 424 | And, on a second terminal, playing the contents from DVR interface with:: | ||
| 364 | 425 | ||
| 365 | $ mplayer /dev/dvb/adapter0/dvr0 | 426 | $ mplayer /dev/dvb/adapter0/dvr0 |
| 366 | 427 | ||
| @@ -423,3 +484,30 @@ A nice addition is to simulate some noise when the signal quality is bad by: · 56 unmodified lines | |||
| 423 | - Updating the error statistics accordingly (e.g. BER, etc). | 484 | - Updating the error statistics accordingly (e.g. BER, etc). |
| 424 | 485 | ||
| 425 | - Simulating some noise in the encoded data. | 486 | - Simulating some noise in the encoded data. |
| 487 | |||
| 488 | Functions and structs used within vidtv | ||
| 489 | --------------------------------------- | ||
| 490 | |||
| 491 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_bridge.h | ||
| 492 | |||
| 493 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_channel.h | ||
| 494 | |||
| 495 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_demod.h | ||
| 496 | |||
| 497 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_encoder.h | ||
| 498 | |||
| 499 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_mux.h | ||
| 500 | |||
| 501 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_pes.h | ||
| 502 | |||
| 503 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_psi.h | ||
| 504 | |||
| 505 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_s302m.h | ||
| 506 | |||
| 507 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_ts.h | ||
| 508 | |||
| 509 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.h | ||
| 510 | |||
| 511 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_common.c | ||
| 512 | |||
| 513 | .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.c | ||
| @@ -254,6 +254,32 @@ you will have done run-time testing specific to your change, but at a · 253 unmodified lines | |||
| 254 | minimum, your changes should survive an ``allyesconfig`` and an | 254 | minimum, your changes should survive an ``allyesconfig`` and an |
| 255 | ``allmodconfig`` build without new warnings or failures. | 255 | ``allmodconfig`` build without new warnings or failures. |
| 256 | 256 | ||
| 257 | Q: How do I post corresponding changes to user space components? | ||
| 258 | ---------------------------------------------------------------- | ||
| 259 | A: User space code exercising kernel features should be posted | ||
| 260 | alongside kernel patches. This gives reviewers a chance to see | ||
| 261 | how any new interface is used and how well it works. | ||
| 262 | |||
| 263 | When user space tools reside in the kernel repo itself all changes | ||
| 264 | should generally come as one series. If series becomes too large | ||
| 265 | or the user space project is not reviewed on netdev include a link | ||
| 266 | to a public repo where user space patches can be seen. | ||
| 267 | |||
| 268 | In case user space tooling lives in a separate repository but is | ||
| 269 | reviewed on netdev (e.g. patches to `iproute2` tools) kernel and | ||
| 270 | user space patches should form separate series (threads) when posted | ||
| 271 | to the mailing list, e.g.:: | ||
| 272 | |||
| 273 | [PATCH net-next 0/3] net: some feature cover letter | ||
| 274 | └─ [PATCH net-next 1/3] net: some feature prep | ||
| 275 | └─ [PATCH net-next 2/3] net: some feature do it | ||
| 276 | └─ [PATCH net-next 3/3] selftest: net: some feature | ||
| 277 | |||
| 278 | [PATCH iproute2-next] ip: add support for some feature | ||
| 279 | |||
| 280 | Posting as one thread is discouraged because it confuses patchwork | ||
| 281 | (as of patchwork 2.2.2). | ||
| 282 | |||
| 257 | Q: Any other tips to help ensure my net/net-next patch gets OK'd? | 283 | Q: Any other tips to help ensure my net/net-next patch gets OK'd? |
| 258 | ----------------------------------------------------------------- | 284 | ----------------------------------------------------------------- |
| 259 | A: Attention to detail. Re-read your own work as if you were the | 285 | A: Attention to detail. Re-read your own work as if you were the |
| @@ -1995,7 +1995,6 @@ N: lpc18xx · 1994 unmodified lines | |||
| 1995 | 1995 | ||
| 1996 | ARM/LPC32XX SOC SUPPORT | 1996 | ARM/LPC32XX SOC SUPPORT |
| 1997 | M: Vladimir Zapolskiy <vz@mleia.com> | 1997 | M: Vladimir Zapolskiy <vz@mleia.com> |
| 1998 | M: Sylvain Lemieux <slemieux.tyco@gmail.com> | ||
| 1999 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1998 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2000 | S: Maintained | 1999 | S: Maintained |
| 2001 | T: git git://github.com/vzapolskiy/linux-lpc32xx.git | 2000 | T: git git://github.com/vzapolskiy/linux-lpc32xx.git |
| @@ -3528,11 +3527,12 @@ BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER · 1526 unmodified lines | |||
| 3528 | M: Arend van Spriel <arend.vanspriel@broadcom.com> | 3527 | M: Arend van Spriel <arend.vanspriel@broadcom.com> |
| 3529 | M: Franky Lin <franky.lin@broadcom.com> | 3528 | M: Franky Lin <franky.lin@broadcom.com> |
| 3530 | M: Hante Meuleman <hante.meuleman@broadcom.com> | 3529 | M: Hante Meuleman <hante.meuleman@broadcom.com> |
| 3531 | M: Chi-Hsien Lin <chi-hsien.lin@cypress.com> | 3530 | M: Chi-hsien Lin <chi-hsien.lin@infineon.com> |
| 3532 | M: Wright Feng <wright.feng@cypress.com> | 3531 | M: Wright Feng <wright.feng@infineon.com> |
| 3532 | M: Chung-hsien Hsu <chung-hsien.hsu@infineon.com> | ||
| 3533 | L: linux-wireless@vger.kernel.org | 3533 | L: linux-wireless@vger.kernel.org |
| 3534 | L: brcm80211-dev-list.pdl@broadcom.com | 3534 | L: brcm80211-dev-list.pdl@broadcom.com |
| 3535 | L: brcm80211-dev-list@cypress.com | 3535 | L: SHA-cyfmac-dev-list@infineon.com |
| 3536 | S: Supported | 3536 | S: Supported |
| 3537 | F: drivers/net/wireless/broadcom/brcm80211/ | 3537 | F: drivers/net/wireless/broadcom/brcm80211/ |
| 3538 | 3538 | ||
| @@ -9155,6 +9155,7 @@ F: include/linux/iomap.h · 5616 unmodified lines | |||
| 9155 | 9155 | ||
| 9156 | IOMMU DRIVERS | 9156 | IOMMU DRIVERS |
| 9157 | M: Joerg Roedel <joro@8bytes.org> | 9157 | M: Joerg Roedel <joro@8bytes.org> |
| 9158 | M: Will Deacon <will@kernel.org> | ||
| 9158 | L: iommu@lists.linux-foundation.org | 9159 | L: iommu@lists.linux-foundation.org |
| 9159 | S: Maintained | 9160 | S: Maintained |
| 9160 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 9161 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| @@ -9638,6 +9639,7 @@ F: Documentation/virt/kvm/s390* · 477 unmodified lines | |||
| 9638 | F: arch/s390/include/asm/gmap.h | 9639 | F: arch/s390/include/asm/gmap.h |
| 9639 | F: arch/s390/include/asm/kvm* | 9640 | F: arch/s390/include/asm/kvm* |
| 9640 | F: arch/s390/include/uapi/asm/kvm* | 9641 | F: arch/s390/include/uapi/asm/kvm* |
| 9642 | F: arch/s390/kernel/uv.c | ||
| 9641 | F: arch/s390/kvm/ | 9643 | F: arch/s390/kvm/ |
| 9642 | F: arch/s390/mm/gmap.c | 9644 | F: arch/s390/mm/gmap.c |
| 9643 | F: tools/testing/selftests/kvm/*/s390x/ | 9645 | F: tools/testing/selftests/kvm/*/s390x/ |
| @@ -13156,7 +13158,9 @@ M: Jesper Dangaard Brouer <hawk@kernel.org> · 3512 unmodified lines | |||
| 13156 | M: Ilias Apalodimas <ilias.apalodimas@linaro.org> | 13158 | M: Ilias Apalodimas <ilias.apalodimas@linaro.org> |
| 13157 | L: netdev@vger.kernel.org | 13159 | L: netdev@vger.kernel.org |
| 13158 | S: Supported | 13160 | S: Supported |
| 13161 | F: Documentation/networking/page_pool.rst | ||
| 13159 | F: include/net/page_pool.h | 13162 | F: include/net/page_pool.h |
| 13163 | F: include/trace/events/page_pool.h | ||
| 13160 | F: net/core/page_pool.c | 13164 | F: net/core/page_pool.c |
| 13161 | 13165 | ||
| 13162 | PANASONIC LAPTOP ACPI EXTRAS DRIVER | 13166 | PANASONIC LAPTOP ACPI EXTRAS DRIVER |
| @@ -14798,7 +14802,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g · 1635 unmodified lines | |||
| 14798 | F: drivers/net/wireless/realtek/rtlwifi/ | 14802 | F: drivers/net/wireless/realtek/rtlwifi/ |
| 14799 | 14803 | ||
| 14800 | REALTEK WIRELESS DRIVER (rtw88) | 14804 | REALTEK WIRELESS DRIVER (rtw88) |
| 14801 | M: Yan-Hsuan Chuang <yhchuang@realtek.com> | 14805 | M: Yan-Hsuan Chuang <tony0620emma@gmail.com> |
| 14802 | L: linux-wireless@vger.kernel.org | 14806 | L: linux-wireless@vger.kernel.org |
| 14803 | S: Maintained | 14807 | S: Maintained |
| 14804 | F: drivers/net/wireless/realtek/rtw88/ | 14808 | F: drivers/net/wireless/realtek/rtw88/ |
| @@ -15771,9 +15775,8 @@ F: drivers/slimbus/ · 966 unmodified lines | |||
| 15771 | F: include/linux/slimbus.h | 15775 | F: include/linux/slimbus.h |
| 15772 | 15776 | ||
| 15773 | SFC NETWORK DRIVER | 15777 | SFC NETWORK DRIVER |
| 15774 | M: Solarflare linux maintainers <linux-net-drivers@solarflare.com> | 15778 | M: Edward Cree <ecree.xilinx@gmail.com> |
| 15775 | M: Edward Cree <ecree@solarflare.com> | 15779 | M: Martin Habets <habetsm.xilinx@gmail.com> |
| 15776 | M: Martin Habets <mhabets@solarflare.com> | ||
| 15777 | L: netdev@vger.kernel.org | 15780 | L: netdev@vger.kernel.org |
| 15778 | S: Supported | 15781 | S: Supported |
| 15779 | F: drivers/net/ethernet/sfc/ | 15782 | F: drivers/net/ethernet/sfc/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 10 | 3 | PATCHLEVEL = 10 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc4 | 5 | EXTRAVERSION = -rc5 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -243,10 +243,8 @@ static inline int constant_fls(unsigned int x) · 242 unmodified lines | |||
| 243 | x <<= 2; | 243 | x <<= 2; |
| 244 | r -= 2; | 244 | r -= 2; |
| 245 | } | 245 | } |
| 246 | if (!(x & 0x80000000u)) { | 246 | if (!(x & 0x80000000u)) |
| 247 | x <<= 1; | ||
| 248 | r -= 1; | 247 | r -= 1; |
| 249 | } | ||
| 250 | return r; | 248 | return r; |
| 251 | } | 249 | } |
| 252 | 250 | ||
| @@ -134,8 +134,10 @@ · 133 unmodified lines | |||
| 134 | 134 | ||
| 135 | #ifdef CONFIG_ARC_HAS_PAE40 | 135 | #ifdef CONFIG_ARC_HAS_PAE40 |
| 136 | #define PTE_BITS_NON_RWX_IN_PD1 (0xff00000000 | PAGE_MASK | _PAGE_CACHEABLE) | 136 | #define PTE_BITS_NON_RWX_IN_PD1 (0xff00000000 | PAGE_MASK | _PAGE_CACHEABLE) |
| 137 | #define MAX_POSSIBLE_PHYSMEM_BITS 40 | ||
| 137 | #else | 138 | #else |
| 138 | #define PTE_BITS_NON_RWX_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE) | 139 | #define PTE_BITS_NON_RWX_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE) |
| 140 | #define MAX_POSSIBLE_PHYSMEM_BITS 32 | ||
| 139 | #endif | 141 | #endif |
| 140 | 142 | ||
| 141 | /************************************************************************** | 143 | /************************************************************************** |
| @@ -38,15 +38,27 @@ · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | #ifdef CONFIG_ARC_DW2_UNWIND | 39 | #ifdef CONFIG_ARC_DW2_UNWIND |
| 40 | 40 | ||
| 41 | static void seed_unwind_frame_info(struct task_struct *tsk, | 41 | static int |
| 42 | struct pt_regs *regs, | 42 | seed_unwind_frame_info(struct task_struct *tsk, struct pt_regs *regs, |
| 43 | struct unwind_frame_info *frame_info) | 43 | struct unwind_frame_info *frame_info) |
| 44 | { | 44 | { |
| 45 | /* | 45 | if (regs) { |
| 46 | * synchronous unwinding (e.g. dump_stack) | 46 | /* |
| 47 | * - uses current values of SP and friends | 47 | * Asynchronous unwinding of intr/exception |
| 48 | */ | 48 | * - Just uses the pt_regs passed |
| 49 | if (tsk == NULL && regs == NULL) { | 49 | */ |
| 50 | frame_info->task = tsk; | ||
| 51 | |||
| 52 | frame_info->regs.r27 = regs->fp; | ||
| 53 | frame_info->regs.r28 = regs->sp; | ||
| 54 | frame_info->regs.r31 = regs->blink; | ||
| 55 | frame_info->regs.r63 = regs->ret; | ||
| 56 | frame_info->call_frame = 0; | ||
| 57 | } else if (tsk == NULL || tsk == current) { | ||
| 58 | /* | ||
| 59 | * synchronous unwinding (e.g. dump_stack) | ||
| 60 | * - uses current values of SP and friends | ||
| 61 | */ | ||
| 50 | unsigned long fp, sp, blink, ret; | 62 | unsigned long fp, sp, blink, ret; |
| 51 | frame_info->task = current; | 63 | frame_info->task = current; |
| 52 | 64 | ||
| @@ -63,13 +75,17 @@ static void seed_unwind_frame_info(struct task_struct *tsk, · 10 unmodified lines | |||
| 63 | frame_info->regs.r31 = blink; | 75 | frame_info->regs.r31 = blink; |
| 64 | frame_info->regs.r63 = ret; | 76 | frame_info->regs.r63 = ret; |
| 65 | frame_info->call_frame = 0; | 77 | frame_info->call_frame = 0; |
| 66 | } else if (regs == NULL) { | 78 | } else { |
| 67 | /* | 79 | /* |
| 68 | * Asynchronous unwinding of sleeping task | 80 | * Asynchronous unwinding of a likely sleeping task |
| 69 | * - Gets SP etc from task's pt_regs (saved bottom of kernel | 81 | * - first ensure it is actually sleeping |
| 70 | * mode stack of task) | 82 | * - if so, it will be in __switch_to, kernel mode SP of task |
| 83 | * is safe-kept and BLINK at a well known location in there | ||
| 71 | */ | 84 | */ |
| 72 | 85 | ||
| 86 | if (tsk->state == TASK_RUNNING) | ||
| 87 | return -1; | ||
| 88 | |||
| 73 | frame_info->task = tsk; | 89 | frame_info->task = tsk; |
| 74 | 90 | ||
| 75 | frame_info->regs.r27 = TSK_K_FP(tsk); | 91 | frame_info->regs.r27 = TSK_K_FP(tsk); |
| @@ -90,19 +106,8 @@ static void seed_unwind_frame_info(struct task_struct *tsk, · 14 unmodified lines | |||
| 90 | frame_info->regs.r28 += 60; | 106 | frame_info->regs.r28 += 60; |
| 91 | frame_info->call_frame = 0; | 107 | frame_info->call_frame = 0; |
| 92 | 108 | ||
| 93 | } else { | ||
| 94 | /* | ||
| 95 | * Asynchronous unwinding of intr/exception | ||
| 96 | * - Just uses the pt_regs passed | ||
| 97 | */ | ||
| 98 | frame_info->task = tsk; | ||
| 99 | |||
| 100 | frame_info->regs.r27 = regs->fp; | ||
| 101 | frame_info->regs.r28 = regs->sp; | ||
| 102 | frame_info->regs.r31 = regs->blink; | ||
| 103 | frame_info->regs.r63 = regs->ret; | ||
| 104 | frame_info->call_frame = 0; | ||
| 105 | } | 109 | } |
| 110 | return 0; | ||
| 106 | } | 111 | } |
| 107 | 112 | ||
| 108 | #endif | 113 | #endif |
| @@ -116,7 +121,8 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, · 7 unmodified lines | |||
| 116 | unsigned int address; | 121 | unsigned int address; |
| 117 | struct unwind_frame_info frame_info; | 122 | struct unwind_frame_info frame_info; |
| 118 | 123 | ||
| 119 | seed_unwind_frame_info(tsk, regs, &frame_info); | 124 | if (seed_unwind_frame_info(tsk, regs, &frame_info)) |
| 125 | return 0; | ||
| 120 | 126 | ||
| 121 | while (1) { | 127 | while (1) { |
| 122 | address = UNW_PC(&frame_info); | 128 | address = UNW_PC(&frame_info); |
| @@ -30,14 +30,14 @@ · 29 unmodified lines | |||
| 30 | * -Changes related to MMU v2 (Rel 4.8) | 30 | * -Changes related to MMU v2 (Rel 4.8) |
| 31 | * | 31 | * |
| 32 | * Vineetg: Aug 29th 2008 | 32 | * Vineetg: Aug 29th 2008 |
| 33 | * -In TLB Flush operations (Metal Fix MMU) there is a explict command to | 33 | * -In TLB Flush operations (Metal Fix MMU) there is a explicit command to |
| 34 | * flush Micro-TLBS. If TLB Index Reg is invalid prior to TLBIVUTLB cmd, | 34 | * flush Micro-TLBS. If TLB Index Reg is invalid prior to TLBIVUTLB cmd, |
| 35 | * it fails. Thus need to load it with ANY valid value before invoking | 35 | * it fails. Thus need to load it with ANY valid value before invoking |
| 36 | * TLBIVUTLB cmd | 36 | * TLBIVUTLB cmd |
| 37 | * | 37 | * |
| 38 | * Vineetg: Aug 21th 2008: | 38 | * Vineetg: Aug 21th 2008: |
| 39 | * -Reduced the duration of IRQ lockouts in TLB Flush routines | 39 | * -Reduced the duration of IRQ lockouts in TLB Flush routines |
| 40 | * -Multiple copies of TLB erase code seperated into a "single" function | 40 | * -Multiple copies of TLB erase code separated into a "single" function |
| 41 | * -In TLB Flush routines, interrupt disabling moved UP to retrieve ASID | 41 | * -In TLB Flush routines, interrupt disabling moved UP to retrieve ASID |
| 42 | * in interrupt-safe region. | 42 | * in interrupt-safe region. |
| 43 | * | 43 | * |
| @@ -66,7 +66,7 @@ · 22 unmodified lines | |||
| 66 | * | 66 | * |
| 67 | * Although J-TLB is 2 way set assoc, ARC700 caches J-TLB into uTLBS which has | 67 | * Although J-TLB is 2 way set assoc, ARC700 caches J-TLB into uTLBS which has |
| 68 | * much higher associativity. u-D-TLB is 8 ways, u-I-TLB is 4 ways. | 68 | * much higher associativity. u-D-TLB is 8 ways, u-I-TLB is 4 ways. |
| 69 | * Given this, the thrasing problem should never happen because once the 3 | 69 | * Given this, the thrashing problem should never happen because once the 3 |
| 70 | * J-TLB entries are created (even though 3rd will knock out one of the prev | 70 | * J-TLB entries are created (even though 3rd will knock out one of the prev |
| 71 | * two), the u-D-TLB and u-I-TLB will have what is required to accomplish memcpy | 71 | * two), the u-D-TLB and u-I-TLB will have what is required to accomplish memcpy |
| 72 | * | 72 | * |
| @@ -127,7 +127,7 @@ static void utlb_invalidate(void) · 54 unmodified lines | |||
| 127 | * There was however an obscure hardware bug, where uTLB flush would | 127 | * There was however an obscure hardware bug, where uTLB flush would |
| 128 | * fail when a prior probe for J-TLB (both totally unrelated) would | 128 | * fail when a prior probe for J-TLB (both totally unrelated) would |
| 129 | * return lkup err - because the entry didn't exist in MMU. | 129 | * return lkup err - because the entry didn't exist in MMU. |
| 130 | * The Workround was to set Index reg with some valid value, prior to | 130 | * The Workaround was to set Index reg with some valid value, prior to |
| 131 | * flush. This was fixed in MMU v3 | 131 | * flush. This was fixed in MMU v3 |
| 132 | */ | 132 | */ |
| 133 | unsigned int idx; | 133 | unsigned int idx; |
| @@ -272,7 +272,7 @@ noinline void local_flush_tlb_all(void) · 138 unmodified lines | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | /* | 274 | /* |
| 275 | * Flush the entrie MM for userland. The fastest way is to move to Next ASID | 275 | * Flush the entire MM for userland. The fastest way is to move to Next ASID |
| 276 | */ | 276 | */ |
| 277 | noinline void local_flush_tlb_mm(struct mm_struct *mm) | 277 | noinline void local_flush_tlb_mm(struct mm_struct *mm) |
| 278 | { | 278 | { |
| @@ -303,7 +303,7 @@ noinline void local_flush_tlb_mm(struct mm_struct *mm) · 24 unmodified lines | |||
| 303 | * Difference between this and Kernel Range Flush is | 303 | * Difference between this and Kernel Range Flush is |
| 304 | * -Here the fastest way (if range is too large) is to move to next ASID | 304 | * -Here the fastest way (if range is too large) is to move to next ASID |
| 305 | * without doing any explicit Shootdown | 305 | * without doing any explicit Shootdown |
| 306 | * -In case of kernel Flush, entry has to be shot down explictly | 306 | * -In case of kernel Flush, entry has to be shot down explicitly |
| 307 | */ | 307 | */ |
| 308 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | 308 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
| 309 | unsigned long end) | 309 | unsigned long end) |
| @@ -620,7 +620,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, · 310 unmodified lines | |||
| 620 | * Super Page size is configurable in hardware (4K to 16M), but fixed once | 620 | * Super Page size is configurable in hardware (4K to 16M), but fixed once |
| 621 | * RTL builds. | 621 | * RTL builds. |
| 622 | * | 622 | * |
| 623 | * The exact THP size a Linx configuration will support is a function of: | 623 | * The exact THP size a Linux configuration will support is a function of: |
| 624 | * - MMU page size (typical 8K, RTL fixed) | 624 | * - MMU page size (typical 8K, RTL fixed) |
| 625 | * - software page walker address split between PGD:PTE:PFN (typical | 625 | * - software page walker address split between PGD:PTE:PFN (typical |
| 626 | * 11:8:13, but can be changed with 1 line) | 626 | * 11:8:13, but can be changed with 1 line) |
| @@ -698,7 +698,7 @@ void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, · 71 unmodified lines | |||
| 698 | 698 | ||
| 699 | #endif | 699 | #endif |
| 700 | 700 | ||
| 701 | /* Read the Cache Build Confuration Registers, Decode them and save into | 701 | /* Read the Cache Build Configuration Registers, Decode them and save into |
| 702 | * the cpuinfo structure for later use. | 702 | * the cpuinfo structure for later use. |
| 703 | * No Validation is done here, simply read/convert the BCRs | 703 | * No Validation is done here, simply read/convert the BCRs |
| 704 | */ | 704 | */ |
| @@ -803,13 +803,13 @@ void arc_mmu_init(void) · 98 unmodified lines | |||
| 803 | pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); | 803 | pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); |
| 804 | 804 | ||
| 805 | /* | 805 | /* |
| 806 | * Can't be done in processor.h due to header include depenedencies | 806 | * Can't be done in processor.h due to header include dependencies |
| 807 | */ | 807 | */ |
| 808 | BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_KVADDR_SIZE << 20), PMD_SIZE)); | 808 | BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_KVADDR_SIZE << 20), PMD_SIZE)); |
| 809 | 809 | ||
| 810 | /* | 810 | /* |
| 811 | * stack top size sanity check, | 811 | * stack top size sanity check, |
| 812 | * Can't be done in processor.h due to header include depenedencies | 812 | * Can't be done in processor.h due to header include dependencies |
| 813 | */ | 813 | */ |
| 814 | BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE)); | 814 | BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE)); |
| 815 | 815 | ||
| @@ -881,7 +881,7 @@ void arc_mmu_init(void) · 65 unmodified lines | |||
| 881 | * the duplicate one. | 881 | * the duplicate one. |
| 882 | * -Knob to be verbose abt it.(TODO: hook them up to debugfs) | 882 | * -Knob to be verbose abt it.(TODO: hook them up to debugfs) |
| 883 | */ | 883 | */ |
| 884 | volatile int dup_pd_silent; /* Be slient abt it or complain (default) */ | 884 | volatile int dup_pd_silent; /* Be silent abt it or complain (default) */ |
| 885 | 885 | ||
| 886 | void do_tlb_overlap_fault(unsigned long cause, unsigned long address, | 886 | void do_tlb_overlap_fault(unsigned long cause, unsigned long address, |
| 887 | struct pt_regs *regs) | 887 | struct pt_regs *regs) |
| @@ -948,7 +948,7 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, · 60 unmodified lines | |||
| 948 | 948 | ||
| 949 | /*********************************************************************** | 949 | /*********************************************************************** |
| 950 | * Diagnostic Routines | 950 | * Diagnostic Routines |
| 951 | * -Called from Low Level TLB Hanlders if things don;t look good | 951 | * -Called from Low Level TLB Handlers if things don;t look good |
| 952 | **********************************************************************/ | 952 | **********************************************************************/ |
| 953 | 953 | ||
| 954 | #ifdef CONFIG_ARC_DBG_TLB_PARANOIA | 954 | #ifdef CONFIG_ARC_DBG_TLB_PARANOIA |
| @@ -1472,6 +1472,9 @@ ENTRY(efi_enter_kernel) · 1471 unmodified lines | |||
| 1472 | @ issued from HYP mode take us to the correct handler code. We | 1472 | @ issued from HYP mode take us to the correct handler code. We |
| 1473 | @ will disable the MMU before jumping to the kernel proper. | 1473 | @ will disable the MMU before jumping to the kernel proper. |
| 1474 | @ | 1474 | @ |
| 1475 | ARM( bic r1, r1, #(1 << 30) ) @ clear HSCTLR.TE | ||
| 1476 | THUMB( orr r1, r1, #(1 << 30) ) @ set HSCTLR.TE | ||
| 1477 | mcr p15, 4, r1, c1, c0, 0 | ||
| 1475 | adr r0, __hyp_reentry_vectors | 1478 | adr r0, __hyp_reentry_vectors |
| 1476 | mcr p15, 4, r0, c12, c0, 0 @ set HYP vector base (HVBAR) | 1479 | mcr p15, 4, r0, c12, c0, 0 @ set HYP vector base (HVBAR) |
| 1477 | isb | 1480 | isb |
| @@ -521,7 +521,7 @@ · 520 unmodified lines | |||
| 521 | ranges = <0x0 0x100000 0x8000>; | 521 | ranges = <0x0 0x100000 0x8000>; |
| 522 | 522 | ||
| 523 | mac_sw: switch@0 { | 523 | mac_sw: switch@0 { |
| 524 | compatible = "ti,am4372-cpsw","ti,cpsw-switch"; | 524 | compatible = "ti,am4372-cpsw-switch", "ti,cpsw-switch"; |
| 525 | reg = <0x0 0x4000>; | 525 | reg = <0x0 0x4000>; |
| 526 | ranges = <0 0 0x4000>; | 526 | ranges = <0 0 0x4000>; |
| 527 | clocks = <&cpsw_125mhz_gclk>, <&dpll_clksel_mac_clk>; | 527 | clocks = <&cpsw_125mhz_gclk>, <&dpll_clksel_mac_clk>; |
| @@ -32,8 +32,8 @@ · 31 unmodified lines | |||
| 32 | interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, | 32 | interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, |
| 33 | <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; | 33 | <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; |
| 34 | interrupt-names = "int0", "int1"; | 34 | interrupt-names = "int0", "int1"; |
| 35 | clocks = <&mcan_clk>, <&l3_iclk_div>; | 35 | clocks = <&l3_iclk_div>, <&mcan_clk>; |
| 36 | clock-names = "cclk", "hclk"; | 36 | clock-names = "hclk", "cclk"; |
| 37 | bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; | 37 | bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; |
| 38 | }; | 38 | }; |
| 39 | }; | 39 | }; |
| @@ -75,6 +75,8 @@ · 74 unmodified lines | |||
| 75 | #define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t)) | 75 | #define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t)) |
| 76 | #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32)) | 76 | #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32)) |
| 77 | 77 | ||
| 78 | #define MAX_POSSIBLE_PHYSMEM_BITS 32 | ||
| 79 | |||
| 78 | /* | 80 | /* |
| 79 | * PMD_SHIFT determines the size of the area a second-level page table can map | 81 | * PMD_SHIFT determines the size of the area a second-level page table can map |
| 80 | * PGDIR_SHIFT determines what a third-level page table entry can map | 82 | * PGDIR_SHIFT determines what a third-level page table entry can map |
| @@ -25,6 +25,8 @@ · 24 unmodified lines | |||
| 25 | #define PTE_HWTABLE_OFF (0) | 25 | #define PTE_HWTABLE_OFF (0) |
| 26 | #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) | 26 | #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) |
| 27 | 27 | ||
| 28 | #define MAX_POSSIBLE_PHYSMEM_BITS 40 | ||
| 29 | |||
| 28 | /* | 30 | /* |
| 29 | * PGDIR_SHIFT determines the size a top-level page table entry can map. | 31 | * PGDIR_SHIFT determines the size a top-level page table entry can map. |
| 30 | */ | 32 | */ |
| @@ -7,7 +7,6 @@ config ARCH_OMAP2 · 6 unmodified lines | |||
| 7 | depends on ARCH_MULTI_V6 | 7 | depends on ARCH_MULTI_V6 |
| 8 | select ARCH_OMAP2PLUS | 8 | select ARCH_OMAP2PLUS |
| 9 | select CPU_V6 | 9 | select CPU_V6 |
| 10 | select PM_GENERIC_DOMAINS if PM | ||
| 11 | select SOC_HAS_OMAP2_SDRC | 10 | select SOC_HAS_OMAP2_SDRC |
| 12 | 11 | ||
| 13 | config ARCH_OMAP3 | 12 | config ARCH_OMAP3 |
| @@ -106,6 +105,8 @@ config ARCH_OMAP2PLUS · 92 unmodified lines | |||
| 106 | select OMAP_DM_TIMER | 105 | select OMAP_DM_TIMER |
| 107 | select OMAP_GPMC | 106 | select OMAP_GPMC |
| 108 | select PINCTRL | 107 | select PINCTRL |
| 108 | select PM_GENERIC_DOMAINS if PM | ||
| 109 | select PM_GENERIC_DOMAINS_OF if PM | ||
| 109 | select RESET_CONTROLLER | 110 | select RESET_CONTROLLER |
| 110 | select SOC_BUS | 111 | select SOC_BUS |
| 111 | select TI_SYSC | 112 | select TI_SYSC |
| @@ -175,8 +175,11 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 174 unmodified lines | |||
| 175 | if (mpuss_can_lose_context) { | 175 | if (mpuss_can_lose_context) { |
| 176 | error = cpu_cluster_pm_enter(); | 176 | error = cpu_cluster_pm_enter(); |
| 177 | if (error) { | 177 | if (error) { |
| 178 | omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON); | 178 | index = 0; |
| 179 | goto cpu_cluster_pm_out; | 179 | cx = state_ptr + index; |
| 180 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); | ||
| 181 | omap_set_pwrdm_state(mpu_pd, cx->mpu_state); | ||
| 182 | mpuss_can_lose_context = 0; | ||
| 180 | } | 183 | } |
| 181 | } | 184 | } |
| 182 | } | 185 | } |
| @@ -184,7 +187,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, · 1 unmodified line | |||
| 184 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); | 187 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); |
| 185 | cpu_done[dev->cpu] = true; | 188 | cpu_done[dev->cpu] = true; |
| 186 | 189 | ||
| 187 | cpu_cluster_pm_out: | ||
| 188 | /* Wakeup CPU1 only if it is not offlined */ | 190 | /* Wakeup CPU1 only if it is not offlined */ |
| 189 | if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { | 191 | if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { |
| 190 | 192 | ||
| @@ -5,20 +5,20 @@ · 4 unmodified lines | |||
| 5 | usb { | 5 | usb { |
| 6 | compatible = "simple-bus"; | 6 | compatible = "simple-bus"; |
| 7 | dma-ranges; | 7 | dma-ranges; |
| 8 | #address-cells = <1>; | 8 | #address-cells = <2>; |
| 9 | #size-cells = <1>; | 9 | #size-cells = <2>; |
| 10 | ranges = <0x0 0x0 0x68500000 0x00400000>; | 10 | ranges = <0x0 0x0 0x0 0x68500000 0x0 0x00400000>; |
| 11 | 11 | ||
| 12 | usbphy0: usb-phy@0 { | 12 | usbphy0: usb-phy@0 { |
| 13 | compatible = "brcm,sr-usb-combo-phy"; | 13 | compatible = "brcm,sr-usb-combo-phy"; |
| 14 | reg = <0x00000000 0x100>; | 14 | reg = <0x0 0x00000000 0x0 0x100>; |
| 15 | #phy-cells = <1>; | 15 | #phy-cells = <1>; |
| 16 | status = "disabled"; | 16 | status = "disabled"; |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | xhci0: usb@1000 { | 19 | xhci0: usb@1000 { |
| 20 | compatible = "generic-xhci"; | 20 | compatible = "generic-xhci"; |
| 21 | reg = <0x00001000 0x1000>; | 21 | reg = <0x0 0x00001000 0x0 0x1000>; |
| 22 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; | 22 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; |
| 23 | phys = <&usbphy0 1>, <&usbphy0 0>; | 23 | phys = <&usbphy0 1>, <&usbphy0 0>; |
| 24 | phy-names = "phy0", "phy1"; | 24 | phy-names = "phy0", "phy1"; |
| @@ -28,7 +28,7 @@ · 3 unmodified lines | |||
| 28 | 28 | ||
| 29 | bdc0: usb@2000 { | 29 | bdc0: usb@2000 { |
| 30 | compatible = "brcm,bdc-v0.16"; | 30 | compatible = "brcm,bdc-v0.16"; |
| 31 | reg = <0x00002000 0x1000>; | 31 | reg = <0x0 0x00002000 0x0 0x1000>; |
| 32 | interrupts = <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>; | 32 | interrupts = <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>; |
| 33 | phys = <&usbphy0 0>, <&usbphy0 1>; | 33 | phys = <&usbphy0 0>, <&usbphy0 1>; |
| 34 | phy-names = "phy0", "phy1"; | 34 | phy-names = "phy0", "phy1"; |
| @@ -38,21 +38,21 @@ · 3 unmodified lines | |||
| 38 | 38 | ||
| 39 | usbphy1: usb-phy@10000 { | 39 | usbphy1: usb-phy@10000 { |
| 40 | compatible = "brcm,sr-usb-combo-phy"; | 40 | compatible = "brcm,sr-usb-combo-phy"; |
| 41 | reg = <0x00010000 0x100>; | 41 | reg = <0x0 0x00010000 0x0 0x100>; |
| 42 | #phy-cells = <1>; | 42 | #phy-cells = <1>; |
| 43 | status = "disabled"; | 43 | status = "disabled"; |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | usbphy2: usb-phy@20000 { | 46 | usbphy2: usb-phy@20000 { |
| 47 | compatible = "brcm,sr-usb-hs-phy"; | 47 | compatible = "brcm,sr-usb-hs-phy"; |
| 48 | reg = <0x00020000 0x100>; | 48 | reg = <0x0 0x00020000 0x0 0x100>; |
| 49 | #phy-cells = <0>; | 49 | #phy-cells = <0>; |
| 50 | status = "disabled"; | 50 | status = "disabled"; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | xhci1: usb@11000 { | 53 | xhci1: usb@11000 { |
| 54 | compatible = "generic-xhci"; | 54 | compatible = "generic-xhci"; |
| 55 | reg = <0x00011000 0x1000>; | 55 | reg = <0x0 0x00011000 0x0 0x1000>; |
| 56 | interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>; | 56 | interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>; |
| 57 | phys = <&usbphy1 1>, <&usbphy2>, <&usbphy1 0>; | 57 | phys = <&usbphy1 1>, <&usbphy2>, <&usbphy1 0>; |
| 58 | phy-names = "phy0", "phy1", "phy2"; | 58 | phy-names = "phy0", "phy1", "phy2"; |
| @@ -62,7 +62,7 @@ · 3 unmodified lines | |||
| 62 | 62 | ||
| 63 | bdc1: usb@21000 { | 63 | bdc1: usb@21000 { |
| 64 | compatible = "brcm,bdc-v0.16"; | 64 | compatible = "brcm,bdc-v0.16"; |
| 65 | reg = <0x00021000 0x1000>; | 65 | reg = <0x0 0x00021000 0x0 0x1000>; |
| 66 | interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; | 66 | interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; |
| 67 | phys = <&usbphy2>; | 67 | phys = <&usbphy2>; |
| 68 | phy-names = "phy0"; | 68 | phy-names = "phy0"; |
| @@ -10,18 +10,6 @@ · 9 unmodified lines | |||
| 10 | model = "NVIDIA Jetson TX2 Developer Kit"; | 10 | model = "NVIDIA Jetson TX2 Developer Kit"; |
| 11 | compatible = "nvidia,p2771-0000", "nvidia,tegra186"; | 11 | compatible = "nvidia,p2771-0000", "nvidia,tegra186"; |
| 12 | 12 | ||
| 13 | aconnect { | ||
| 14 | status = "okay"; | ||
| 15 | |||
| 16 | dma-controller@2930000 { | ||
| 17 | status = "okay"; | ||
| 18 | }; | ||
| 19 | |||
| 20 | interrupt-controller@2a40000 { | ||
| 21 | status = "okay"; | ||
| 22 | }; | ||
| 23 | }; | ||
| 24 | |||
| 25 | i2c@3160000 { | 13 | i2c@3160000 { |
| 26 | power-monitor@42 { | 14 | power-monitor@42 { |
| 27 | compatible = "ti,ina3221"; | 15 | compatible = "ti,ina3221"; |
| @@ -54,7 +54,7 @@ · 53 unmodified lines | |||
| 54 | status = "okay"; | 54 | status = "okay"; |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | serial@c280000 { | 57 | serial@3100000 { |
| 58 | status = "okay"; | 58 | status = "okay"; |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| @@ -1161,7 +1161,7 @@ · 1160 unmodified lines | |||
| 1161 | 1161 | ||
| 1162 | hsp_aon: hsp@c150000 { | 1162 | hsp_aon: hsp@c150000 { |
| 1163 | compatible = "nvidia,tegra194-hsp", "nvidia,tegra186-hsp"; | 1163 | compatible = "nvidia,tegra194-hsp", "nvidia,tegra186-hsp"; |
| 1164 | reg = <0x0c150000 0xa0000>; | 1164 | reg = <0x0c150000 0x90000>; |
| 1165 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, | 1165 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, |
| 1166 | <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, | 1166 | <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, |
| 1167 | <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, | 1167 | <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, |
| @@ -1663,16 +1663,6 @@ · 1662 unmodified lines | |||
| 1663 | vin-supply = <&vdd_5v0_sys>; | 1663 | vin-supply = <&vdd_5v0_sys>; |
| 1664 | }; | 1664 | }; |
| 1665 | 1665 | ||
| 1666 | vdd_usb_vbus_otg: regulator@11 { | ||
| 1667 | compatible = "regulator-fixed"; | ||
| 1668 | regulator-name = "USB_VBUS_EN0"; | ||
| 1669 | regulator-min-microvolt = <5000000>; | ||
| 1670 | regulator-max-microvolt = <5000000>; | ||
| 1671 | gpio = <&gpio TEGRA_GPIO(CC, 4) GPIO_ACTIVE_HIGH>; | ||
| 1672 | enable-active-high; | ||
| 1673 | vin-supply = <&vdd_5v0_sys>; | ||
| 1674 | }; | ||
| 1675 | |||
| 1676 | vdd_hdmi: regulator@10 { | 1666 | vdd_hdmi: regulator@10 { |
| 1677 | compatible = "regulator-fixed"; | 1667 | compatible = "regulator-fixed"; |
| 1678 | regulator-name = "VDD_HDMI_5V0"; | 1668 | regulator-name = "VDD_HDMI_5V0"; |
| @@ -1712,4 +1702,14 @@ · 33 unmodified lines | |||
| 1712 | enable-active-high; | 1702 | enable-active-high; |
| 1713 | vin-supply = <&vdd_3v3_sys>; | 1703 | vin-supply = <&vdd_3v3_sys>; |
| 1714 | }; | 1704 | }; |
| 1705 | |||
| 1706 | vdd_usb_vbus_otg: regulator@14 { | ||
| 1707 | compatible = "regulator-fixed"; | ||
| 1708 | regulator-name = "USB_VBUS_EN0"; | ||
| 1709 | regulator-min-microvolt = <5000000>; | ||
| 1710 | regulator-max-microvolt = <5000000>; | ||
| 1711 | gpio = <&gpio TEGRA_GPIO(CC, 4) GPIO_ACTIVE_HIGH>; | ||
| 1712 | enable-active-high; | ||
| 1713 | vin-supply = <&vdd_5v0_sys>; | ||
| 1714 | }; | ||
| 1715 | }; | 1715 | }; |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | compatible = "nvidia,tegra234-vdk", "nvidia,tegra234"; | 8 | compatible = "nvidia,tegra234-vdk", "nvidia,tegra234"; |
| 9 | 9 | ||
| 10 | aliases { | 10 | aliases { |
| 11 | sdhci3 = "/cbb@0/sdhci@3460000"; | 11 | mmc3 = "/bus@0/mmc@3460000"; |
| 12 | serial0 = &uarta; | 12 | serial0 = &uarta; |
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| @@ -17,12 +17,12 @@ · 2 unmodified lines | |||
| 17 | stdout-path = "serial0:115200n8"; | 17 | stdout-path = "serial0:115200n8"; |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | cbb@0 { | 20 | bus@0 { |
| 21 | serial@3100000 { | 21 | serial@3100000 { |
| 22 | status = "okay"; | 22 | status = "okay"; |
| 23 | }; | 23 | }; |
| 24 | 24 | ||
| 25 | sdhci@3460000 { | 25 | mmc@3460000 { |
| 26 | status = "okay"; | 26 | status = "okay"; |
| 27 | bus-width = <8>; | 27 | bus-width = <8>; |
| 28 | non-removable; | 28 | non-removable; |
| @@ -179,22 +179,22 @@ · 178 unmodified lines | |||
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | soc: soc { | 181 | soc: soc { |
| 182 | #address-cells = <1>; | 182 | #address-cells = <2>; |
| 183 | #size-cells = <1>; | 183 | #size-cells = <2>; |
| 184 | ranges = <0 0 0 0xffffffff>; | 184 | ranges = <0 0 0 0 0x0 0xffffffff>; |
| 185 | dma-ranges; | 185 | dma-ranges; |
| 186 | compatible = "simple-bus"; | 186 | compatible = "simple-bus"; |
| 187 | 187 | ||
| 188 | prng: qrng@e1000 { | 188 | prng: qrng@e1000 { |
| 189 | compatible = "qcom,prng-ee"; | 189 | compatible = "qcom,prng-ee"; |
| 190 | reg = <0xe3000 0x1000>; | 190 | reg = <0x0 0xe3000 0x0 0x1000>; |
| 191 | clocks = <&gcc GCC_PRNG_AHB_CLK>; | 191 | clocks = <&gcc GCC_PRNG_AHB_CLK>; |
| 192 | clock-names = "core"; | 192 | clock-names = "core"; |
| 193 | }; | 193 | }; |
| 194 | 194 | ||
| 195 | cryptobam: dma@704000 { | 195 | cryptobam: dma@704000 { |
| 196 | compatible = "qcom,bam-v1.7.0"; | 196 | compatible = "qcom,bam-v1.7.0"; |
| 197 | reg = <0x00704000 0x20000>; | 197 | reg = <0x0 0x00704000 0x0 0x20000>; |
| 198 | interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; | 198 | interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; |
| 199 | clocks = <&gcc GCC_CRYPTO_AHB_CLK>; | 199 | clocks = <&gcc GCC_CRYPTO_AHB_CLK>; |
| 200 | clock-names = "bam_clk"; | 200 | clock-names = "bam_clk"; |
| @@ -206,7 +206,7 @@ · 5 unmodified lines | |||
| 206 | 206 | ||
| 207 | crypto: crypto@73a000 { | 207 | crypto: crypto@73a000 { |
| 208 | compatible = "qcom,crypto-v5.1"; | 208 | compatible = "qcom,crypto-v5.1"; |
| 209 | reg = <0x0073a000 0x6000>; | 209 | reg = <0x0 0x0073a000 0x0 0x6000>; |
| 210 | clocks = <&gcc GCC_CRYPTO_AHB_CLK>, | 210 | clocks = <&gcc GCC_CRYPTO_AHB_CLK>, |
| 211 | <&gcc GCC_CRYPTO_AXI_CLK>, | 211 | <&gcc GCC_CRYPTO_AXI_CLK>, |
| 212 | <&gcc GCC_CRYPTO_CLK>; | 212 | <&gcc GCC_CRYPTO_CLK>; |
| @@ -217,7 +217,7 @@ · 4 unmodified lines | |||
| 217 | 217 | ||
| 218 | tlmm: pinctrl@1000000 { | 218 | tlmm: pinctrl@1000000 { |
| 219 | compatible = "qcom,ipq6018-pinctrl"; | 219 | compatible = "qcom,ipq6018-pinctrl"; |
| 220 | reg = <0x01000000 0x300000>; | 220 | reg = <0x0 0x01000000 0x0 0x300000>; |
| 221 | interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; | 221 | interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; |
| 222 | gpio-controller; | 222 | gpio-controller; |
| 223 | #gpio-cells = <2>; | 223 | #gpio-cells = <2>; |
| @@ -235,7 +235,7 @@ · 11 unmodified lines | |||
| 235 | 235 | ||
| 236 | gcc: gcc@1800000 { | 236 | gcc: gcc@1800000 { |
| 237 | compatible = "qcom,gcc-ipq6018"; | 237 | compatible = "qcom,gcc-ipq6018"; |
| 238 | reg = <0x01800000 0x80000>; | 238 | reg = <0x0 0x01800000 0x0 0x80000>; |
| 239 | clocks = <&xo>, <&sleep_clk>; | 239 | clocks = <&xo>, <&sleep_clk>; |
| 240 | clock-names = "xo", "sleep_clk"; | 240 | clock-names = "xo", "sleep_clk"; |
| 241 | #clock-cells = <1>; | 241 | #clock-cells = <1>; |
| @@ -244,17 +244,17 @@ · 2 unmodified lines | |||
| 244 | 244 | ||
| 245 | tcsr_mutex_regs: syscon@1905000 { | 245 | tcsr_mutex_regs: syscon@1905000 { |
| 246 | compatible = "syscon"; | 246 | compatible = "syscon"; |
| 247 | reg = <0x01905000 0x8000>; | 247 | reg = <0x0 0x01905000 0x0 0x8000>; |
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | tcsr_q6: syscon@1945000 { | 250 | tcsr_q6: syscon@1945000 { |
| 251 | compatible = "syscon"; | 251 | compatible = "syscon"; |
| 252 | reg = <0x01945000 0xe000>; | 252 | reg = <0x0 0x01945000 0x0 0xe000>; |
| 253 | }; | 253 | }; |
| 254 | 254 | ||
| 255 | blsp_dma: dma@7884000 { | 255 | blsp_dma: dma@7884000 { |
| 256 | compatible = "qcom,bam-v1.7.0"; | 256 | compatible = "qcom,bam-v1.7.0"; |
| 257 | reg = <0x07884000 0x2b000>; | 257 | reg = <0x0 0x07884000 0x0 0x2b000>; |
| 258 | interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; | 258 | interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; |
| 259 | clocks = <&gcc GCC_BLSP1_AHB_CLK>; | 259 | clocks = <&gcc GCC_BLSP1_AHB_CLK>; |
| 260 | clock-names = "bam_clk"; | 260 | clock-names = "bam_clk"; |
| @@ -264,7 +264,7 @@ · 3 unmodified lines | |||
| 264 | 264 | ||
| 265 | blsp1_uart3: serial@78b1000 { | 265 | blsp1_uart3: serial@78b1000 { |
| 266 | compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; | 266 | compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; |
| 267 | reg = <0x078b1000 0x200>; | 267 | reg = <0x0 0x078b1000 0x0 0x200>; |
| 268 | interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>; | 268 | interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>; |
| 269 | clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>, | 269 | clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>, |
| 270 | <&gcc GCC_BLSP1_AHB_CLK>; | 270 | <&gcc GCC_BLSP1_AHB_CLK>; |
| @@ -276,7 +276,7 @@ · 5 unmodified lines | |||
| 276 | compatible = "qcom,spi-qup-v2.2.1"; | 276 | compatible = "qcom,spi-qup-v2.2.1"; |
| 277 | #address-cells = <1>; | 277 | #address-cells = <1>; |
| 278 | #size-cells = <0>; | 278 | #size-cells = <0>; |
| 279 | reg = <0x078b5000 0x600>; | 279 | reg = <0x0 0x078b5000 0x0 0x600>; |
| 280 | interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; | 280 | interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; |
| 281 | spi-max-frequency = <50000000>; | 281 | spi-max-frequency = <50000000>; |
| 282 | clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, | 282 | clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, |
| @@ -291,7 +291,7 @@ · 8 unmodified lines | |||
| 291 | compatible = "qcom,spi-qup-v2.2.1"; | 291 | compatible = "qcom,spi-qup-v2.2.1"; |
| 292 | #address-cells = <1>; | 292 | #address-cells = <1>; |
| 293 | #size-cells = <0>; | 293 | #size-cells = <0>; |
| 294 | reg = <0x078b6000 0x600>; | 294 | reg = <0x0 0x078b6000 0x0 0x600>; |
| 295 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; | 295 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; |
| 296 | spi-max-frequency = <50000000>; | 296 | spi-max-frequency = <50000000>; |
| 297 | clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, | 297 | clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, |
| @@ -306,7 +306,7 @@ · 8 unmodified lines | |||
| 306 | compatible = "qcom,i2c-qup-v2.2.1"; | 306 | compatible = "qcom,i2c-qup-v2.2.1"; |
| 307 | #address-cells = <1>; | 307 | #address-cells = <1>; |
| 308 | #size-cells = <0>; | 308 | #size-cells = <0>; |
| 309 | reg = <0x078b6000 0x600>; | 309 | reg = <0x0 0x078b6000 0x0 0x600>; |
| 310 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; | 310 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; |
| 311 | clocks = <&gcc GCC_BLSP1_AHB_CLK>, | 311 | clocks = <&gcc GCC_BLSP1_AHB_CLK>, |
| 312 | <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; | 312 | <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; |
| @@ -321,7 +321,7 @@ · 8 unmodified lines | |||
| 321 | compatible = "qcom,i2c-qup-v2.2.1"; | 321 | compatible = "qcom,i2c-qup-v2.2.1"; |
| 322 | #address-cells = <1>; | 322 | #address-cells = <1>; |
| 323 | #size-cells = <0>; | 323 | #size-cells = <0>; |
| 324 | reg = <0x078b7000 0x600>; | 324 | reg = <0x0 0x078b7000 0x0 0x600>; |
| 325 | interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; | 325 | interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; |
| 326 | clocks = <&gcc GCC_BLSP1_AHB_CLK>, | 326 | clocks = <&gcc GCC_BLSP1_AHB_CLK>, |
| 327 | <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>; | 327 | <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>; |
| @@ -336,24 +336,24 @@ · 8 unmodified lines | |||
| 336 | compatible = "qcom,msm-qgic2"; | 336 | compatible = "qcom,msm-qgic2"; |
| 337 | interrupt-controller; | 337 | interrupt-controller; |
| 338 | #interrupt-cells = <0x3>; | 338 | #interrupt-cells = <0x3>; |
| 339 | reg = <0x0b000000 0x1000>, /*GICD*/ | 339 | reg = <0x0 0x0b000000 0x0 0x1000>, /*GICD*/ |
| 340 | <0x0b002000 0x1000>, /*GICC*/ | 340 | <0x0 0x0b002000 0x0 0x1000>, /*GICC*/ |
| 341 | <0x0b001000 0x1000>, /*GICH*/ | 341 | <0x0 0x0b001000 0x0 0x1000>, /*GICH*/ |
| 342 | <0x0b004000 0x1000>; /*GICV*/ | 342 | <0x0 0x0b004000 0x0 0x1000>; /*GICV*/ |
| 343 | interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; | 343 | interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; |
| 344 | }; | 344 | }; |
| 345 | 345 | ||
| 346 | watchdog@b017000 { | 346 | watchdog@b017000 { |
| 347 | compatible = "qcom,kpss-wdt"; | 347 | compatible = "qcom,kpss-wdt"; |
| 348 | interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>; | 348 | interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>; |
| 349 | reg = <0x0b017000 0x40>; | 349 | reg = <0x0 0x0b017000 0x0 0x40>; |
| 350 | clocks = <&sleep_clk>; | 350 | clocks = <&sleep_clk>; |
| 351 | timeout-sec = <10>; | 351 | timeout-sec = <10>; |
| 352 | }; | 352 | }; |
| 353 | 353 | ||
| 354 | apcs_glb: mailbox@b111000 { | 354 | apcs_glb: mailbox@b111000 { |
| 355 | compatible = "qcom,ipq6018-apcs-apps-global"; | 355 | compatible = "qcom,ipq6018-apcs-apps-global"; |
| 356 | reg = <0x0b111000 0x1000>; | 356 | reg = <0x0 0x0b111000 0x0 0x1000>; |
| 357 | #clock-cells = <1>; | 357 | #clock-cells = <1>; |
| 358 | clocks = <&a53pll>, <&xo>; | 358 | clocks = <&a53pll>, <&xo>; |
| 359 | clock-names = "pll", "xo"; | 359 | clock-names = "pll", "xo"; |
| @@ -362,7 +362,7 @@ · 2 unmodified lines | |||
| 362 | 362 | ||
| 363 | a53pll: clock@b116000 { | 363 | a53pll: clock@b116000 { |
| 364 | compatible = "qcom,ipq6018-a53pll"; | 364 | compatible = "qcom,ipq6018-a53pll"; |
| 365 | reg = <0x0b116000 0x40>; | 365 | reg = <0x0 0x0b116000 0x0 0x40>; |
| 366 | #clock-cells = <0>; | 366 | #clock-cells = <0>; |
| 367 | clocks = <&xo>; | 367 | clocks = <&xo>; |
| 368 | clock-names = "xo"; | 368 | clock-names = "xo"; |
| @@ -377,68 +377,68 @@ · 8 unmodified lines | |||
| 377 | }; | 377 | }; |
| 378 | 378 | ||
| 379 | timer@b120000 { | 379 | timer@b120000 { |
| 380 | #address-cells = <1>; | 380 | #address-cells = <2>; |
| 381 | #size-cells = <1>; | 381 | #size-cells = <2>; |
| 382 | ranges; | 382 | ranges; |
| 383 | compatible = "arm,armv7-timer-mem"; | 383 | compatible = "arm,armv7-timer-mem"; |
| 384 | reg = <0x0b120000 0x1000>; | 384 | reg = <0x0 0x0b120000 0x0 0x1000>; |
| 385 | clock-frequency = <19200000>; | 385 | clock-frequency = <19200000>; |
| 386 | 386 | ||
| 387 | frame@b120000 { | 387 | frame@b120000 { |
| 388 | frame-number = <0>; | 388 | frame-number = <0>; |
| 389 | interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, | 389 | interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, |
| 390 | <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; | 390 | <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; |
| 391 | reg = <0x0b121000 0x1000>, | 391 | reg = <0x0 0x0b121000 0x0 0x1000>, |
| 392 | <0x0b122000 0x1000>; | 392 | <0x0 0x0b122000 0x0 0x1000>; |
| 393 | }; | 393 | }; |
| 394 | 394 | ||
| 395 | frame@b123000 { | 395 | frame@b123000 { |
| 396 | frame-number = <1>; | 396 | frame-number = <1>; |
| 397 | interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; | 397 | interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; |
| 398 | reg = <0xb123000 0x1000>; | 398 | reg = <0x0 0xb123000 0x0 0x1000>; |
| 399 | status = "disabled"; | 399 | status = "disabled"; |
| 400 | }; | 400 | }; |
| 401 | 401 | ||
| 402 | frame@b124000 { | 402 | frame@b124000 { |
| 403 | frame-number = <2>; | 403 | frame-number = <2>; |
| 404 | interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; | 404 | interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; |
| 405 | reg = <0x0b124000 0x1000>; | 405 | reg = <0x0 0x0b124000 0x0 0x1000>; |
| 406 | status = "disabled"; | 406 | status = "disabled"; |
| 407 | }; | 407 | }; |
| 408 | 408 | ||
| 409 | frame@b125000 { | 409 | frame@b125000 { |
| 410 | frame-number = <3>; | 410 | frame-number = <3>; |
| 411 | interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; | 411 | interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; |
| 412 | reg = <0x0b125000 0x1000>; | 412 | reg = <0x0 0x0b125000 0x0 0x1000>; |
| 413 | status = "disabled"; | 413 | status = "disabled"; |
| 414 | }; | 414 | }; |
| 415 | 415 | ||
| 416 | frame@b126000 { | 416 | frame@b126000 { |
| 417 | frame-number = <4>; | 417 | frame-number = <4>; |
| 418 | interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; | 418 | interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; |
| 419 | reg = <0x0b126000 0x1000>; | 419 | reg = <0x0 0x0b126000 0x0 0x1000>; |
| 420 | status = "disabled"; | 420 | status = "disabled"; |
| 421 | }; | 421 | }; |
| 422 | 422 | ||
| 423 | frame@b127000 { | 423 | frame@b127000 { |
| 424 | frame-number = <5>; | 424 | frame-number = <5>; |
| 425 | interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; | 425 | interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; |
| 426 | reg = <0x0b127000 0x1000>; | 426 | reg = <0x0 0x0b127000 0x0 0x1000>; |
| 427 | status = "disabled"; | 427 | status = "disabled"; |
| 428 | }; | 428 | }; |
| 429 | 429 | ||
| 430 | frame@b128000 { | 430 | frame@b128000 { |
| 431 | frame-number = <6>; | 431 | frame-number = <6>; |
| 432 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; | 432 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
| 433 | reg = <0x0b128000 0x1000>; | 433 | reg = <0x0 0x0b128000 0x0 0x1000>; |
| 434 | status = "disabled"; | 434 | status = "disabled"; |
| 435 | }; | 435 | }; |
| 436 | }; | 436 | }; |
| 437 | 437 | ||
| 438 | q6v5_wcss: remoteproc@cd00000 { | 438 | q6v5_wcss: remoteproc@cd00000 { |
| 439 | compatible = "qcom,ipq8074-wcss-pil"; | 439 | compatible = "qcom,ipq8074-wcss-pil"; |
| 440 | reg = <0x0cd00000 0x4040>, | 440 | reg = <0x0 0x0cd00000 0x0 0x4040>, |
| 441 | <0x004ab000 0x20>; | 441 | <0x0 0x004ab000 0x0 0x20>; |
| 442 | reg-names = "qdsp6", | 442 | reg-names = "qdsp6", |
| 443 | "rmb"; | 443 | "rmb"; |
| 444 | interrupts-extended = <&intc GIC_SPI 325 IRQ_TYPE_EDGE_RISING>, | 444 | interrupts-extended = <&intc GIC_SPI 325 IRQ_TYPE_EDGE_RISING>, |
| @@ -243,7 +243,6 @@ · 242 unmodified lines | |||
| 243 | interrupts = <RK_PB2 IRQ_TYPE_LEVEL_LOW>; | 243 | interrupts = <RK_PB2 IRQ_TYPE_LEVEL_LOW>; |
| 244 | pinctrl-names = "default"; | 244 | pinctrl-names = "default"; |
| 245 | pinctrl-0 = <&pmic_int>; | 245 | pinctrl-0 = <&pmic_int>; |
| 246 | rockchip,system-power-controller; | ||
| 247 | wakeup-source; | 246 | wakeup-source; |
| 248 | #clock-cells = <1>; | 247 | #clock-cells = <1>; |
| 249 | clock-output-names = "rk808-clkout1", "xin32k"; | 248 | clock-output-names = "rk808-clkout1", "xin32k"; |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | |||
| 20 | gmac_clk: gmac-clock { | 20 | gmac_clk: gmac-clock { |
| 21 | compatible = "fixed-clock"; | 21 | compatible = "fixed-clock"; |
| 22 | clock-frequency = <125000000>; | 22 | clock-frequency = <125000000>; |
| 23 | clock-output-names = "gmac_clk"; | 23 | clock-output-names = "gmac_clkin"; |
| 24 | #clock-cells = <0>; | 24 | #clock-cells = <0>; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| @@ -74,14 +74,14 @@ · 73 unmodified lines | |||
| 74 | label = "red:diy"; | 74 | label = "red:diy"; |
| 75 | gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; | 75 | gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; |
| 76 | default-state = "off"; | 76 | default-state = "off"; |
| 77 | linux,default-trigger = "mmc1"; | 77 | linux,default-trigger = "mmc2"; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | yellow_led: led-2 { | 80 | yellow_led: led-2 { |
| 81 | label = "yellow:yellow-led"; | 81 | label = "yellow:yellow-led"; |
| 82 | gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; | 82 | gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; |
| 83 | default-state = "off"; | 83 | default-state = "off"; |
| 84 | linux,default-trigger = "mmc0"; | 84 | linux,default-trigger = "mmc1"; |
| 85 | }; | 85 | }; |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| @@ -29,6 +29,9 @@ · 28 unmodified lines | |||
| 29 | i2c6 = &i2c6; | 29 | i2c6 = &i2c6; |
| 30 | i2c7 = &i2c7; | 30 | i2c7 = &i2c7; |
| 31 | i2c8 = &i2c8; | 31 | i2c8 = &i2c8; |
| 32 | mmc0 = &sdio0; | ||
| 33 | mmc1 = &sdmmc; | ||
| 34 | mmc2 = &sdhci; | ||
| 32 | serial0 = &uart0; | 35 | serial0 = &uart0; |
| 33 | serial1 = &uart1; | 36 | serial1 = &uart1; |
| 34 | serial2 = &uart2; | 37 | serial2 = &uart2; |
| @@ -115,8 +115,6 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; · 114 unmodified lines | |||
| 115 | #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) | 115 | #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) |
| 116 | #define pte_valid_not_user(pte) \ | 116 | #define pte_valid_not_user(pte) \ |
| 117 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) | 117 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) |
| 118 | #define pte_valid_young(pte) \ | ||
| 119 | ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) | ||
| 120 | #define pte_valid_user(pte) \ | 118 | #define pte_valid_user(pte) \ |
| 121 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) | 119 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) |
| 122 | 120 | ||
| @@ -124,9 +122,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; · 1 unmodified line | |||
| 124 | * Could the pte be present in the TLB? We must check mm_tlb_flush_pending | 122 | * Could the pte be present in the TLB? We must check mm_tlb_flush_pending |
| 125 | * so that we don't erroneously return false for pages that have been | 123 | * so that we don't erroneously return false for pages that have been |
| 126 | * remapped as PROT_NONE but are yet to be flushed from the TLB. | 124 | * remapped as PROT_NONE but are yet to be flushed from the TLB. |
| 125 | * Note that we can't make any assumptions based on the state of the access | ||
| 126 | * flag, since ptep_clear_flush_young() elides a DSB when invalidating the | ||
| 127 | * TLB. | ||
| 127 | */ | 128 | */ |
| 128 | #define pte_accessible(mm, pte) \ | 129 | #define pte_accessible(mm, pte) \ |
| 129 | (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid_young(pte)) | 130 | (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte)) |
| 130 | 131 | ||
| 131 | /* | 132 | /* |
| 132 | * p??_access_permitted() is true for valid user mappings (subject to the | 133 | * p??_access_permitted() is true for valid user mappings (subject to the |
| @@ -164,13 +165,6 @@ static inline pmd_t set_pmd_bit(pmd_t pmd, pgprot_t prot) · 31 unmodified lines | |||
| 164 | return pmd; | 165 | return pmd; |
| 165 | } | 166 | } |
| 166 | 167 | ||
| 167 | static inline pte_t pte_wrprotect(pte_t pte) | ||
| 168 | { | ||
| 169 | pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); | ||
| 170 | pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); | ||
| 171 | return pte; | ||
| 172 | } | ||
| 173 | |||
| 174 | static inline pte_t pte_mkwrite(pte_t pte) | 168 | static inline pte_t pte_mkwrite(pte_t pte) |
| 175 | { | 169 | { |
| 176 | pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); | 170 | pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); |
| @@ -196,6 +190,20 @@ static inline pte_t pte_mkdirty(pte_t pte) · 19 unmodified lines | |||
| 196 | return pte; | 190 | return pte; |
| 197 | } | 191 | } |
| 198 | 192 | ||
| 193 | static inline pte_t pte_wrprotect(pte_t pte) | ||
| 194 | { | ||
| 195 | /* | ||
| 196 | * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY | ||
| 197 | * clear), set the PTE_DIRTY bit. | ||
| 198 | */ | ||
| 199 | if (pte_hw_dirty(pte)) | ||
| 200 | pte = pte_mkdirty(pte); | ||
| 201 | |||
| 202 | pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); | ||
| 203 | pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); | ||
| 204 | return pte; | ||
| 205 | } | ||
| 206 | |||
| 199 | static inline pte_t pte_mkold(pte_t pte) | 207 | static inline pte_t pte_mkold(pte_t pte) |
| 200 | { | 208 | { |
| 201 | return clear_pte_bit(pte, __pgprot(PTE_AF)); | 209 | return clear_pte_bit(pte, __pgprot(PTE_AF)); |
| @@ -845,12 +853,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres · 643 unmodified lines | |||
| 845 | pte = READ_ONCE(*ptep); | 853 | pte = READ_ONCE(*ptep); |
| 846 | do { | 854 | do { |
| 847 | old_pte = pte; | 855 | old_pte = pte; |
| 848 | /* | ||
| 849 | * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY | ||
| 850 | * clear), set the PTE_DIRTY bit. | ||
| 851 | */ | ||
| 852 | if (pte_hw_dirty(pte)) | ||
| 853 | pte = pte_mkdirty(pte); | ||
| 854 | pte = pte_wrprotect(pte); | 856 | pte = pte_wrprotect(pte); |
| 855 | pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), | 857 | pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), |
| 856 | pte_val(old_pte), pte_val(pte)); | 858 | pte_val(old_pte), pte_val(pte)); |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | |||
| 7 | #ifndef _ARM_PROBES_H | 7 | #ifndef _ARM_PROBES_H |
| 8 | #define _ARM_PROBES_H | 8 | #define _ARM_PROBES_H |
| 9 | 9 | ||
| 10 | #include <asm/insn.h> | ||
| 11 | |||
| 10 | typedef u32 probe_opcode_t; | 12 | typedef u32 probe_opcode_t; |
| 11 | typedef void (probes_handler_t) (u32 opcode, long addr, struct pt_regs *); | 13 | typedef void (probes_handler_t) (u32 opcode, long addr, struct pt_regs *); |
| 12 | 14 | ||
| @@ -13,6 +13,11 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | SECTIONS { | 14 | SECTIONS { |
| 15 | HYP_SECTION(.text) | 15 | HYP_SECTION(.text) |
| 16 | /* | ||
| 17 | * .hyp..data..percpu needs to be page aligned to maintain the same | ||
| 18 | * alignment for when linking into vmlinux. | ||
| 19 | */ | ||
| 20 | . = ALIGN(PAGE_SIZE); | ||
| 16 | HYP_SECTION_NAME(.data..percpu) : { | 21 | HYP_SECTION_NAME(.data..percpu) : { |
| 17 | PERCPU_INPUT(L1_CACHE_BYTES) | 22 | PERCPU_INPUT(L1_CACHE_BYTES) |
| 18 | } | 23 | } |
| @@ -273,6 +273,23 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu, · 272 unmodified lines | |||
| 273 | return extract_bytes(value, addr & 7, len); | 273 | return extract_bytes(value, addr & 7, len); |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static unsigned long vgic_uaccess_read_v3r_typer(struct kvm_vcpu *vcpu, | ||
| 277 | gpa_t addr, unsigned int len) | ||
| 278 | { | ||
| 279 | unsigned long mpidr = kvm_vcpu_get_mpidr_aff(vcpu); | ||
| 280 | int target_vcpu_id = vcpu->vcpu_id; | ||
| 281 | u64 value; | ||
| 282 | |||
| 283 | value = (u64)(mpidr & GENMASK(23, 0)) << 32; | ||
| 284 | value |= ((target_vcpu_id & 0xffff) << 8); | ||
| 285 | |||
| 286 | if (vgic_has_its(vcpu->kvm)) | ||
| 287 | value |= GICR_TYPER_PLPIS; | ||
| 288 | |||
| 289 | /* reporting of the Last bit is not supported for userspace */ | ||
| 290 | return extract_bytes(value, addr & 7, len); | ||
| 291 | } | ||
| 292 | |||
| 276 | static unsigned long vgic_mmio_read_v3r_iidr(struct kvm_vcpu *vcpu, | 293 | static unsigned long vgic_mmio_read_v3r_iidr(struct kvm_vcpu *vcpu, |
| 277 | gpa_t addr, unsigned int len) | 294 | gpa_t addr, unsigned int len) |
| 278 | { | 295 | { |
| @@ -593,8 +610,9 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = { · 314 unmodified lines | |||
| 593 | REGISTER_DESC_WITH_LENGTH(GICR_IIDR, | 610 | REGISTER_DESC_WITH_LENGTH(GICR_IIDR, |
| 594 | vgic_mmio_read_v3r_iidr, vgic_mmio_write_wi, 4, | 611 | vgic_mmio_read_v3r_iidr, vgic_mmio_write_wi, 4, |
| 595 | VGIC_ACCESS_32bit), | 612 | VGIC_ACCESS_32bit), |
| 596 | REGISTER_DESC_WITH_LENGTH(GICR_TYPER, | 613 | REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_TYPER, |
| 597 | vgic_mmio_read_v3r_typer, vgic_mmio_write_wi, 8, | 614 | vgic_mmio_read_v3r_typer, vgic_mmio_write_wi, |
| 615 | vgic_uaccess_read_v3r_typer, vgic_mmio_uaccess_write_wi, 8, | ||
| 598 | VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), | 616 | VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), |
| 599 | REGISTER_DESC_WITH_LENGTH(GICR_WAKER, | 617 | REGISTER_DESC_WITH_LENGTH(GICR_WAKER, |
| 600 | vgic_mmio_read_raz, vgic_mmio_write_wi, 4, | 618 | vgic_mmio_read_raz, vgic_mmio_write_wi, 4, |
| @@ -18,4 +18,10 @@ · 17 unmodified lines | |||
| 18 | #endif | 18 | #endif |
| 19 | 19 | ||
| 20 | #endif /* CONFIG_SPARSEMEM */ | 20 | #endif /* CONFIG_SPARSEMEM */ |
| 21 | |||
| 22 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 23 | int memory_add_physaddr_to_nid(u64 addr); | ||
| 24 | #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid | ||
| 25 | #endif | ||
| 26 | |||
| 21 | #endif /* _ASM_IA64_SPARSEMEM_H */ | 27 | #endif /* _ASM_IA64_SPARSEMEM_H */ |
| @@ -154,6 +154,7 @@ static inline void pmd_clear(pmd_t *pmdp) · 153 unmodified lines | |||
| 154 | 154 | ||
| 155 | #if defined(CONFIG_XPA) | 155 | #if defined(CONFIG_XPA) |
| 156 | 156 | ||
| 157 | #define MAX_POSSIBLE_PHYSMEM_BITS 40 | ||
| 157 | #define pte_pfn(x) (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT)) | 158 | #define pte_pfn(x) (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT)) |
| 158 | static inline pte_t | 159 | static inline pte_t |
| 159 | pfn_pte(unsigned long pfn, pgprot_t prot) | 160 | pfn_pte(unsigned long pfn, pgprot_t prot) |
| @@ -169,6 +170,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) · 9 unmodified lines | |||
| 169 | 170 | ||
| 170 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 171 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 171 | 172 | ||
| 173 | #define MAX_POSSIBLE_PHYSMEM_BITS 36 | ||
| 172 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) | 174 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) |
| 173 | 175 | ||
| 174 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) | 176 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) |
| @@ -183,6 +185,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) · 8 unmodified lines | |||
| 183 | 185 | ||
| 184 | #else | 186 | #else |
| 185 | 187 | ||
| 188 | #define MAX_POSSIBLE_PHYSMEM_BITS 32 | ||
| 186 | #ifdef CONFIG_CPU_VR41XX | 189 | #ifdef CONFIG_CPU_VR41XX |
| 187 | #define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2))) | 190 | #define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2))) |
| 188 | #define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot)) | 191 | #define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot)) |
| @@ -248,7 +248,6 @@ KBUILD_CFLAGS += $(call cc-option,-mno-string) · 247 unmodified lines | |||
| 248 | cpu-as-$(CONFIG_40x) += -Wa,-m405 | 248 | cpu-as-$(CONFIG_40x) += -Wa,-m405 |
| 249 | cpu-as-$(CONFIG_44x) += -Wa,-m440 | 249 | cpu-as-$(CONFIG_44x) += -Wa,-m440 |
| 250 | cpu-as-$(CONFIG_ALTIVEC) += $(call as-option,-Wa$(comma)-maltivec) | 250 | cpu-as-$(CONFIG_ALTIVEC) += $(call as-option,-Wa$(comma)-maltivec) |
| 251 | cpu-as-$(CONFIG_E200) += -Wa,-me200 | ||
| 252 | cpu-as-$(CONFIG_E500) += -Wa,-me500 | 251 | cpu-as-$(CONFIG_E500) += -Wa,-me500 |
| 253 | 252 | ||
| 254 | # When using '-many -mpower4' gas will first try and find a matching power4 | 253 | # When using '-many -mpower4' gas will first try and find a matching power4 |
| @@ -36,8 +36,10 @@ static inline bool pte_user(pte_t pte) · 35 unmodified lines | |||
| 36 | */ | 36 | */ |
| 37 | #ifdef CONFIG_PTE_64BIT | 37 | #ifdef CONFIG_PTE_64BIT |
| 38 | #define PTE_RPN_MASK (~((1ULL << PTE_RPN_SHIFT) - 1)) | 38 | #define PTE_RPN_MASK (~((1ULL << PTE_RPN_SHIFT) - 1)) |
| 39 | #define MAX_POSSIBLE_PHYSMEM_BITS 36 | ||
| 39 | #else | 40 | #else |
| 40 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) | 41 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) |
| 42 | #define MAX_POSSIBLE_PHYSMEM_BITS 32 | ||
| 41 | #endif | 43 | #endif |
| 42 | 44 | ||
| 43 | /* | 45 | /* |
| @@ -63,6 +63,8 @@ · 62 unmodified lines | |||
| 63 | 63 | ||
| 64 | #else /* !__ASSEMBLY__ */ | 64 | #else /* !__ASSEMBLY__ */ |
| 65 | 65 | ||
| 66 | #include <linux/jump_label.h> | ||
| 67 | |||
| 66 | DECLARE_STATIC_KEY_FALSE(uaccess_flush_key); | 68 | DECLARE_STATIC_KEY_FALSE(uaccess_flush_key); |
| 67 | 69 | ||
| 68 | #ifdef CONFIG_PPC_KUAP | 70 | #ifdef CONFIG_PPC_KUAP |
| @@ -46,5 +46,10 @@ u64 memory_hotplug_max(void); · 45 unmodified lines | |||
| 46 | #define __HAVE_ARCH_RESERVED_KERNEL_PAGES | 46 | #define __HAVE_ARCH_RESERVED_KERNEL_PAGES |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 50 | extern int create_section_mapping(unsigned long start, unsigned long end, | ||
| 51 | int nid, pgprot_t prot); | ||
| 52 | #endif | ||
| 53 | |||
| 49 | #endif /* __KERNEL__ */ | 54 | #endif /* __KERNEL__ */ |
| 50 | #endif /* _ASM_MMZONE_H_ */ | 55 | #endif /* _ASM_MMZONE_H_ */ |
| @@ -153,8 +153,10 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); · 152 unmodified lines | |||
| 153 | */ | 153 | */ |
| 154 | #if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) | 154 | #if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) |
| 155 | #define PTE_RPN_MASK (~((1ULL << PTE_RPN_SHIFT) - 1)) | 155 | #define PTE_RPN_MASK (~((1ULL << PTE_RPN_SHIFT) - 1)) |
| 156 | #define MAX_POSSIBLE_PHYSMEM_BITS 36 | ||
| 156 | #else | 157 | #else |
| 157 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) | 158 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) |
| 159 | #define MAX_POSSIBLE_PHYSMEM_BITS 32 | ||
| 158 | #endif | 160 | #endif |
| 159 | 161 | ||
| 160 | /* | 162 | /* |
| @@ -13,9 +13,9 @@ · 12 unmodified lines | |||
| 13 | #endif /* CONFIG_SPARSEMEM */ | 13 | #endif /* CONFIG_SPARSEMEM */ |
| 14 | 14 | ||
| 15 | #ifdef CONFIG_MEMORY_HOTPLUG | 15 | #ifdef CONFIG_MEMORY_HOTPLUG |
| 16 | extern int create_section_mapping(unsigned long start, unsigned long end, | ||
| 17 | int nid, pgprot_t prot); | ||
| 18 | extern int remove_section_mapping(unsigned long start, unsigned long end); | 16 | extern int remove_section_mapping(unsigned long start, unsigned long end); |
| 17 | extern int memory_add_physaddr_to_nid(u64 start); | ||
| 18 | #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid | ||
| 19 | 19 | ||
| 20 | #ifdef CONFIG_NUMA | 20 | #ifdef CONFIG_NUMA |
| 21 | extern int hot_add_scn_to_nid(unsigned long scn_addr); | 21 | extern int hot_add_scn_to_nid(unsigned long scn_addr); |
| @@ -26,6 +26,5 @@ static inline int hot_add_scn_to_nid(unsigned long scn_addr) · 4 unmodified lines | |||
| 26 | } | 26 | } |
| 27 | #endif /* CONFIG_NUMA */ | 27 | #endif /* CONFIG_NUMA */ |
| 28 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 28 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
| 29 | |||
| 30 | #endif /* __KERNEL__ */ | 29 | #endif /* __KERNEL__ */ |
| 31 | #endif /* _ASM_POWERPC_SPARSEMEM_H */ | 30 | #endif /* _ASM_POWERPC_SPARSEMEM_H */ |
| @@ -1000,8 +1000,6 @@ TRAMP_REAL_BEGIN(system_reset_idle_wake) · 999 unmodified lines | |||
| 1000 | * Vectors for the FWNMI option. Share common code. | 1000 | * Vectors for the FWNMI option. Share common code. |
| 1001 | */ | 1001 | */ |
| 1002 | TRAMP_REAL_BEGIN(system_reset_fwnmi) | 1002 | TRAMP_REAL_BEGIN(system_reset_fwnmi) |
| 1003 | /* XXX: fwnmi guest could run a nested/PR guest, so why no test? */ | ||
| 1004 | __IKVM_REAL(system_reset)=0 | ||
| 1005 | GEN_INT_ENTRY system_reset, virt=0 | 1003 | GEN_INT_ENTRY system_reset, virt=0 |
| 1006 | 1004 | ||
| 1007 | #endif /* CONFIG_PPC_PSERIES */ | 1005 | #endif /* CONFIG_PPC_PSERIES */ |
| @@ -1412,6 +1410,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) · 404 unmodified lines | |||
| 1412 | * If none is found, do a Linux page fault. Linux page faults can happen in | 1410 | * If none is found, do a Linux page fault. Linux page faults can happen in |
| 1413 | * kernel mode due to user copy operations of course. | 1411 | * kernel mode due to user copy operations of course. |
| 1414 | * | 1412 | * |
| 1413 | * KVM: The KVM HDSI handler may perform a load with MSR[DR]=1 in guest | ||
| 1414 | * MMU context, which may cause a DSI in the host, which must go to the | ||
| 1415 | * KVM handler. MSR[IR] is not enabled, so the real-mode handler will | ||
| 1416 | * always be used regardless of AIL setting. | ||
| 1417 | * | ||
| 1415 | * - Radix MMU | 1418 | * - Radix MMU |
| 1416 | * The hardware loads from the Linux page table directly, so a fault goes | 1419 | * The hardware loads from the Linux page table directly, so a fault goes |
| 1417 | * immediately to Linux page fault. | 1420 | * immediately to Linux page fault. |
| @@ -1422,10 +1425,8 @@ INT_DEFINE_BEGIN(data_access) · 4 unmodified lines | |||
| 1422 | IVEC=0x300 | 1425 | IVEC=0x300 |
| 1423 | IDAR=1 | 1426 | IDAR=1 |
| 1424 | IDSISR=1 | 1427 | IDSISR=1 |
| 1425 | #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE | ||
| 1426 | IKVM_SKIP=1 | 1428 | IKVM_SKIP=1 |
| 1427 | IKVM_REAL=1 | 1429 | IKVM_REAL=1 |
| 1428 | #endif | ||
| 1429 | INT_DEFINE_END(data_access) | 1430 | INT_DEFINE_END(data_access) |
| 1430 | 1431 | ||
| 1431 | EXC_REAL_BEGIN(data_access, 0x300, 0x80) | 1432 | EXC_REAL_BEGIN(data_access, 0x300, 0x80) |
| @@ -1464,6 +1465,8 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) · 32 unmodified lines | |||
| 1464 | * ppc64_bolted_size (first segment). The kernel handler must avoid stomping | 1465 | * ppc64_bolted_size (first segment). The kernel handler must avoid stomping |
| 1465 | * on user-handler data structures. | 1466 | * on user-handler data structures. |
| 1466 | * | 1467 | * |
| 1468 | * KVM: Same as 0x300, DSLB must test for KVM guest. | ||
| 1469 | * | ||
| 1467 | * A dedicated save area EXSLB is used (XXX: but it actually need not be | 1470 | * A dedicated save area EXSLB is used (XXX: but it actually need not be |
| 1468 | * these days, we could use EXGEN). | 1471 | * these days, we could use EXGEN). |
| 1469 | */ | 1472 | */ |
| @@ -1472,10 +1475,8 @@ INT_DEFINE_BEGIN(data_access_slb) · 2 unmodified lines | |||
| 1472 | IAREA=PACA_EXSLB | 1475 | IAREA=PACA_EXSLB |
| 1473 | IRECONCILE=0 | 1476 | IRECONCILE=0 |
| 1474 | IDAR=1 | 1477 | IDAR=1 |
| 1475 | #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE | ||
| 1476 | IKVM_SKIP=1 | 1478 | IKVM_SKIP=1 |
| 1477 | IKVM_REAL=1 | 1479 | IKVM_REAL=1 |
| 1478 | #endif | ||
| 1479 | INT_DEFINE_END(data_access_slb) | 1480 | INT_DEFINE_END(data_access_slb) |
| 1480 | 1481 | ||
| 1481 | EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) | 1482 | EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) |
| @@ -156,6 +156,7 @@ __after_mmu_off: · 155 unmodified lines | |||
| 156 | bl initial_bats | 156 | bl initial_bats |
| 157 | bl load_segment_registers | 157 | bl load_segment_registers |
| 158 | BEGIN_MMU_FTR_SECTION | 158 | BEGIN_MMU_FTR_SECTION |
| 159 | bl reloc_offset | ||
| 159 | bl early_hash_table | 160 | bl early_hash_table |
| 160 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) | 161 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) |
| 161 | #if defined(CONFIG_BOOTX_TEXT) | 162 | #if defined(CONFIG_BOOTX_TEXT) |
| @@ -920,7 +921,7 @@ early_hash_table: · 758 unmodified lines | |||
| 920 | ori r6, r6, 3 /* 256kB table */ | 921 | ori r6, r6, 3 /* 256kB table */ |
| 921 | mtspr SPRN_SDR1, r6 | 922 | mtspr SPRN_SDR1, r6 |
| 922 | lis r6, early_hash@h | 923 | lis r6, early_hash@h |
| 923 | lis r3, Hash@ha | 924 | addis r3, r3, Hash@ha |
| 924 | stw r6, Hash@l(r3) | 925 | stw r6, Hash@l(r3) |
| 925 | blr | 926 | blr |
| 926 | 927 | ||
| @@ -251,6 +251,13 @@ static vm_fault_t xive_native_esb_fault(struct vm_fault *vmf) · 250 unmodified lines | |||
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | state = &sb->irq_state[src]; | 253 | state = &sb->irq_state[src]; |
| 254 | |||
| 255 | /* Some sanity checking */ | ||
| 256 | if (!state->valid) { | ||
| 257 | pr_devel("%s: source %lx invalid !\n", __func__, irq); | ||
| 258 | return VM_FAULT_SIGBUS; | ||
| 259 | } | ||
| 260 | |||
| 254 | kvmppc_xive_select_irq(state, &hw_num, &xd); | 261 | kvmppc_xive_select_irq(state, &hw_num, &xd); |
| 255 | 262 | ||
| 256 | arch_spin_lock(&sb->lock); | 263 | arch_spin_lock(&sb->lock); |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | |||
| 50 | #include <asm/rtas.h> | 50 | #include <asm/rtas.h> |
| 51 | #include <asm/kasan.h> | 51 | #include <asm/kasan.h> |
| 52 | #include <asm/svm.h> | 52 | #include <asm/svm.h> |
| 53 | #include <asm/mmzone.h> | ||
| 53 | 54 | ||
| 54 | #include <mm/mmu_decl.h> | 55 | #include <mm/mmu_decl.h> |
| 55 | 56 | ||
| @@ -14,4 +14,6 @@ · 13 unmodified lines | |||
| 14 | #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) | 14 | #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) |
| 15 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) | 15 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) |
| 16 | 16 | ||
| 17 | #define MAX_POSSIBLE_PHYSMEM_BITS 34 | ||
| 18 | |||
| 17 | #endif /* _ASM_RISCV_PGTABLE_32_H */ | 19 | #endif /* _ASM_RISCV_PGTABLE_32_H */ |
| @@ -53,11 +53,11 @@ int main(void) · 52 unmodified lines | |||
| 53 | /* stack_frame offsets */ | 53 | /* stack_frame offsets */ |
| 54 | OFFSET(__SF_BACKCHAIN, stack_frame, back_chain); | 54 | OFFSET(__SF_BACKCHAIN, stack_frame, back_chain); |
| 55 | OFFSET(__SF_GPRS, stack_frame, gprs); | 55 | OFFSET(__SF_GPRS, stack_frame, gprs); |
| 56 | OFFSET(__SF_EMPTY, stack_frame, empty1); | 56 | OFFSET(__SF_EMPTY, stack_frame, empty1[0]); |
| 57 | OFFSET(__SF_SIE_CONTROL, stack_frame, empty1[0]); | 57 | OFFSET(__SF_SIE_CONTROL, stack_frame, empty1[1]); |
| 58 | OFFSET(__SF_SIE_SAVEAREA, stack_frame, empty1[1]); | 58 | OFFSET(__SF_SIE_SAVEAREA, stack_frame, empty1[2]); |
| 59 | OFFSET(__SF_SIE_REASON, stack_frame, empty1[2]); | 59 | OFFSET(__SF_SIE_REASON, stack_frame, empty1[3]); |
| 60 | OFFSET(__SF_SIE_FLAGS, stack_frame, empty1[3]); | 60 | OFFSET(__SF_SIE_FLAGS, stack_frame, empty1[4]); |
| 61 | BLANK(); | 61 | BLANK(); |
| 62 | OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); | 62 | OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); |
| 63 | BLANK(); | 63 | BLANK(); |
| @@ -1068,6 +1068,7 @@ EXPORT_SYMBOL(save_fpu_regs) · 1067 unmodified lines | |||
| 1068 | * %r4 | 1068 | * %r4 |
| 1069 | */ | 1069 | */ |
| 1070 | load_fpu_regs: | 1070 | load_fpu_regs: |
| 1071 | stnsm __SF_EMPTY(%r15),0xfc | ||
| 1071 | lg %r4,__LC_CURRENT | 1072 | lg %r4,__LC_CURRENT |
| 1072 | aghi %r4,__TASK_thread | 1073 | aghi %r4,__TASK_thread |
| 1073 | TSTMSK __LC_CPU_FLAGS,_CIF_FPU | 1074 | TSTMSK __LC_CPU_FLAGS,_CIF_FPU |
| @@ -1099,6 +1100,7 @@ load_fpu_regs: · 25 unmodified lines | |||
| 1099 | .Lload_fpu_regs_done: | 1100 | .Lload_fpu_regs_done: |
| 1100 | ni __LC_CPU_FLAGS+7,255-_CIF_FPU | 1101 | ni __LC_CPU_FLAGS+7,255-_CIF_FPU |
| 1101 | .Lload_fpu_regs_exit: | 1102 | .Lload_fpu_regs_exit: |
| 1103 | ssm __SF_EMPTY(%r15) | ||
| 1102 | BR_EX %r14 | 1104 | BR_EX %r14 |
| 1103 | .Lload_fpu_regs_end: | 1105 | .Lload_fpu_regs_end: |
| 1104 | ENDPROC(load_fpu_regs) | 1106 | ENDPROC(load_fpu_regs) |
| @@ -129,8 +129,15 @@ int uv_destroy_page(unsigned long paddr) · 128 unmodified lines | |||
| 129 | .paddr = paddr | 129 | .paddr = paddr |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | if (uv_call(0, (u64)&uvcb)) | 132 | if (uv_call(0, (u64)&uvcb)) { |
| 133 | /* | ||
| 134 | * Older firmware uses 107/d as an indication of a non secure | ||
| 135 | * page. Let us emulate the newer variant (no-op). | ||
| 136 | */ | ||
| 137 | if (uvcb.header.rc == 0x107 && uvcb.header.rrc == 0xd) | ||
| 138 | return 0; | ||
| 133 | return -EINVAL; | 139 | return -EINVAL; |
| 140 | } | ||
| 134 | return 0; | 141 | return 0; |
| 135 | } | 142 | } |
| 136 | 143 | ||
| @@ -2312,7 +2312,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd) · 2311 unmodified lines | |||
| 2312 | struct kvm_s390_pv_unp unp = {}; | 2312 | struct kvm_s390_pv_unp unp = {}; |
| 2313 | 2313 | ||
| 2314 | r = -EINVAL; | 2314 | r = -EINVAL; |
| 2315 | if (!kvm_s390_pv_is_protected(kvm)) | 2315 | if (!kvm_s390_pv_is_protected(kvm) || !mm_is_protected(kvm->mm)) |
| 2316 | break; | 2316 | break; |
| 2317 | 2317 | ||
| 2318 | r = -EFAULT; | 2318 | r = -EFAULT; |
| @@ -3564,7 +3564,6 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) · 1245 unmodified lines | |||
| 3564 | vcpu->arch.sie_block->pp = 0; | 3564 | vcpu->arch.sie_block->pp = 0; |
| 3565 | vcpu->arch.sie_block->fpf &= ~FPF_BPBC; | 3565 | vcpu->arch.sie_block->fpf &= ~FPF_BPBC; |
| 3566 | vcpu->arch.sie_block->todpr = 0; | 3566 | vcpu->arch.sie_block->todpr = 0; |
| 3567 | vcpu->arch.sie_block->cpnc = 0; | ||
| 3568 | } | 3567 | } |
| 3569 | } | 3568 | } |
| 3570 | 3569 | ||
| @@ -3582,7 +3581,6 @@ static void kvm_arch_vcpu_ioctl_clear_reset(struct kvm_vcpu *vcpu) · 11 unmodified lines | |||
| 3582 | 3581 | ||
| 3583 | regs->etoken = 0; | 3582 | regs->etoken = 0; |
| 3584 | regs->etoken_extension = 0; | 3583 | regs->etoken_extension = 0; |
| 3585 | regs->diag318 = 0; | ||
| 3586 | } | 3584 | } |
| 3587 | 3585 | ||
| 3588 | int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | 3586 | int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) |
| @@ -208,7 +208,6 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc) · 207 unmodified lines | |||
| 208 | return -EIO; | 208 | return -EIO; |
| 209 | } | 209 | } |
| 210 | kvm->arch.gmap->guest_handle = uvcb.guest_handle; | 210 | kvm->arch.gmap->guest_handle = uvcb.guest_handle; |
| 211 | atomic_set(&kvm->mm->context.is_protected, 1); | ||
| 212 | return 0; | 211 | return 0; |
| 213 | } | 212 | } |
| 214 | 213 | ||
| @@ -228,6 +227,8 @@ int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length, u16 *rc, · 13 unmodified lines | |||
| 228 | *rrc = uvcb.header.rrc; | 227 | *rrc = uvcb.header.rrc; |
| 229 | KVM_UV_EVENT(kvm, 3, "PROTVIRT VM SET PARMS: rc %x rrc %x", | 228 | KVM_UV_EVENT(kvm, 3, "PROTVIRT VM SET PARMS: rc %x rrc %x", |
| 230 | *rc, *rrc); | 229 | *rc, *rrc); |
| 230 | if (!cc) | ||
| 231 | atomic_set(&kvm->mm->context.is_protected, 1); | ||
| 231 | return cc ? -EINVAL : 0; | 232 | return cc ? -EINVAL : 0; |
| 232 | } | 233 | } |
| 233 | 234 | ||
| @@ -2690,6 +2690,8 @@ static const struct mm_walk_ops reset_acc_walk_ops = { · 2689 unmodified lines | |||
| 2690 | #include <linux/sched/mm.h> | 2690 | #include <linux/sched/mm.h> |
| 2691 | void s390_reset_acc(struct mm_struct *mm) | 2691 | void s390_reset_acc(struct mm_struct *mm) |
| 2692 | { | 2692 | { |
| 2693 | if (!mm_is_protected(mm)) | ||
| 2694 | return; | ||
| 2693 | /* | 2695 | /* |
| 2694 | * we might be called during | 2696 | * we might be called during |
| 2695 | * reset: we walk the pages and clear | 2697 | * reset: we walk the pages and clear |
| @@ -107,14 +107,14 @@ · 106 unmodified lines | |||
| 107 | MODULE_LICENSE("GPL"); | 107 | MODULE_LICENSE("GPL"); |
| 108 | 108 | ||
| 109 | #define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \ | 109 | #define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \ |
| 110 | static ssize_t __cstate_##_var##_show(struct kobject *kobj, \ | 110 | static ssize_t __cstate_##_var##_show(struct device *dev, \ |
| 111 | struct kobj_attribute *attr, \ | 111 | struct device_attribute *attr, \ |
| 112 | char *page) \ | 112 | char *page) \ |
| 113 | { \ | 113 | { \ |
| 114 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ | 114 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ |
| 115 | return sprintf(page, _format "\n"); \ | 115 | return sprintf(page, _format "\n"); \ |
| 116 | } \ | 116 | } \ |
| 117 | static struct kobj_attribute format_attr_##_var = \ | 117 | static struct device_attribute format_attr_##_var = \ |
| 118 | __ATTR(_name, 0444, __cstate_##_var##_show, NULL) | 118 | __ATTR(_name, 0444, __cstate_##_var##_show, NULL) |
| 119 | 119 | ||
| 120 | static ssize_t cstate_get_attr_cpumask(struct device *dev, | 120 | static ssize_t cstate_get_attr_cpumask(struct device *dev, |
| @@ -94,8 +94,8 @@ end: · 93 unmodified lines | |||
| 94 | return map; | 94 | return map; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | ssize_t uncore_event_show(struct kobject *kobj, | 97 | ssize_t uncore_event_show(struct device *dev, |
| 98 | struct kobj_attribute *attr, char *buf) | 98 | struct device_attribute *attr, char *buf) |
| 99 | { | 99 | { |
| 100 | struct uncore_event_desc *event = | 100 | struct uncore_event_desc *event = |
| 101 | container_of(attr, struct uncore_event_desc, attr); | 101 | container_of(attr, struct uncore_event_desc, attr); |
| @@ -157,7 +157,7 @@ struct intel_uncore_box { · 156 unmodified lines | |||
| 157 | #define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS 2 | 157 | #define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS 2 |
| 158 | 158 | ||
| 159 | struct uncore_event_desc { | 159 | struct uncore_event_desc { |
| 160 | struct kobj_attribute attr; | 160 | struct device_attribute attr; |
| 161 | const char *config; | 161 | const char *config; |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
| @@ -179,8 +179,8 @@ struct pci2phy_map { · 15 unmodified lines | |||
| 179 | struct pci2phy_map *__find_pci2phy_map(int segment); | 179 | struct pci2phy_map *__find_pci2phy_map(int segment); |
| 180 | int uncore_pcibus_to_physid(struct pci_bus *bus); | 180 | int uncore_pcibus_to_physid(struct pci_bus *bus); |
| 181 | 181 | ||
| 182 | ssize_t uncore_event_show(struct kobject *kobj, | 182 | ssize_t uncore_event_show(struct device *dev, |
| 183 | struct kobj_attribute *attr, char *buf); | 183 | struct device_attribute *attr, char *buf); |
| 184 | 184 | ||
| 185 | static inline struct intel_uncore_pmu *dev_to_uncore_pmu(struct device *dev) | 185 | static inline struct intel_uncore_pmu *dev_to_uncore_pmu(struct device *dev) |
| 186 | { | 186 | { |
| @@ -201,14 +201,14 @@ extern int __uncore_max_dies; · 14 unmodified lines | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | #define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ | 203 | #define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ |
| 204 | static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ | 204 | static ssize_t __uncore_##_var##_show(struct device *dev, \ |
| 205 | struct kobj_attribute *attr, \ | 205 | struct device_attribute *attr, \ |
| 206 | char *page) \ | 206 | char *page) \ |
| 207 | { \ | 207 | { \ |
| 208 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ | 208 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ |
| 209 | return sprintf(page, _format "\n"); \ | 209 | return sprintf(page, _format "\n"); \ |
| 210 | } \ | 210 | } \ |
| 211 | static struct kobj_attribute format_attr_##_var = \ | 211 | static struct device_attribute format_attr_##_var = \ |
| 212 | __ATTR(_name, 0444, __uncore_##_var##_show, NULL) | 212 | __ATTR(_name, 0444, __uncore_##_var##_show, NULL) |
| 213 | 213 | ||
| 214 | static inline bool uncore_pmc_fixed(int idx) | 214 | static inline bool uncore_pmc_fixed(int idx) |
| @@ -93,18 +93,6 @@ static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = { · 92 unmodified lines | |||
| 93 | * any other bit is reserved | 93 | * any other bit is reserved |
| 94 | */ | 94 | */ |
| 95 | #define RAPL_EVENT_MASK 0xFFULL | 95 | #define RAPL_EVENT_MASK 0xFFULL |
| 96 | |||
| 97 | #define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \ | ||
| 98 | static ssize_t __rapl_##_var##_show(struct kobject *kobj, \ | ||
| 99 | struct kobj_attribute *attr, \ | ||
| 100 | char *page) \ | ||
| 101 | { \ | ||
| 102 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ | ||
| 103 | return sprintf(page, _format "\n"); \ | ||
| 104 | } \ | ||
| 105 | static struct kobj_attribute format_attr_##_var = \ | ||
| 106 | __ATTR(_name, 0444, __rapl_##_var##_show, NULL) | ||
| 107 | |||
| 108 | #define RAPL_CNTR_WIDTH 32 | 96 | #define RAPL_CNTR_WIDTH 32 |
| 109 | 97 | ||
| 110 | #define RAPL_EVENT_ATTR_STR(_name, v, str) \ | 98 | #define RAPL_EVENT_ATTR_STR(_name, v, str) \ |
| @@ -441,7 +429,7 @@ static struct attribute_group rapl_pmu_events_group = { · 330 unmodified lines | |||
| 441 | .attrs = attrs_empty, | 429 | .attrs = attrs_empty, |
| 442 | }; | 430 | }; |
| 443 | 431 | ||
| 444 | DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7"); | 432 | PMU_FORMAT_ATTR(event, "config:0-7"); |
| 445 | static struct attribute *rapl_formats_attr[] = { | 433 | static struct attribute *rapl_formats_attr[] = { |
| 446 | &format_attr_event.attr, | 434 | &format_attr_event.attr, |
| 447 | NULL, | 435 | NULL, |
| @@ -1656,6 +1656,7 @@ int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); · 1655 unmodified lines | |||
| 1656 | int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 1656 | int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
| 1657 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); | 1657 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); |
| 1658 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 1658 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
| 1659 | int kvm_cpu_has_extint(struct kvm_vcpu *v); | ||
| 1659 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); | 1660 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); |
| 1660 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); | 1661 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); |
| 1661 | void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); | 1662 | void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); |
| @@ -28,4 +28,14 @@ · 27 unmodified lines | |||
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #endif /* CONFIG_SPARSEMEM */ | 30 | #endif /* CONFIG_SPARSEMEM */ |
| 31 | |||
| 32 | #ifndef __ASSEMBLY__ | ||
| 33 | #ifdef CONFIG_NUMA_KEEP_MEMINFO | ||
| 34 | extern int phys_to_target_node(phys_addr_t start); | ||
| 35 | #define phys_to_target_node phys_to_target_node | ||
| 36 | extern int memory_add_physaddr_to_nid(u64 start); | ||
| 37 | #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid | ||
| 38 | #endif | ||
| 39 | #endif /* __ASSEMBLY__ */ | ||
| 40 | |||
| 31 | #endif /* _ASM_X86_SPARSEMEM_H */ | 41 | #endif /* _ASM_X86_SPARSEMEM_H */ |
| @@ -100,53 +100,6 @@ static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev · 99 unmodified lines | |||
| 100 | return find_matching_signature(mc, csig, cpf); | 100 | return find_matching_signature(mc, csig, cpf); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* | ||
| 104 | * Given CPU signature and a microcode patch, this function finds if the | ||
| 105 | * microcode patch has matching family and model with the CPU. | ||
| 106 | * | ||
| 107 | * %true - if there's a match | ||
| 108 | * %false - otherwise | ||
| 109 | */ | ||
| 110 | static bool microcode_matches(struct microcode_header_intel *mc_header, | ||
| 111 | unsigned long sig) | ||
| 112 | { | ||
| 113 | unsigned long total_size = get_totalsize(mc_header); | ||
| 114 | unsigned long data_size = get_datasize(mc_header); | ||
| 115 | struct extended_sigtable *ext_header; | ||
| 116 | unsigned int fam_ucode, model_ucode; | ||
| 117 | struct extended_signature *ext_sig; | ||
| 118 | unsigned int fam, model; | ||
| 119 | int ext_sigcount, i; | ||
| 120 | |||
| 121 | fam = x86_family(sig); | ||
| 122 | model = x86_model(sig); | ||
| 123 | |||
| 124 | fam_ucode = x86_family(mc_header->sig); | ||
| 125 | model_ucode = x86_model(mc_header->sig); | ||
| 126 | |||
| 127 | if (fam == fam_ucode && model == model_ucode) | ||
| 128 | return true; | ||
| 129 | |||
| 130 | /* Look for ext. headers: */ | ||
| 131 | if (total_size <= data_size + MC_HEADER_SIZE) | ||
| 132 | return false; | ||
| 133 | |||
| 134 | ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE; | ||
| 135 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE; | ||
| 136 | ext_sigcount = ext_header->count; | ||
| 137 | |||
| 138 | for (i = 0; i < ext_sigcount; i++) { | ||
| 139 | fam_ucode = x86_family(ext_sig->sig); | ||
| 140 | model_ucode = x86_model(ext_sig->sig); | ||
| 141 | |||
| 142 | if (fam == fam_ucode && model == model_ucode) | ||
| 143 | return true; | ||
| 144 | |||
| 145 | ext_sig++; | ||
| 146 | } | ||
| 147 | return false; | ||
| 148 | } | ||
| 149 | |||
| 150 | static struct ucode_patch *memdup_patch(void *data, unsigned int size) | 103 | static struct ucode_patch *memdup_patch(void *data, unsigned int size) |
| 151 | { | 104 | { |
| 152 | struct ucode_patch *p; | 105 | struct ucode_patch *p; |
| @@ -164,7 +117,7 @@ static struct ucode_patch *memdup_patch(void *data, unsigned int size) · 11 unmodified lines | |||
| 164 | return p; | 117 | return p; |
| 165 | } | 118 | } |
| 166 | 119 | ||
| 167 | static void save_microcode_patch(void *data, unsigned int size) | 120 | static void save_microcode_patch(struct ucode_cpu_info *uci, void *data, unsigned int size) |
| 168 | { | 121 | { |
| 169 | struct microcode_header_intel *mc_hdr, *mc_saved_hdr; | 122 | struct microcode_header_intel *mc_hdr, *mc_saved_hdr; |
| 170 | struct ucode_patch *iter, *tmp, *p = NULL; | 123 | struct ucode_patch *iter, *tmp, *p = NULL; |
| @@ -210,6 +163,9 @@ static void save_microcode_patch(void *data, unsigned int size) · 39 unmodified lines | |||
| 210 | if (!p) | 163 | if (!p) |
| 211 | return; | 164 | return; |
| 212 | 165 | ||
| 166 | if (!find_matching_signature(p->data, uci->cpu_sig.sig, uci->cpu_sig.pf)) | ||
| 167 | return; | ||
| 168 | |||
| 213 | /* | 169 | /* |
| 214 | * Save for early loading. On 32-bit, that needs to be a physical | 170 | * Save for early loading. On 32-bit, that needs to be a physical |
| 215 | * address as the APs are running from physical addresses, before | 171 | * address as the APs are running from physical addresses, before |
| @@ -344,13 +300,14 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save) · 128 unmodified lines | |||
| 344 | 300 | ||
| 345 | size -= mc_size; | 301 | size -= mc_size; |
| 346 | 302 | ||
| 347 | if (!microcode_matches(mc_header, uci->cpu_sig.sig)) { | 303 | if (!find_matching_signature(data, uci->cpu_sig.sig, |
| 304 | uci->cpu_sig.pf)) { | ||
| 348 | data += mc_size; | 305 | data += mc_size; |
| 349 | continue; | 306 | continue; |
| 350 | } | 307 | } |
| 351 | 308 | ||
| 352 | if (save) { | 309 | if (save) { |
| 353 | save_microcode_patch(data, mc_size); | 310 | save_microcode_patch(uci, data, mc_size); |
| 354 | goto next; | 311 | goto next; |
| 355 | } | 312 | } |
| 356 | 313 | ||
| @@ -483,14 +440,14 @@ static void show_saved_mc(void) · 126 unmodified lines | |||
| 483 | * Save this microcode patch. It will be loaded early when a CPU is | 440 | * Save this microcode patch. It will be loaded early when a CPU is |
| 484 | * hot-added or resumes. | 441 | * hot-added or resumes. |
| 485 | */ | 442 | */ |
| 486 | static void save_mc_for_early(u8 *mc, unsigned int size) | 443 | static void save_mc_for_early(struct ucode_cpu_info *uci, u8 *mc, unsigned int size) |
| 487 | { | 444 | { |
| 488 | /* Synchronization during CPU hotplug. */ | 445 | /* Synchronization during CPU hotplug. */ |
| 489 | static DEFINE_MUTEX(x86_cpu_microcode_mutex); | 446 | static DEFINE_MUTEX(x86_cpu_microcode_mutex); |
| 490 | 447 | ||
| 491 | mutex_lock(&x86_cpu_microcode_mutex); | 448 | mutex_lock(&x86_cpu_microcode_mutex); |
| 492 | 449 | ||
| 493 | save_microcode_patch(mc, size); | 450 | save_microcode_patch(uci, mc, size); |
| 494 | show_saved_mc(); | 451 | show_saved_mc(); |
| 495 | 452 | ||
| 496 | mutex_unlock(&x86_cpu_microcode_mutex); | 453 | mutex_unlock(&x86_cpu_microcode_mutex); |
| @@ -935,7 +892,7 @@ static enum ucode_state generic_load_microcode(int cpu, struct iov_iter *iter) · 438 unmodified lines | |||
| 935 | * permanent memory. So it will be loaded early when a CPU is hot added | 892 | * permanent memory. So it will be loaded early when a CPU is hot added |
| 936 | * or resumes. | 893 | * or resumes. |
| 937 | */ | 894 | */ |
| 938 | save_mc_for_early(new_mc, new_mc_size); | 895 | save_mc_for_early(uci, new_mc, new_mc_size); |
| 939 | 896 | ||
| 940 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", | 897 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
| 941 | cpu, new_rev, uci->cpu_sig.rev); | 898 | cpu, new_rev, uci->cpu_sig.rev); |
| @@ -78,6 +78,9 @@ static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src, · 77 unmodified lines | |||
| 78 | if (!user_mode(regs)) | 78 | if (!user_mode(regs)) |
| 79 | return copy_from_kernel_nofault(buf, (u8 *)src, nbytes); | 79 | return copy_from_kernel_nofault(buf, (u8 *)src, nbytes); |
| 80 | 80 | ||
| 81 | /* The user space code from other tasks cannot be accessed. */ | ||
| 82 | if (regs != task_pt_regs(current)) | ||
| 83 | return -EPERM; | ||
| 81 | /* | 84 | /* |
| 82 | * Make sure userspace isn't trying to trick us into dumping kernel | 85 | * Make sure userspace isn't trying to trick us into dumping kernel |
| 83 | * memory by pointing the userspace instruction pointer at it. | 86 | * memory by pointing the userspace instruction pointer at it. |
| @@ -85,6 +88,12 @@ static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src, · 1 unmodified line | |||
| 85 | if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX)) | 88 | if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX)) |
| 86 | return -EINVAL; | 89 | return -EINVAL; |
| 87 | 90 | ||
| 91 | /* | ||
| 92 | * Even if named copy_from_user_nmi() this can be invoked from | ||
| 93 | * other contexts and will not try to resolve a pagefault, which is | ||
| 94 | * the correct thing to do here as this code can be called from any | ||
| 95 | * context. | ||
| 96 | */ | ||
| 88 | return copy_from_user_nmi(buf, (void __user *)src, nbytes); | 97 | return copy_from_user_nmi(buf, (void __user *)src, nbytes); |
| 89 | } | 98 | } |
| 90 | 99 | ||
| @@ -115,13 +124,19 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) · 24 unmodified lines | |||
| 115 | u8 opcodes[OPCODE_BUFSIZE]; | 124 | u8 opcodes[OPCODE_BUFSIZE]; |
| 116 | unsigned long prologue = regs->ip - PROLOGUE_SIZE; | 125 | unsigned long prologue = regs->ip - PROLOGUE_SIZE; |
| 117 | 126 | ||
| 118 | if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) { | 127 | switch (copy_code(regs, opcodes, prologue, sizeof(opcodes))) { |
| 119 | printk("%sCode: Unable to access opcode bytes at RIP 0x%lx.\n", | 128 | case 0: |
| 120 | loglvl, prologue); | ||
| 121 | } else { | ||
| 122 | printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %" | 129 | printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %" |
| 123 | __stringify(EPILOGUE_SIZE) "ph\n", loglvl, opcodes, | 130 | __stringify(EPILOGUE_SIZE) "ph\n", loglvl, opcodes, |
| 124 | opcodes[PROLOGUE_SIZE], opcodes + PROLOGUE_SIZE + 1); | 131 | opcodes[PROLOGUE_SIZE], opcodes + PROLOGUE_SIZE + 1); |
| 132 | break; | ||
| 133 | case -EPERM: | ||
| 134 | /* No access to the user space stack of other tasks. Ignore. */ | ||
| 135 | break; | ||
| 136 | default: | ||
| 137 | printk("%sCode: Unable to access opcode bytes at RIP 0x%lx.\n", | ||
| 138 | loglvl, prologue); | ||
| 139 | break; | ||
| 125 | } | 140 | } |
| 126 | } | 141 | } |
| 127 | 142 | ||
| @@ -514,16 +514,10 @@ int tboot_force_iommu(void) · 513 unmodified lines | |||
| 514 | if (!tboot_enabled()) | 514 | if (!tboot_enabled()) |
| 515 | return 0; | 515 | return 0; |
| 516 | 516 | ||
| 517 | if (intel_iommu_tboot_noforce) | 517 | if (no_iommu || dmar_disabled) |
| 518 | return 1; | ||
| 519 | |||
| 520 | if (no_iommu || swiotlb || dmar_disabled) | ||
| 521 | pr_warn("Forcing Intel-IOMMU to enabled\n"); | 518 | pr_warn("Forcing Intel-IOMMU to enabled\n"); |
| 522 | 519 | ||
| 523 | dmar_disabled = 0; | 520 | dmar_disabled = 0; |
| 524 | #ifdef CONFIG_SWIOTLB | ||
| 525 | swiotlb = 0; | ||
| 526 | #endif | ||
| 527 | no_iommu = 0; | 521 | no_iommu = 0; |
| 528 | 522 | ||
| 529 | return 1; | 523 | return 1; |
| @@ -40,29 +40,10 @@ static int pending_userspace_extint(struct kvm_vcpu *v) · 39 unmodified lines | |||
| 40 | * check if there is pending interrupt from | 40 | * check if there is pending interrupt from |
| 41 | * non-APIC source without intack. | 41 | * non-APIC source without intack. |
| 42 | */ | 42 | */ |
| 43 | static int kvm_cpu_has_extint(struct kvm_vcpu *v) | 43 | int kvm_cpu_has_extint(struct kvm_vcpu *v) |
| 44 | { | ||
| 45 | u8 accept = kvm_apic_accept_pic_intr(v); | ||
| 46 | |||
| 47 | if (accept) { | ||
| 48 | if (irqchip_split(v->kvm)) | ||
| 49 | return pending_userspace_extint(v); | ||
| 50 | else | ||
| 51 | return v->kvm->arch.vpic->output; | ||
| 52 | } else | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * check if there is injectable interrupt: | ||
| 58 | * when virtual interrupt delivery enabled, | ||
| 59 | * interrupt from apic will handled by hardware, | ||
| 60 | * we don't need to check it here. | ||
| 61 | */ | ||
| 62 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v) | ||
| 63 | { | 44 | { |
| 64 | /* | 45 | /* |
| 65 | * FIXME: interrupt.injected represents an interrupt that it's | 46 | * FIXME: interrupt.injected represents an interrupt whose |
| 66 | * side-effects have already been applied (e.g. bit from IRR | 47 | * side-effects have already been applied (e.g. bit from IRR |
| 67 | * already moved to ISR). Therefore, it is incorrect to rely | 48 | * already moved to ISR). Therefore, it is incorrect to rely |
| 68 | * on interrupt.injected to know if there is a pending | 49 | * on interrupt.injected to know if there is a pending |
| @@ -75,6 +56,23 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v) · 6 unmodified lines | |||
| 75 | if (!lapic_in_kernel(v)) | 56 | if (!lapic_in_kernel(v)) |
| 76 | return v->arch.interrupt.injected; | 57 | return v->arch.interrupt.injected; |
| 77 | 58 | ||
| 59 | if (!kvm_apic_accept_pic_intr(v)) | ||
| 60 | return 0; | ||
| 61 | |||
| 62 | if (irqchip_split(v->kvm)) | ||
| 63 | return pending_userspace_extint(v); | ||
| 64 | else | ||
| 65 | return v->kvm->arch.vpic->output; | ||
| 66 | } | ||
| 67 | |||
| 68 | /* | ||
| 69 | * check if there is injectable interrupt: | ||
| 70 | * when virtual interrupt delivery enabled, | ||
| 71 | * interrupt from apic will handled by hardware, | ||
| 72 | * we don't need to check it here. | ||
| 73 | */ | ||
| 74 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v) | ||
| 75 | { | ||
| 78 | if (kvm_cpu_has_extint(v)) | 76 | if (kvm_cpu_has_extint(v)) |
| 79 | return 1; | 77 | return 1; |
| 80 | 78 | ||
| @@ -91,20 +89,6 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_injectable_intr); · 10 unmodified lines | |||
| 91 | */ | 89 | */ |
| 92 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v) | 90 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v) |
| 93 | { | 91 | { |
| 94 | /* | ||
| 95 | * FIXME: interrupt.injected represents an interrupt that it's | ||
| 96 | * side-effects have already been applied (e.g. bit from IRR | ||
| 97 | * already moved to ISR). Therefore, it is incorrect to rely | ||
| 98 | * on interrupt.injected to know if there is a pending | ||
| 99 | * interrupt in the user-mode LAPIC. | ||
| 100 | * This leads to nVMX/nSVM not be able to distinguish | ||
| 101 | * if it should exit from L2 to L1 on EXTERNAL_INTERRUPT on | ||
| 102 | * pending interrupt or should re-inject an injected | ||
| 103 | * interrupt. | ||
| 104 | */ | ||
| 105 | if (!lapic_in_kernel(v)) | ||
| 106 | return v->arch.interrupt.injected; | ||
| 107 | |||
| 108 | if (kvm_cpu_has_extint(v)) | 92 | if (kvm_cpu_has_extint(v)) |
| 109 | return 1; | 93 | return 1; |
| 110 | 94 | ||
| @@ -118,16 +102,21 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); · 7 unmodified lines | |||
| 118 | */ | 102 | */ |
| 119 | static int kvm_cpu_get_extint(struct kvm_vcpu *v) | 103 | static int kvm_cpu_get_extint(struct kvm_vcpu *v) |
| 120 | { | 104 | { |
| 121 | if (kvm_cpu_has_extint(v)) { | 105 | if (!kvm_cpu_has_extint(v)) { |
| 122 | if (irqchip_split(v->kvm)) { | 106 | WARN_ON(!lapic_in_kernel(v)); |
| 123 | int vector = v->arch.pending_external_vector; | ||
| 124 | |||
| 125 | v->arch.pending_external_vector = -1; | ||
| 126 | return vector; | ||
| 127 | } else | ||
| 128 | return kvm_pic_read_irq(v->kvm); /* PIC */ | ||
| 129 | } else | ||
| 130 | return -1; | 107 | return -1; |
| 108 | } | ||
| 109 | |||
| 110 | if (!lapic_in_kernel(v)) | ||
| 111 | return v->arch.interrupt.nr; | ||
| 112 | |||
| 113 | if (irqchip_split(v->kvm)) { | ||
| 114 | int vector = v->arch.pending_external_vector; | ||
| 115 | |||
| 116 | v->arch.pending_external_vector = -1; | ||
| 117 | return vector; | ||
| 118 | } else | ||
| 119 | return kvm_pic_read_irq(v->kvm); /* PIC */ | ||
| 131 | } | 120 | } |
| 132 | 121 | ||
| 133 | /* | 122 | /* |
| @@ -135,13 +124,7 @@ static int kvm_cpu_get_extint(struct kvm_vcpu *v) · 1 unmodified line | |||
| 135 | */ | 124 | */ |
| 136 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v) | 125 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v) |
| 137 | { | 126 | { |
| 138 | int vector; | 127 | int vector = kvm_cpu_get_extint(v); |
| 139 | |||
| 140 | if (!lapic_in_kernel(v)) | ||
| 141 | return v->arch.interrupt.nr; | ||
| 142 | |||
| 143 | vector = kvm_cpu_get_extint(v); | ||
| 144 | |||
| 145 | if (vector != -1) | 128 | if (vector != -1) |
| 146 | return vector; /* PIC */ | 129 | return vector; /* PIC */ |
| 147 | 130 | ||
| @@ -2465,7 +2465,7 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) · 2464 unmodified lines | |||
| 2465 | struct kvm_lapic *apic = vcpu->arch.apic; | 2465 | struct kvm_lapic *apic = vcpu->arch.apic; |
| 2466 | u32 ppr; | 2466 | u32 ppr; |
| 2467 | 2467 | ||
| 2468 | if (!kvm_apic_hw_enabled(apic)) | 2468 | if (!kvm_apic_present(vcpu)) |
| 2469 | return -1; | 2469 | return -1; |
| 2470 | 2470 | ||
| 2471 | __apic_update_ppr(apic, &ppr); | 2471 | __apic_update_ppr(apic, &ppr); |
| @@ -3517,7 +3517,7 @@ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) · 3516 unmodified lines | |||
| 3517 | { | 3517 | { |
| 3518 | u64 sptes[PT64_ROOT_MAX_LEVEL]; | 3518 | u64 sptes[PT64_ROOT_MAX_LEVEL]; |
| 3519 | struct rsvd_bits_validate *rsvd_check; | 3519 | struct rsvd_bits_validate *rsvd_check; |
| 3520 | int root = vcpu->arch.mmu->root_level; | 3520 | int root = vcpu->arch.mmu->shadow_root_level; |
| 3521 | int leaf; | 3521 | int leaf; |
| 3522 | int level; | 3522 | int level; |
| 3523 | bool reserved = false; | 3523 | bool reserved = false; |
| @@ -642,8 +642,8 @@ static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long src_paddr, · 641 unmodified lines | |||
| 642 | * Its safe to read more than we are asked, caller should ensure that | 642 | * Its safe to read more than we are asked, caller should ensure that |
| 643 | * destination has enough space. | 643 | * destination has enough space. |
| 644 | */ | 644 | */ |
| 645 | src_paddr = round_down(src_paddr, 16); | ||
| 646 | offset = src_paddr & 15; | 645 | offset = src_paddr & 15; |
| 646 | src_paddr = round_down(src_paddr, 16); | ||
| 647 | sz = round_up(sz + offset, 16); | 647 | sz = round_up(sz + offset, 16); |
| 648 | 648 | ||
| 649 | return __sev_issue_dbg_cmd(kvm, src_paddr, dst_paddr, sz, err, false); | 649 | return __sev_issue_dbg_cmd(kvm, src_paddr, dst_paddr, sz, err, false); |
| @@ -1309,8 +1309,10 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) · 1308 unmodified lines | |||
| 1309 | svm->avic_is_running = true; | 1309 | svm->avic_is_running = true; |
| 1310 | 1310 | ||
| 1311 | svm->msrpm = svm_vcpu_alloc_msrpm(); | 1311 | svm->msrpm = svm_vcpu_alloc_msrpm(); |
| 1312 | if (!svm->msrpm) | 1312 | if (!svm->msrpm) { |
| 1313 | err = -ENOMEM; | ||
| 1313 | goto error_free_vmcb_page; | 1314 | goto error_free_vmcb_page; |
| 1315 | } | ||
| 1314 | 1316 | ||
| 1315 | svm_vcpu_init_msrpm(vcpu, svm->msrpm); | 1317 | svm_vcpu_init_msrpm(vcpu, svm->msrpm); |
| 1316 | 1318 | ||
| @@ -4051,21 +4051,23 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, · 4050 unmodified lines | |||
| 4051 | 4051 | ||
| 4052 | static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu) | 4052 | static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu) |
| 4053 | { | 4053 | { |
| 4054 | /* | ||
| 4055 | * We can accept userspace's request for interrupt injection | ||
| 4056 | * as long as we have a place to store the interrupt number. | ||
| 4057 | * The actual injection will happen when the CPU is able to | ||
| 4058 | * deliver the interrupt. | ||
| 4059 | */ | ||
| 4060 | if (kvm_cpu_has_extint(vcpu)) | ||
| 4061 | return false; | ||
| 4062 | |||
| 4063 | /* Acknowledging ExtINT does not happen if LINT0 is masked. */ | ||
| 4054 | return (!lapic_in_kernel(vcpu) || | 4064 | return (!lapic_in_kernel(vcpu) || |
| 4055 | kvm_apic_accept_pic_intr(vcpu)); | 4065 | kvm_apic_accept_pic_intr(vcpu)); |
| 4056 | } | 4066 | } |
| 4057 | 4067 | ||
| 4058 | /* | ||
| 4059 | * if userspace requested an interrupt window, check that the | ||
| 4060 | * interrupt window is open. | ||
| 4061 | * | ||
| 4062 | * No need to exit to userspace if we already have an interrupt queued. | ||
| 4063 | */ | ||
| 4064 | static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu) | 4068 | static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu) |
| 4065 | { | 4069 | { |
| 4066 | return kvm_arch_interrupt_allowed(vcpu) && | 4070 | return kvm_arch_interrupt_allowed(vcpu) && |
| 4067 | !kvm_cpu_has_interrupt(vcpu) && | ||
| 4068 | !kvm_event_needs_reinjection(vcpu) && | ||
| 4069 | kvm_cpu_accept_dm_intr(vcpu); | 4071 | kvm_cpu_accept_dm_intr(vcpu); |
| 4070 | } | 4072 | } |
| 4071 | 4073 | ||
| @@ -938,6 +938,7 @@ int phys_to_target_node(phys_addr_t start) · 937 unmodified lines | |||
| 938 | 938 | ||
| 939 | return meminfo_to_nid(&numa_reserved_meminfo, start); | 939 | return meminfo_to_nid(&numa_reserved_meminfo, start); |
| 940 | } | 940 | } |
| 941 | EXPORT_SYMBOL_GPL(phys_to_target_node); | ||
| 941 | 942 | ||
| 942 | int memory_add_physaddr_to_nid(u64 start) | 943 | int memory_add_physaddr_to_nid(u64 start) |
| 943 | { | 944 | { |
| @@ -947,4 +948,5 @@ int memory_add_physaddr_to_nid(u64 start) · 3 unmodified lines | |||
| 947 | nid = numa_meminfo.blk[0].nid; | 948 | nid = numa_meminfo.blk[0].nid; |
| 948 | return nid; | 949 | return nid; |
| 949 | } | 950 | } |
| 951 | EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); | ||
| 950 | #endif | 952 | #endif |
| @@ -78,28 +78,30 @@ int __init efi_alloc_page_tables(void) · 77 unmodified lines | |||
| 78 | gfp_mask = GFP_KERNEL | __GFP_ZERO; | 78 | gfp_mask = GFP_KERNEL | __GFP_ZERO; |
| 79 | efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER); | 79 | efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER); |
| 80 | if (!efi_pgd) | 80 | if (!efi_pgd) |
| 81 | return -ENOMEM; | 81 | goto fail; |
| 82 | 82 | ||
| 83 | pgd = efi_pgd + pgd_index(EFI_VA_END); | 83 | pgd = efi_pgd + pgd_index(EFI_VA_END); |
| 84 | p4d = p4d_alloc(&init_mm, pgd, EFI_VA_END); | 84 | p4d = p4d_alloc(&init_mm, pgd, EFI_VA_END); |
| 85 | if (!p4d) { | 85 | if (!p4d) |
| 86 | free_page((unsigned long)efi_pgd); | 86 | goto free_pgd; |
| 87 | return -ENOMEM; | ||
| 88 | } | ||
| 89 | 87 | ||
| 90 | pud = pud_alloc(&init_mm, p4d, EFI_VA_END); | 88 | pud = pud_alloc(&init_mm, p4d, EFI_VA_END); |
| 91 | if (!pud) { | 89 | if (!pud) |
| 92 | if (pgtable_l5_enabled()) | 90 | goto free_p4d; |
| 93 | free_page((unsigned long) pgd_page_vaddr(*pgd)); | ||
| 94 | free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER); | ||
| 95 | return -ENOMEM; | ||
| 96 | } | ||
| 97 | 91 | ||
| 98 | efi_mm.pgd = efi_pgd; | 92 | efi_mm.pgd = efi_pgd; |
| 99 | mm_init_cpumask(&efi_mm); | 93 | mm_init_cpumask(&efi_mm); |
| 100 | init_new_context(NULL, &efi_mm); | 94 | init_new_context(NULL, &efi_mm); |
| 101 | 95 | ||
| 102 | return 0; | 96 | return 0; |
| 97 | |||
| 98 | free_p4d: | ||
| 99 | if (pgtable_l5_enabled()) | ||
| 100 | free_page((unsigned long)pgd_page_vaddr(*pgd)); | ||
| 101 | free_pgd: | ||
| 102 | free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER); | ||
| 103 | fail: | ||
| 104 | return -ENOMEM; | ||
| 103 | } | 105 | } |
| 104 | 106 | ||
| 105 | /* | 107 | /* |
| @@ -93,10 +93,20 @@ void xen_init_lock_cpu(int cpu) · 92 unmodified lines | |||
| 93 | 93 | ||
| 94 | void xen_uninit_lock_cpu(int cpu) | 94 | void xen_uninit_lock_cpu(int cpu) |
| 95 | { | 95 | { |
| 96 | int irq; | ||
| 97 | |||
| 96 | if (!xen_pvspin) | 98 | if (!xen_pvspin) |
| 97 | return; | 99 | return; |
| 98 | 100 | ||
| 99 | unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); | 101 | /* |
| 102 | * When booting the kernel with 'mitigations=auto,nosmt', the secondary | ||
| 103 | * CPUs are not activated, and lock_kicker_irq is not initialized. | ||
| 104 | */ | ||
| 105 | irq = per_cpu(lock_kicker_irq, cpu); | ||
| 106 | if (irq == -1) | ||
| 107 | return; | ||
| 108 | |||
| 109 | unbind_from_irqhandler(irq, NULL); | ||
| 100 | per_cpu(lock_kicker_irq, cpu) = -1; | 110 | per_cpu(lock_kicker_irq, cpu) = -1; |
| 101 | kfree(per_cpu(irq_name, cpu)); | 111 | kfree(per_cpu(irq_name, cpu)); |
| 102 | per_cpu(irq_name, cpu) = NULL; | 112 | per_cpu(irq_name, cpu) = NULL; |
| @@ -849,6 +849,7 @@ static void blkcg_fill_root_iostats(void) · 848 unmodified lines | |||
| 849 | blkg_iostat_set(&blkg->iostat.cur, &tmp); | 849 | blkg_iostat_set(&blkg->iostat.cur, &tmp); |
| 850 | u64_stats_update_end(&blkg->iostat.sync); | 850 | u64_stats_update_end(&blkg->iostat.sync); |
| 851 | } | 851 | } |
| 852 | disk_put_part(part); | ||
| 852 | } | 853 | } |
| 853 | } | 854 | } |
| 854 | 855 | ||
| @@ -225,13 +225,18 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) · 224 unmodified lines | |||
| 225 | /* release the tag's ownership to the req cloned from */ | 225 | /* release the tag's ownership to the req cloned from */ |
| 226 | spin_lock_irqsave(&fq->mq_flush_lock, flags); | 226 | spin_lock_irqsave(&fq->mq_flush_lock, flags); |
| 227 | 227 | ||
| 228 | WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE); | ||
| 229 | if (!refcount_dec_and_test(&flush_rq->ref)) { | 228 | if (!refcount_dec_and_test(&flush_rq->ref)) { |
| 230 | fq->rq_status = error; | 229 | fq->rq_status = error; |
| 231 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); | 230 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); |
| 232 | return; | 231 | return; |
| 233 | } | 232 | } |
| 234 | 233 | ||
| 234 | /* | ||
| 235 | * Flush request has to be marked as IDLE when it is really ended | ||
| 236 | * because its .end_io() is called from timeout code path too for | ||
| 237 | * avoiding use-after-free. | ||
| 238 | */ | ||
| 239 | WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE); | ||
| 235 | if (fq->rq_status != BLK_STS_OK) | 240 | if (fq->rq_status != BLK_STS_OK) |
| 236 | error = fq->rq_status; | 241 | error = fq->rq_status; |
| 237 | 242 | ||
| @@ -103,6 +103,13 @@ int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots) · 102 unmodified lines | |||
| 103 | spin_lock_init(&ksm->idle_slots_lock); | 103 | spin_lock_init(&ksm->idle_slots_lock); |
| 104 | 104 | ||
| 105 | slot_hashtable_size = roundup_pow_of_two(num_slots); | 105 | slot_hashtable_size = roundup_pow_of_two(num_slots); |
| 106 | /* | ||
| 107 | * hash_ptr() assumes bits != 0, so ensure the hash table has at least 2 | ||
| 108 | * buckets. This only makes a difference when there is only 1 keyslot. | ||
| 109 | */ | ||
| 110 | if (slot_hashtable_size < 2) | ||
| 111 | slot_hashtable_size = 2; | ||
| 112 | |||
| 106 | ksm->log_slot_ht_size = ilog2(slot_hashtable_size); | 113 | ksm->log_slot_ht_size = ilog2(slot_hashtable_size); |
| 107 | ksm->slot_hashtable = kvmalloc_array(slot_hashtable_size, | 114 | ksm->slot_hashtable = kvmalloc_array(slot_hashtable_size, |
| 108 | sizeof(ksm->slot_hashtable[0]), | 115 | sizeof(ksm->slot_hashtable[0]), |
| @@ -49,15 +49,25 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) · 48 unmodified lines | |||
| 49 | 49 | ||
| 50 | if (!tty->ops->write) | 50 | if (!tty->ops->write) |
| 51 | return -EOPNOTSUPP; | 51 | return -EOPNOTSUPP; |
| 52 | |||
| 53 | mutex_lock(&speakup_tty_mutex); | ||
| 54 | if (speakup_tty) { | ||
| 55 | mutex_unlock(&speakup_tty_mutex); | ||
| 56 | return -EBUSY; | ||
| 57 | } | ||
| 52 | speakup_tty = tty; | 58 | speakup_tty = tty; |
| 53 | 59 | ||
| 54 | ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL); | 60 | ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL); |
| 55 | if (!ldisc_data) | 61 | if (!ldisc_data) { |
| 62 | speakup_tty = NULL; | ||
| 63 | mutex_unlock(&speakup_tty_mutex); | ||
| 56 | return -ENOMEM; | 64 | return -ENOMEM; |
| 65 | } | ||
| 57 | 66 | ||
| 58 | init_completion(&ldisc_data->completion); | 67 | init_completion(&ldisc_data->completion); |
| 59 | ldisc_data->buf_free = true; | 68 | ldisc_data->buf_free = true; |
| 60 | speakup_tty->disc_data = ldisc_data; | 69 | speakup_tty->disc_data = ldisc_data; |
| 70 | mutex_unlock(&speakup_tty_mutex); | ||
| 61 | 71 | ||
| 62 | return 0; | 72 | return 0; |
| 63 | } | 73 | } |
| @@ -44,7 +44,7 @@ static DEFINE_SPINLOCK(iort_fwnode_lock); · 43 unmodified lines | |||
| 44 | * iort_set_fwnode() - Create iort_fwnode and use it to register | 44 | * iort_set_fwnode() - Create iort_fwnode and use it to register |
| 45 | * iommu data in the iort_fwnode_list | 45 | * iommu data in the iort_fwnode_list |
| 46 | * | 46 | * |
| 47 | * @node: IORT table node associated with the IOMMU | 47 | * @iort_node: IORT table node associated with the IOMMU |
| 48 | * @fwnode: fwnode associated with the IORT node | 48 | * @fwnode: fwnode associated with the IORT node |
| 49 | * | 49 | * |
| 50 | * Returns: 0 on success | 50 | * Returns: 0 on success |
| @@ -673,7 +673,8 @@ static int iort_dev_find_its_id(struct device *dev, u32 id, · 622 unmodified lines | |||
| 673 | /** | 673 | /** |
| 674 | * iort_get_device_domain() - Find MSI domain related to a device | 674 | * iort_get_device_domain() - Find MSI domain related to a device |
| 675 | * @dev: The device. | 675 | * @dev: The device. |
| 676 | * @req_id: Requester ID for the device. | 676 | * @id: Requester ID for the device. |
| 677 | * @bus_token: irq domain bus token. | ||
| 677 | * | 678 | * |
| 678 | * Returns: the MSI domain for this device, NULL otherwise | 679 | * Returns: the MSI domain for this device, NULL otherwise |
| 679 | */ | 680 | */ |
| @@ -1136,7 +1137,7 @@ static int rc_dma_get_range(struct device *dev, u64 *size) · 456 unmodified lines | |||
| 1136 | * | 1137 | * |
| 1137 | * @dev: device to configure | 1138 | * @dev: device to configure |
| 1138 | * @dma_addr: device DMA address result pointer | 1139 | * @dma_addr: device DMA address result pointer |
| 1139 | * @size: DMA range size result pointer | 1140 | * @dma_size: DMA range size result pointer |
| 1140 | */ | 1141 | */ |
| 1141 | void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) | 1142 | void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) |
| 1142 | { | 1143 | { |
| @@ -1526,6 +1527,7 @@ static __init const struct iort_dev_config *iort_get_dev_cfg( · 383 unmodified lines | |||
| 1526 | /** | 1527 | /** |
| 1527 | * iort_add_platform_device() - Allocate a platform device for IORT node | 1528 | * iort_add_platform_device() - Allocate a platform device for IORT node |
| 1528 | * @node: Pointer to device ACPI IORT node | 1529 | * @node: Pointer to device ACPI IORT node |
| 1530 | * @ops: Pointer to IORT device config struct | ||
| 1529 | * | 1531 | * |
| 1530 | * Returns: 0 on success, <0 failure | 1532 | * Returns: 0 on success, <0 failure |
| 1531 | */ | 1533 | */ |
| @@ -227,6 +227,9 @@ static int sysc_wait_softreset(struct sysc *ddata) · 226 unmodified lines | |||
| 227 | u32 sysc_mask, syss_done, rstval; | 227 | u32 sysc_mask, syss_done, rstval; |
| 228 | int syss_offset, error = 0; | 228 | int syss_offset, error = 0; |
| 229 | 229 | ||
| 230 | if (ddata->cap->regbits->srst_shift < 0) | ||
| 231 | return 0; | ||
| 232 | |||
| 230 | syss_offset = ddata->offsets[SYSC_SYSSTATUS]; | 233 | syss_offset = ddata->offsets[SYSC_SYSSTATUS]; |
| 231 | sysc_mask = BIT(ddata->cap->regbits->srst_shift); | 234 | sysc_mask = BIT(ddata->cap->regbits->srst_shift); |
| 232 | 235 | ||
| @@ -970,9 +973,15 @@ static int sysc_enable_module(struct device *dev) · 737 unmodified lines | |||
| 970 | return error; | 973 | return error; |
| 971 | } | 974 | } |
| 972 | } | 975 | } |
| 973 | error = sysc_wait_softreset(ddata); | 976 | /* |
| 974 | if (error) | 977 | * Some modules like i2c and hdq1w have unusable reset status unless |
| 975 | dev_warn(ddata->dev, "OCP softreset timed out\n"); | 978 | * the module reset quirk is enabled. Skip status check on enable. |
| 979 | */ | ||
| 980 | if (!(ddata->cfg.quirks & SYSC_MODULE_QUIRK_ENA_RESETDONE)) { | ||
| 981 | error = sysc_wait_softreset(ddata); | ||
| 982 | if (error) | ||
| 983 | dev_warn(ddata->dev, "OCP softreset timed out\n"); | ||
| 984 | } | ||
| 976 | if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET) | 985 | if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET) |
| 977 | sysc_disable_opt_clocks(ddata); | 986 | sysc_disable_opt_clocks(ddata); |
| 978 | 987 | ||
| @@ -1373,17 +1382,17 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { · 394 unmodified lines | |||
| 1373 | SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, | 1382 | SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, |
| 1374 | SYSC_QUIRK_OPT_CLKS_NEEDED), | 1383 | SYSC_QUIRK_OPT_CLKS_NEEDED), |
| 1375 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, | 1384 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, |
| 1376 | SYSC_MODULE_QUIRK_HDQ1W), | 1385 | SYSC_MODULE_QUIRK_HDQ1W | SYSC_MODULE_QUIRK_ENA_RESETDONE), |
| 1377 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, | 1386 | SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, |
| 1378 | SYSC_MODULE_QUIRK_HDQ1W), | 1387 | SYSC_MODULE_QUIRK_HDQ1W | SYSC_MODULE_QUIRK_ENA_RESETDONE), |
| 1379 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000036, 0x000000ff, | 1388 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000036, 0x000000ff, |
| 1380 | SYSC_MODULE_QUIRK_I2C), | 1389 | SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE), |
| 1381 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x0000003c, 0x000000ff, | 1390 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x0000003c, 0x000000ff, |
| 1382 | SYSC_MODULE_QUIRK_I2C), | 1391 | SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE), |
| 1383 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000040, 0x000000ff, | 1392 | SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000040, 0x000000ff, |
| 1384 | SYSC_MODULE_QUIRK_I2C), | 1393 | SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE), |
| 1385 | SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, | 1394 | SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, |
| 1386 | SYSC_MODULE_QUIRK_I2C), | 1395 | SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE), |
| 1387 | SYSC_QUIRK("gpu", 0x50000000, 0x14, -ENODEV, -ENODEV, 0x00010201, 0xffffffff, 0), | 1396 | SYSC_QUIRK("gpu", 0x50000000, 0x14, -ENODEV, -ENODEV, 0x00010201, 0xffffffff, 0), |
| 1388 | SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff, | 1397 | SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff, |
| 1389 | SYSC_MODULE_QUIRK_SGX), | 1398 | SYSC_MODULE_QUIRK_SGX), |
| @@ -2880,7 +2889,7 @@ static int sysc_check_active_timer(struct sysc *ddata) · 1490 unmodified lines | |||
| 2880 | 2889 | ||
| 2881 | if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && | 2890 | if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && |
| 2882 | (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) | 2891 | (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) |
| 2883 | return -EBUSY; | 2892 | return -ENXIO; |
| 2884 | 2893 | ||
| 2885 | return 0; | 2894 | return 0; |
| 2886 | } | 2895 | } |
| @@ -368,7 +368,7 @@ static const struct regmap_config ti_eqep_regmap32_config = { · 367 unmodified lines | |||
| 368 | .reg_bits = 32, | 368 | .reg_bits = 32, |
| 369 | .val_bits = 32, | 369 | .val_bits = 32, |
| 370 | .reg_stride = 4, | 370 | .reg_stride = 4, |
| 371 | .max_register = 0x24, | 371 | .max_register = QUPRD, |
| 372 | }; | 372 | }; |
| 373 | 373 | ||
| 374 | static const struct regmap_config ti_eqep_regmap16_config = { | 374 | static const struct regmap_config ti_eqep_regmap16_config = { |
| @@ -376,7 +376,7 @@ static const struct regmap_config ti_eqep_regmap16_config = { · 1 unmodified line | |||
| 376 | .reg_bits = 16, | 376 | .reg_bits = 16, |
| 377 | .val_bits = 16, | 377 | .val_bits = 16, |
| 378 | .reg_stride = 2, | 378 | .reg_stride = 2, |
| 379 | .max_register = 0x1e, | 379 | .max_register = QCPRDLAT, |
| 380 | }; | 380 | }; |
| 381 | 381 | ||
| 382 | static int ti_eqep_probe(struct platform_device *pdev) | 382 | static int ti_eqep_probe(struct platform_device *pdev) |
| @@ -236,13 +236,15 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev) · 235 unmodified lines | |||
| 236 | if (!handle || !handle->perf_ops) | 236 | if (!handle || !handle->perf_ops) |
| 237 | return -ENODEV; | 237 | return -ENODEV; |
| 238 | 238 | ||
| 239 | #ifdef CONFIG_COMMON_CLK | ||
| 239 | /* dummy clock provider as needed by OPP if clocks property is used */ | 240 | /* dummy clock provider as needed by OPP if clocks property is used */ |
| 240 | if (of_find_property(dev->of_node, "#clock-cells", NULL)) | 241 | if (of_find_property(dev->of_node, "#clock-cells", NULL)) |
| 241 | devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); | 242 | devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); |
| 243 | #endif | ||
| 242 | 244 | ||
| 243 | ret = cpufreq_register_driver(&scmi_cpufreq_driver); | 245 | ret = cpufreq_register_driver(&scmi_cpufreq_driver); |
| 244 | if (ret) { | 246 | if (ret) { |
| 245 | dev_err(&sdev->dev, "%s: registering cpufreq failed, err: %d\n", | 247 | dev_err(dev, "%s: registering cpufreq failed, err: %d\n", |
| 246 | __func__, ret); | 248 | __func__, ret); |
| 247 | } | 249 | } |
| 248 | 250 | ||
| @@ -50,7 +50,6 @@ config DEV_DAX_HMEM · 49 unmodified lines | |||
| 50 | Say M if unsure. | 50 | Say M if unsure. |
| 51 | 51 | ||
| 52 | config DEV_DAX_HMEM_DEVICES | 52 | config DEV_DAX_HMEM_DEVICES |
| 53 | depends on NUMA_KEEP_MEMINFO # for phys_to_target_node() | ||
| 54 | depends on DEV_DAX_HMEM && DAX=y | 53 | depends on DEV_DAX_HMEM && DAX=y |
| 55 | def_bool y | 54 | def_bool y |
| 56 | 55 | ||
| @@ -1039,16 +1039,15 @@ static int get_dma_id(struct dma_device *device) · 1038 unmodified lines | |||
| 1039 | static int __dma_async_device_channel_register(struct dma_device *device, | 1039 | static int __dma_async_device_channel_register(struct dma_device *device, |
| 1040 | struct dma_chan *chan) | 1040 | struct dma_chan *chan) |
| 1041 | { | 1041 | { |
| 1042 | int rc = 0; | 1042 | int rc; |
| 1043 | 1043 | ||
| 1044 | chan->local = alloc_percpu(typeof(*chan->local)); | 1044 | chan->local = alloc_percpu(typeof(*chan->local)); |
| 1045 | if (!chan->local) | 1045 | if (!chan->local) |
| 1046 | goto err_out; | 1046 | return -ENOMEM; |
| 1047 | chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL); | 1047 | chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL); |
| 1048 | if (!chan->dev) { | 1048 | if (!chan->dev) { |
| 1049 | free_percpu(chan->local); | 1049 | rc = -ENOMEM; |
| 1050 | chan->local = NULL; | 1050 | goto err_free_local; |
| 1051 | goto err_out; | ||
| 1052 | } | 1051 | } |
| 1053 | 1052 | ||
| 1054 | /* | 1053 | /* |
| @@ -1061,7 +1060,8 @@ static int __dma_async_device_channel_register(struct dma_device *device, · 6 unmodified lines | |||
| 1061 | if (chan->chan_id < 0) { | 1060 | if (chan->chan_id < 0) { |
| 1062 | pr_err("%s: unable to alloc ida for chan: %d\n", | 1061 | pr_err("%s: unable to alloc ida for chan: %d\n", |
| 1063 | __func__, chan->chan_id); | 1062 | __func__, chan->chan_id); |
| 1064 | goto err_out; | 1063 | rc = chan->chan_id; |
| 1064 | goto err_free_dev; | ||
| 1065 | } | 1065 | } |
| 1066 | 1066 | ||
| 1067 | chan->dev->device.class = &dma_devclass; | 1067 | chan->dev->device.class = &dma_devclass; |
| @@ -1082,9 +1082,10 @@ static int __dma_async_device_channel_register(struct dma_device *device, · 14 unmodified lines | |||
| 1082 | mutex_lock(&device->chan_mutex); | 1082 | mutex_lock(&device->chan_mutex); |
| 1083 | ida_free(&device->chan_ida, chan->chan_id); | 1083 | ida_free(&device->chan_ida, chan->chan_id); |
| 1084 | mutex_unlock(&device->chan_mutex); | 1084 | mutex_unlock(&device->chan_mutex); |
| 1085 | err_out: | 1085 | err_free_dev: |
| 1086 | free_percpu(chan->local); | ||
| 1087 | kfree(chan->dev); | 1086 | kfree(chan->dev); |
| 1087 | err_free_local: | ||
| 1088 | free_percpu(chan->local); | ||
| 1088 | return rc; | 1089 | return rc; |
| 1089 | } | 1090 | } |
| 1090 | 1091 | ||
| @@ -271,7 +271,7 @@ int idxd_wq_map_portal(struct idxd_wq *wq) · 270 unmodified lines | |||
| 271 | resource_size_t start; | 271 | resource_size_t start; |
| 272 | 272 | ||
| 273 | start = pci_resource_start(pdev, IDXD_WQ_BAR); | 273 | start = pci_resource_start(pdev, IDXD_WQ_BAR); |
| 274 | start = start + wq->id * IDXD_PORTAL_SIZE; | 274 | start += idxd_get_wq_portal_full_offset(wq->id, IDXD_PORTAL_LIMITED); |
| 275 | 275 | ||
| 276 | wq->dportal = devm_ioremap(dev, start, IDXD_PORTAL_SIZE); | 276 | wq->dportal = devm_ioremap(dev, start, IDXD_PORTAL_SIZE); |
| 277 | if (!wq->dportal) | 277 | if (!wq->dportal) |
| @@ -295,7 +295,7 @@ void idxd_wq_disable_cleanup(struct idxd_wq *wq) · 17 unmodified lines | |||
| 295 | int i, wq_offset; | 295 | int i, wq_offset; |
| 296 | 296 | ||
| 297 | lockdep_assert_held(&idxd->dev_lock); | 297 | lockdep_assert_held(&idxd->dev_lock); |
| 298 | memset(&wq->wqcfg, 0, sizeof(wq->wqcfg)); | 298 | memset(wq->wqcfg, 0, idxd->wqcfg_size); |
| 299 | wq->type = IDXD_WQT_NONE; | 299 | wq->type = IDXD_WQT_NONE; |
| 300 | wq->size = 0; | 300 | wq->size = 0; |
| 301 | wq->group = NULL; | 301 | wq->group = NULL; |
| @@ -304,8 +304,8 @@ void idxd_wq_disable_cleanup(struct idxd_wq *wq) · 2 unmodified lines | |||
| 304 | clear_bit(WQ_FLAG_DEDICATED, &wq->flags); | 304 | clear_bit(WQ_FLAG_DEDICATED, &wq->flags); |
| 305 | memset(wq->name, 0, WQ_NAME_SIZE); | 305 | memset(wq->name, 0, WQ_NAME_SIZE); |
| 306 | 306 | ||
| 307 | for (i = 0; i < 8; i++) { | 307 | for (i = 0; i < WQCFG_STRIDES(idxd); i++) { |
| 308 | wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32); | 308 | wq_offset = WQCFG_OFFSET(idxd, wq->id, i); |
| 309 | iowrite32(0, idxd->reg_base + wq_offset); | 309 | iowrite32(0, idxd->reg_base + wq_offset); |
| 310 | dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n", | 310 | dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n", |
| 311 | wq->id, i, wq_offset, | 311 | wq->id, i, wq_offset, |
| @@ -539,10 +539,10 @@ static int idxd_wq_config_write(struct idxd_wq *wq) · 227 unmodified lines | |||
| 539 | if (!wq->group) | 539 | if (!wq->group) |
| 540 | return 0; | 540 | return 0; |
| 541 | 541 | ||
| 542 | memset(&wq->wqcfg, 0, sizeof(union wqcfg)); | 542 | memset(wq->wqcfg, 0, idxd->wqcfg_size); |
| 543 | 543 | ||
| 544 | /* byte 0-3 */ | 544 | /* byte 0-3 */ |
| 545 | wq->wqcfg.wq_size = wq->size; | 545 | wq->wqcfg->wq_size = wq->size; |
| 546 | 546 | ||
| 547 | if (wq->size == 0) { | 547 | if (wq->size == 0) { |
| 548 | dev_warn(dev, "Incorrect work queue size: 0\n"); | 548 | dev_warn(dev, "Incorrect work queue size: 0\n"); |
| @@ -550,22 +550,21 @@ static int idxd_wq_config_write(struct idxd_wq *wq) · 1 unmodified line | |||
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | /* bytes 4-7 */ | 552 | /* bytes 4-7 */ |
| 553 | wq->wqcfg.wq_thresh = wq->threshold; | 553 | wq->wqcfg->wq_thresh = wq->threshold; |
| 554 | 554 | ||
| 555 | /* byte 8-11 */ | 555 | /* byte 8-11 */ |
| 556 | wq->wqcfg.priv = !!(wq->type == IDXD_WQT_KERNEL); | 556 | wq->wqcfg->priv = !!(wq->type == IDXD_WQT_KERNEL); |
| 557 | wq->wqcfg.mode = 1; | 557 | wq->wqcfg->mode = 1; |
| 558 | 558 | wq->wqcfg->priority = wq->priority; | |
| 559 | wq->wqcfg.priority = wq->priority; | ||
| 560 | 559 | ||
| 561 | /* bytes 12-15 */ | 560 | /* bytes 12-15 */ |
| 562 | wq->wqcfg.max_xfer_shift = ilog2(wq->max_xfer_bytes); | 561 | wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes); |
| 563 | wq->wqcfg.max_batch_shift = ilog2(wq->max_batch_size); | 562 | wq->wqcfg->max_batch_shift = ilog2(wq->max_batch_size); |
| 564 | 563 | ||
| 565 | dev_dbg(dev, "WQ %d CFGs\n", wq->id); | 564 | dev_dbg(dev, "WQ %d CFGs\n", wq->id); |
| 566 | for (i = 0; i < 8; i++) { | 565 | for (i = 0; i < WQCFG_STRIDES(idxd); i++) { |
| 567 | wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32); | 566 | wq_offset = WQCFG_OFFSET(idxd, wq->id, i); |
| 568 | iowrite32(wq->wqcfg.bits[i], idxd->reg_base + wq_offset); | 567 | iowrite32(wq->wqcfg->bits[i], idxd->reg_base + wq_offset); |
| 569 | dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n", | 568 | dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n", |
| 570 | wq->id, i, wq_offset, | 569 | wq->id, i, wq_offset, |
| 571 | ioread32(idxd->reg_base + wq_offset)); | 570 | ioread32(idxd->reg_base + wq_offset)); |
| @@ -103,7 +103,7 @@ struct idxd_wq { · 102 unmodified lines | |||
| 103 | u32 priority; | 103 | u32 priority; |
| 104 | enum idxd_wq_state state; | 104 | enum idxd_wq_state state; |
| 105 | unsigned long flags; | 105 | unsigned long flags; |
| 106 | union wqcfg wqcfg; | 106 | union wqcfg *wqcfg; |
| 107 | u32 vec_ptr; /* interrupt steering */ | 107 | u32 vec_ptr; /* interrupt steering */ |
| 108 | struct dsa_hw_desc **hw_descs; | 108 | struct dsa_hw_desc **hw_descs; |
| 109 | int num_descs; | 109 | int num_descs; |
| @@ -183,6 +183,7 @@ struct idxd_device { · 73 unmodified lines | |||
| 183 | int max_wq_size; | 183 | int max_wq_size; |
| 184 | int token_limit; | 184 | int token_limit; |
| 185 | int nr_tokens; /* non-reserved tokens */ | 185 | int nr_tokens; /* non-reserved tokens */ |
| 186 | unsigned int wqcfg_size; | ||
| 186 | 187 | ||
| 187 | union sw_err_reg sw_err; | 188 | union sw_err_reg sw_err; |
| 188 | wait_queue_head_t cmd_waitq; | 189 | wait_queue_head_t cmd_waitq; |
| @@ -178,6 +178,9 @@ static int idxd_setup_internals(struct idxd_device *idxd) · 177 unmodified lines | |||
| 178 | wq->idxd_cdev.minor = -1; | 178 | wq->idxd_cdev.minor = -1; |
| 179 | wq->max_xfer_bytes = idxd->max_xfer_bytes; | 179 | wq->max_xfer_bytes = idxd->max_xfer_bytes; |
| 180 | wq->max_batch_size = idxd->max_batch_size; | 180 | wq->max_batch_size = idxd->max_batch_size; |
| 181 | wq->wqcfg = devm_kzalloc(dev, idxd->wqcfg_size, GFP_KERNEL); | ||
| 182 | if (!wq->wqcfg) | ||
| 183 | return -ENOMEM; | ||
| 181 | } | 184 | } |
| 182 | 185 | ||
| 183 | for (i = 0; i < idxd->max_engines; i++) { | 186 | for (i = 0; i < idxd->max_engines; i++) { |
| @@ -251,6 +254,8 @@ static void idxd_read_caps(struct idxd_device *idxd) · 67 unmodified lines | |||
| 251 | dev_dbg(dev, "total workqueue size: %u\n", idxd->max_wq_size); | 254 | dev_dbg(dev, "total workqueue size: %u\n", idxd->max_wq_size); |
| 252 | idxd->max_wqs = idxd->hw.wq_cap.num_wqs; | 255 | idxd->max_wqs = idxd->hw.wq_cap.num_wqs; |
| 253 | dev_dbg(dev, "max workqueues: %u\n", idxd->max_wqs); | 256 | dev_dbg(dev, "max workqueues: %u\n", idxd->max_wqs); |
| 257 | idxd->wqcfg_size = 1 << (idxd->hw.wq_cap.wqcfg_size + IDXD_WQCFG_MIN); | ||
| 258 | dev_dbg(dev, "wqcfg size: %u\n", idxd->wqcfg_size); | ||
| 254 | 259 | ||
| 255 | /* reading operation capabilities */ | 260 | /* reading operation capabilities */ |
| 256 | for (i = 0; i < 4; i++) { | 261 | for (i = 0; i < 4; i++) { |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | #define IDXD_MMIO_BAR 0 | 9 | #define IDXD_MMIO_BAR 0 |
| 10 | #define IDXD_WQ_BAR 2 | 10 | #define IDXD_WQ_BAR 2 |
| 11 | #define IDXD_PORTAL_SIZE 0x4000 | 11 | #define IDXD_PORTAL_SIZE PAGE_SIZE |
| 12 | 12 | ||
| 13 | /* MMIO Device BAR0 Registers */ | 13 | /* MMIO Device BAR0 Registers */ |
| 14 | #define IDXD_VER_OFFSET 0x00 | 14 | #define IDXD_VER_OFFSET 0x00 |
| @@ -43,7 +43,8 @@ union wq_cap_reg { · 28 unmodified lines | |||
| 43 | struct { | 43 | struct { |
| 44 | u64 total_wq_size:16; | 44 | u64 total_wq_size:16; |
| 45 | u64 num_wqs:8; | 45 | u64 num_wqs:8; |
| 46 | u64 rsvd:24; | 46 | u64 wqcfg_size:4; |
| 47 | u64 rsvd:20; | ||
| 47 | u64 shared_mode:1; | 48 | u64 shared_mode:1; |
| 48 | u64 dedicated_mode:1; | 49 | u64 dedicated_mode:1; |
| 49 | u64 rsvd2:1; | 50 | u64 rsvd2:1; |
| @@ -55,6 +56,7 @@ union wq_cap_reg { · 5 unmodified lines | |||
| 55 | u64 bits; | 56 | u64 bits; |
| 56 | } __packed; | 57 | } __packed; |
| 57 | #define IDXD_WQCAP_OFFSET 0x20 | 58 | #define IDXD_WQCAP_OFFSET 0x20 |
| 59 | #define IDXD_WQCFG_MIN 5 | ||
| 58 | 60 | ||
| 59 | union group_cap_reg { | 61 | union group_cap_reg { |
| 60 | struct { | 62 | struct { |
| @@ -333,4 +335,23 @@ union wqcfg { · 272 unmodified lines | |||
| 333 | }; | 335 | }; |
| 334 | u32 bits[8]; | 336 | u32 bits[8]; |
| 335 | } __packed; | 337 | } __packed; |
| 338 | |||
| 339 | /* | ||
| 340 | * This macro calculates the offset into the WQCFG register | ||
| 341 | * idxd - struct idxd * | ||
| 342 | * n - wq id | ||
| 343 | * ofs - the index of the 32b dword for the config register | ||
| 344 | * | ||
| 345 | * The WQCFG register block is divided into groups per each wq. The n index | ||
| 346 | * allows us to move to the register group that's for that particular wq. | ||
| 347 | * Each register is 32bits. The ofs gives us the number of register to access. | ||
| 348 | */ | ||
| 349 | #define WQCFG_OFFSET(_idxd_dev, n, ofs) \ | ||
| 350 | ({\ | ||
| 351 | typeof(_idxd_dev) __idxd_dev = (_idxd_dev); \ | ||
| 352 | (__idxd_dev)->wqcfg_offset + (n) * (__idxd_dev)->wqcfg_size + sizeof(u32) * (ofs); \ | ||
| 353 | }) | ||
| 354 | |||
| 355 | #define WQCFG_STRIDES(_idxd_dev) ((_idxd_dev)->wqcfg_size / sizeof(u32)) | ||
| 356 | |||
| 336 | #endif | 357 | #endif |
| @@ -74,7 +74,7 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) · 73 unmodified lines | |||
| 74 | if (idxd->state != IDXD_DEV_ENABLED) | 74 | if (idxd->state != IDXD_DEV_ENABLED) |
| 75 | return -EIO; | 75 | return -EIO; |
| 76 | 76 | ||
| 77 | portal = wq->dportal + idxd_get_wq_portal_offset(IDXD_PORTAL_UNLIMITED); | 77 | portal = wq->dportal; |
| 78 | /* | 78 | /* |
| 79 | * The wmb() flushes writes to coherent DMA data before possibly | 79 | * The wmb() flushes writes to coherent DMA data before possibly |
| 80 | * triggering a DMA read. The wmb() is necessary even on UP because | 80 | * triggering a DMA read. The wmb() is necessary even on UP because |
| @@ -40,16 +40,6 @@ · 39 unmodified lines | |||
| 40 | #define DCA2_TAG_MAP_BYTE3 0x82 | 40 | #define DCA2_TAG_MAP_BYTE3 0x82 |
| 41 | #define DCA2_TAG_MAP_BYTE4 0x82 | 41 | #define DCA2_TAG_MAP_BYTE4 0x82 |
| 42 | 42 | ||
| 43 | /* verify if tag map matches expected values */ | ||
| 44 | static inline int dca2_tag_map_valid(u8 *tag_map) | ||
| 45 | { | ||
| 46 | return ((tag_map[0] == DCA2_TAG_MAP_BYTE0) && | ||
| 47 | (tag_map[1] == DCA2_TAG_MAP_BYTE1) && | ||
| 48 | (tag_map[2] == DCA2_TAG_MAP_BYTE2) && | ||
| 49 | (tag_map[3] == DCA2_TAG_MAP_BYTE3) && | ||
| 50 | (tag_map[4] == DCA2_TAG_MAP_BYTE4)); | ||
| 51 | } | ||
| 52 | |||
| 53 | /* | 43 | /* |
| 54 | * "Legacy" DCA systems do not implement the DCA register set in the | 44 | * "Legacy" DCA systems do not implement the DCA register set in the |
| 55 | * I/OAT device. Software needs direct support for their tag mappings. | 45 | * I/OAT device. Software needs direct support for their tag mappings. |
| @@ -2799,7 +2799,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, · 2798 unmodified lines | |||
| 2799 | * If burst size is smaller than bus width then make sure we only | 2799 | * If burst size is smaller than bus width then make sure we only |
| 2800 | * transfer one at a time to avoid a burst stradling an MFIFO entry. | 2800 | * transfer one at a time to avoid a burst stradling an MFIFO entry. |
| 2801 | */ | 2801 | */ |
| 2802 | if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width) | 2802 | if (burst * 8 < pl330->pcfg.data_bus_width) |
| 2803 | desc->rqcfg.brst_len = 1; | 2803 | desc->rqcfg.brst_len = 1; |
| 2804 | 2804 | ||
| 2805 | desc->bytes_requested = len; | 2805 | desc->bytes_requested = len; |
| @@ -83,7 +83,7 @@ EXPORT_SYMBOL(xudma_rflow_is_gp); · 82 unmodified lines | |||
| 83 | #define XUDMA_GET_PUT_RESOURCE(res) \ | 83 | #define XUDMA_GET_PUT_RESOURCE(res) \ |
| 84 | struct udma_##res *xudma_##res##_get(struct udma_dev *ud, int id) \ | 84 | struct udma_##res *xudma_##res##_get(struct udma_dev *ud, int id) \ |
| 85 | { \ | 85 | { \ |
| 86 | return __udma_reserve_##res(ud, false, id); \ | 86 | return __udma_reserve_##res(ud, UDMA_TP_NORMAL, id); \ |
| 87 | } \ | 87 | } \ |
| 88 | EXPORT_SYMBOL(xudma_##res##_get); \ | 88 | EXPORT_SYMBOL(xudma_##res##_get); \ |
| 89 | \ | 89 | \ |
| @@ -1522,29 +1522,38 @@ static void omap_dma_free(struct omap_dmadev *od) · 1521 unmodified lines | |||
| 1522 | } | 1522 | } |
| 1523 | } | 1523 | } |
| 1524 | 1524 | ||
| 1525 | /* Currently used by omap2 & 3 to block deeper SoC idle states */ | ||
| 1526 | static bool omap_dma_busy(struct omap_dmadev *od) | ||
| 1527 | { | ||
| 1528 | struct omap_chan *c; | ||
| 1529 | int lch = -1; | ||
| 1530 | |||
| 1531 | while (1) { | ||
| 1532 | lch = find_next_bit(od->lch_bitmap, od->lch_count, lch + 1); | ||
| 1533 | if (lch >= od->lch_count) | ||
| 1534 | break; | ||
| 1535 | c = od->lch_map[lch]; | ||
| 1536 | if (!c) | ||
| 1537 | continue; | ||
| 1538 | if (omap_dma_chan_read(c, CCR) & CCR_ENABLE) | ||
| 1539 | return true; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | return false; | ||
| 1543 | } | ||
| 1544 | |||
| 1525 | /* Currently only used for omap2. For omap1, also a check for lcd_dma is needed */ | 1545 | /* Currently only used for omap2. For omap1, also a check for lcd_dma is needed */ |
| 1526 | static int omap_dma_busy_notifier(struct notifier_block *nb, | 1546 | static int omap_dma_busy_notifier(struct notifier_block *nb, |
| 1527 | unsigned long cmd, void *v) | 1547 | unsigned long cmd, void *v) |
| 1528 | { | 1548 | { |
| 1529 | struct omap_dmadev *od; | 1549 | struct omap_dmadev *od; |
| 1530 | struct omap_chan *c; | ||
| 1531 | int lch = -1; | ||
| 1532 | 1550 | ||
| 1533 | od = container_of(nb, struct omap_dmadev, nb); | 1551 | od = container_of(nb, struct omap_dmadev, nb); |
| 1534 | 1552 | ||
| 1535 | switch (cmd) { | 1553 | switch (cmd) { |
| 1536 | case CPU_CLUSTER_PM_ENTER: | 1554 | case CPU_CLUSTER_PM_ENTER: |
| 1537 | while (1) { | 1555 | if (omap_dma_busy(od)) |
| 1538 | lch = find_next_bit(od->lch_bitmap, od->lch_count, | 1556 | return NOTIFY_BAD; |
| 1539 | lch + 1); | ||
| 1540 | if (lch >= od->lch_count) | ||
| 1541 | break; | ||
| 1542 | c = od->lch_map[lch]; | ||
| 1543 | if (!c) | ||
| 1544 | continue; | ||
| 1545 | if (omap_dma_chan_read(c, CCR) & CCR_ENABLE) | ||
| 1546 | return NOTIFY_BAD; | ||
| 1547 | } | ||
| 1548 | break; | 1557 | break; |
| 1549 | case CPU_CLUSTER_PM_ENTER_FAILED: | 1558 | case CPU_CLUSTER_PM_ENTER_FAILED: |
| 1550 | case CPU_CLUSTER_PM_EXIT: | 1559 | case CPU_CLUSTER_PM_EXIT: |
| @@ -1595,6 +1604,8 @@ static int omap_dma_context_notifier(struct notifier_block *nb, · 44 unmodified lines | |||
| 1595 | 1604 | ||
| 1596 | switch (cmd) { | 1605 | switch (cmd) { |
| 1597 | case CPU_CLUSTER_PM_ENTER: | 1606 | case CPU_CLUSTER_PM_ENTER: |
| 1607 | if (omap_dma_busy(od)) | ||
| 1608 | return NOTIFY_BAD; | ||
| 1598 | omap_dma_context_save(od); | 1609 | omap_dma_context_save(od); |
| 1599 | break; | 1610 | break; |
| 1600 | case CPU_CLUSTER_PM_ENTER_FAILED: | 1611 | case CPU_CLUSTER_PM_ENTER_FAILED: |
| @@ -517,8 +517,8 @@ struct xilinx_dma_device { · 516 unmodified lines | |||
| 517 | #define to_dma_tx_descriptor(tx) \ | 517 | #define to_dma_tx_descriptor(tx) \ |
| 518 | container_of(tx, struct xilinx_dma_tx_descriptor, async_tx) | 518 | container_of(tx, struct xilinx_dma_tx_descriptor, async_tx) |
| 519 | #define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \ | 519 | #define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \ |
| 520 | readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, val, \ | 520 | readl_poll_timeout_atomic(chan->xdev->regs + chan->ctrl_offset + reg, \ |
| 521 | cond, delay_us, timeout_us) | 521 | val, cond, delay_us, timeout_us) |
| 522 | 522 | ||
| 523 | /* IO accessors */ | 523 | /* IO accessors */ |
| 524 | static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) | 524 | static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) |
| @@ -948,8 +948,10 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan, · 423 unmodified lines | |||
| 948 | { | 948 | { |
| 949 | struct xilinx_cdma_tx_segment *cdma_seg; | 949 | struct xilinx_cdma_tx_segment *cdma_seg; |
| 950 | struct xilinx_axidma_tx_segment *axidma_seg; | 950 | struct xilinx_axidma_tx_segment *axidma_seg; |
| 951 | struct xilinx_aximcdma_tx_segment *aximcdma_seg; | ||
| 951 | struct xilinx_cdma_desc_hw *cdma_hw; | 952 | struct xilinx_cdma_desc_hw *cdma_hw; |
| 952 | struct xilinx_axidma_desc_hw *axidma_hw; | 953 | struct xilinx_axidma_desc_hw *axidma_hw; |
| 954 | struct xilinx_aximcdma_desc_hw *aximcdma_hw; | ||
| 953 | struct list_head *entry; | 955 | struct list_head *entry; |
| 954 | u32 residue = 0; | 956 | u32 residue = 0; |
| 955 | 957 | ||
| @@ -961,13 +963,23 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan, · 5 unmodified lines | |||
| 961 | cdma_hw = &cdma_seg->hw; | 963 | cdma_hw = &cdma_seg->hw; |
| 962 | residue += (cdma_hw->control - cdma_hw->status) & | 964 | residue += (cdma_hw->control - cdma_hw->status) & |
| 963 | chan->xdev->max_buffer_len; | 965 | chan->xdev->max_buffer_len; |
| 964 | } else { | 966 | } else if (chan->xdev->dma_config->dmatype == |
| 967 | XDMA_TYPE_AXIDMA) { | ||
| 965 | axidma_seg = list_entry(entry, | 968 | axidma_seg = list_entry(entry, |
| 966 | struct xilinx_axidma_tx_segment, | 969 | struct xilinx_axidma_tx_segment, |
| 967 | node); | 970 | node); |
| 968 | axidma_hw = &axidma_seg->hw; | 971 | axidma_hw = &axidma_seg->hw; |
| 969 | residue += (axidma_hw->control - axidma_hw->status) & | 972 | residue += (axidma_hw->control - axidma_hw->status) & |
| 970 | chan->xdev->max_buffer_len; | 973 | chan->xdev->max_buffer_len; |
| 974 | } else { | ||
| 975 | aximcdma_seg = | ||
| 976 | list_entry(entry, | ||
| 977 | struct xilinx_aximcdma_tx_segment, | ||
| 978 | node); | ||
| 979 | aximcdma_hw = &aximcdma_seg->hw; | ||
| 980 | residue += | ||
| 981 | (aximcdma_hw->control - aximcdma_hw->status) & | ||
| 982 | chan->xdev->max_buffer_len; | ||
| 971 | } | 983 | } |
| 972 | } | 984 | } |
| 973 | 985 | ||
| @@ -1135,7 +1147,7 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) · 161 unmodified lines | |||
| 1135 | upper_32_bits(chan->seg_p + sizeof(*chan->seg_mv) * | 1147 | upper_32_bits(chan->seg_p + sizeof(*chan->seg_mv) * |
| 1136 | ((i + 1) % XILINX_DMA_NUM_DESCS)); | 1148 | ((i + 1) % XILINX_DMA_NUM_DESCS)); |
| 1137 | chan->seg_mv[i].phys = chan->seg_p + | 1149 | chan->seg_mv[i].phys = chan->seg_p + |
| 1138 | sizeof(*chan->seg_v) * i; | 1150 | sizeof(*chan->seg_mv) * i; |
| 1139 | list_add_tail(&chan->seg_mv[i].node, | 1151 | list_add_tail(&chan->seg_mv[i].node, |
| 1140 | &chan->free_seg_list); | 1152 | &chan->free_seg_list); |
| 1141 | } | 1153 | } |
| @@ -1560,7 +1572,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) · 418 unmodified lines | |||
| 1560 | static void xilinx_mcdma_start_transfer(struct xilinx_dma_chan *chan) | 1572 | static void xilinx_mcdma_start_transfer(struct xilinx_dma_chan *chan) |
| 1561 | { | 1573 | { |
| 1562 | struct xilinx_dma_tx_descriptor *head_desc, *tail_desc; | 1574 | struct xilinx_dma_tx_descriptor *head_desc, *tail_desc; |
| 1563 | struct xilinx_axidma_tx_segment *tail_segment; | 1575 | struct xilinx_aximcdma_tx_segment *tail_segment; |
| 1564 | u32 reg; | 1576 | u32 reg; |
| 1565 | 1577 | ||
| 1566 | /* | 1578 | /* |
| @@ -1582,7 +1594,7 @@ static void xilinx_mcdma_start_transfer(struct xilinx_dma_chan *chan) · 15 unmodified lines | |||
| 1582 | tail_desc = list_last_entry(&chan->pending_list, | 1594 | tail_desc = list_last_entry(&chan->pending_list, |
| 1583 | struct xilinx_dma_tx_descriptor, node); | 1595 | struct xilinx_dma_tx_descriptor, node); |
| 1584 | tail_segment = list_last_entry(&tail_desc->segments, | 1596 | tail_segment = list_last_entry(&tail_desc->segments, |
| 1585 | struct xilinx_axidma_tx_segment, node); | 1597 | struct xilinx_aximcdma_tx_segment, node); |
| 1586 | 1598 | ||
| 1587 | reg = dma_ctrl_read(chan, XILINX_MCDMA_CHAN_CR_OFFSET(chan->tdest)); | 1599 | reg = dma_ctrl_read(chan, XILINX_MCDMA_CHAN_CR_OFFSET(chan->tdest)); |
| 1588 | 1600 | ||
| @@ -1864,6 +1876,7 @@ static void append_desc_queue(struct xilinx_dma_chan *chan, · 275 unmodified lines | |||
| 1864 | struct xilinx_vdma_tx_segment *tail_segment; | 1876 | struct xilinx_vdma_tx_segment *tail_segment; |
| 1865 | struct xilinx_dma_tx_descriptor *tail_desc; | 1877 | struct xilinx_dma_tx_descriptor *tail_desc; |
| 1866 | struct xilinx_axidma_tx_segment *axidma_tail_segment; | 1878 | struct xilinx_axidma_tx_segment *axidma_tail_segment; |
| 1879 | struct xilinx_aximcdma_tx_segment *aximcdma_tail_segment; | ||
| 1867 | struct xilinx_cdma_tx_segment *cdma_tail_segment; | 1880 | struct xilinx_cdma_tx_segment *cdma_tail_segment; |
| 1868 | 1881 | ||
| 1869 | if (list_empty(&chan->pending_list)) | 1882 | if (list_empty(&chan->pending_list)) |
| @@ -1885,11 +1898,17 @@ static void append_desc_queue(struct xilinx_dma_chan *chan, · 15 unmodified lines | |||
| 1885 | struct xilinx_cdma_tx_segment, | 1898 | struct xilinx_cdma_tx_segment, |
| 1886 | node); | 1899 | node); |
| 1887 | cdma_tail_segment->hw.next_desc = (u32)desc->async_tx.phys; | 1900 | cdma_tail_segment->hw.next_desc = (u32)desc->async_tx.phys; |
| 1888 | } else { | 1901 | } else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { |
| 1889 | axidma_tail_segment = list_last_entry(&tail_desc->segments, | 1902 | axidma_tail_segment = list_last_entry(&tail_desc->segments, |
| 1890 | struct xilinx_axidma_tx_segment, | 1903 | struct xilinx_axidma_tx_segment, |
| 1891 | node); | 1904 | node); |
| 1892 | axidma_tail_segment->hw.next_desc = (u32)desc->async_tx.phys; | 1905 | axidma_tail_segment->hw.next_desc = (u32)desc->async_tx.phys; |
| 1906 | } else { | ||
| 1907 | aximcdma_tail_segment = | ||
| 1908 | list_last_entry(&tail_desc->segments, | ||
| 1909 | struct xilinx_aximcdma_tx_segment, | ||
| 1910 | node); | ||
| 1911 | aximcdma_tail_segment->hw.next_desc = (u32)desc->async_tx.phys; | ||
| 1893 | } | 1912 | } |
| 1894 | 1913 | ||
| 1895 | /* | 1914 | /* |
| @@ -2836,10 +2855,11 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, · 940 unmodified lines | |||
| 2836 | chan->stop_transfer = xilinx_dma_stop_transfer; | 2855 | chan->stop_transfer = xilinx_dma_stop_transfer; |
| 2837 | } | 2856 | } |
| 2838 | 2857 | ||
| 2839 | /* check if SG is enabled (only for AXIDMA and CDMA) */ | 2858 | /* check if SG is enabled (only for AXIDMA, AXIMCDMA, and CDMA) */ |
| 2840 | if (xdev->dma_config->dmatype != XDMA_TYPE_VDMA) { | 2859 | if (xdev->dma_config->dmatype != XDMA_TYPE_VDMA) { |
| 2841 | if (dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & | 2860 | if (xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA || |
| 2842 | XILINX_DMA_DMASR_SG_MASK) | 2861 | dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & |
| 2862 | XILINX_DMA_DMASR_SG_MASK) | ||
| 2843 | chan->has_sg = true; | 2863 | chan->has_sg = true; |
| 2844 | dev_dbg(chan->dev, "ch %d: SG %s\n", chan->id, | 2864 | dev_dbg(chan->dev, "ch %d: SG %s\n", chan->id, |
| 2845 | chan->has_sg ? "enabled" : "disabled"); | 2865 | chan->has_sg ? "enabled" : "disabled"); |
| @@ -20,12 +20,28 @@ · 19 unmodified lines | |||
| 20 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
| 23 | #include <linux/hashtable.h> | ||
| 23 | 24 | ||
| 24 | #include <linux/firmware/xlnx-zynqmp.h> | 25 | #include <linux/firmware/xlnx-zynqmp.h> |
| 25 | #include "zynqmp-debug.h" | 26 | #include "zynqmp-debug.h" |
| 26 | 27 | ||
| 28 | /* Max HashMap Order for PM API feature check (1<<7 = 128) */ | ||
| 29 | #define PM_API_FEATURE_CHECK_MAX_ORDER 7 | ||
| 30 | |||
| 27 | static bool feature_check_enabled; | 31 | static bool feature_check_enabled; |
| 28 | static u32 zynqmp_pm_features[PM_API_MAX]; | 32 | DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER); |
| 33 | |||
| 34 | /** | ||
| 35 | * struct pm_api_feature_data - PM API Feature data | ||
| 36 | * @pm_api_id: PM API Id, used as key to index into hashmap | ||
| 37 | * @feature_status: status of PM API feature: valid, invalid | ||
| 38 | * @hentry: hlist_node that hooks this entry into hashtable | ||
| 39 | */ | ||
| 40 | struct pm_api_feature_data { | ||
| 41 | u32 pm_api_id; | ||
| 42 | int feature_status; | ||
| 43 | struct hlist_node hentry; | ||
| 44 | }; | ||
| 29 | 45 | ||
| 30 | static const struct mfd_cell firmware_devs[] = { | 46 | static const struct mfd_cell firmware_devs[] = { |
| 31 | { | 47 | { |
| @@ -142,29 +158,37 @@ static int zynqmp_pm_feature(u32 api_id) · 110 unmodified lines | |||
| 142 | int ret; | 158 | int ret; |
| 143 | u32 ret_payload[PAYLOAD_ARG_CNT]; | 159 | u32 ret_payload[PAYLOAD_ARG_CNT]; |
| 144 | u64 smc_arg[2]; | 160 | u64 smc_arg[2]; |
| 161 | struct pm_api_feature_data *feature_data; | ||
| 145 | 162 | ||
| 146 | if (!feature_check_enabled) | 163 | if (!feature_check_enabled) |
| 147 | return 0; | 164 | return 0; |
| 148 | 165 | ||
| 149 | /* Return value if feature is already checked */ | 166 | /* Check for existing entry in hash table for given api */ |
| 150 | if (api_id > ARRAY_SIZE(zynqmp_pm_features)) | 167 | hash_for_each_possible(pm_api_features_map, feature_data, hentry, |
| 151 | return PM_FEATURE_INVALID; | 168 | api_id) { |
| 169 | if (feature_data->pm_api_id == api_id) | ||
| 170 | return feature_data->feature_status; | ||
| 171 | } | ||
| 152 | 172 | ||
| 153 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED) | 173 | /* Add new entry if not present */ |
| 154 | return zynqmp_pm_features[api_id]; | 174 | feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL); |
| 175 | if (!feature_data) | ||
| 176 | return -ENOMEM; | ||
| 155 | 177 | ||
| 178 | feature_data->pm_api_id = api_id; | ||
| 156 | smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK; | 179 | smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK; |
| 157 | smc_arg[1] = api_id; | 180 | smc_arg[1] = api_id; |
| 158 | 181 | ||
| 159 | ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload); | 182 | ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload); |
| 160 | if (ret) { | 183 | if (ret) |
| 161 | zynqmp_pm_features[api_id] = PM_FEATURE_INVALID; | 184 | ret = -EOPNOTSUPP; |
| 162 | return PM_FEATURE_INVALID; | 185 | else |
| 163 | } | 186 | ret = ret_payload[1]; |
| 164 | 187 | ||
| 165 | zynqmp_pm_features[api_id] = ret_payload[1]; | 188 | feature_data->feature_status = ret; |
| 189 | hash_add(pm_api_features_map, &feature_data->hentry, api_id); | ||
| 166 | 190 | ||
| 167 | return zynqmp_pm_features[api_id]; | 191 | return ret; |
| 168 | } | 192 | } |
| 169 | 193 | ||
| 170 | /** | 194 | /** |
| @@ -200,9 +224,12 @@ int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1, · 29 unmodified lines | |||
| 200 | * Make sure to stay in x0 register | 224 | * Make sure to stay in x0 register |
| 201 | */ | 225 | */ |
| 202 | u64 smc_arg[4]; | 226 | u64 smc_arg[4]; |
| 227 | int ret; | ||
| 203 | 228 | ||
| 204 | if (zynqmp_pm_feature(pm_api_id) == PM_FEATURE_INVALID) | 229 | /* Check if feature is supported or not */ |
| 205 | return -ENOTSUPP; | 230 | ret = zynqmp_pm_feature(pm_api_id); |
| 231 | if (ret < 0) | ||
| 232 | return ret; | ||
| 206 | 233 | ||
| 207 | smc_arg[0] = PM_SIP_SVC | pm_api_id; | 234 | smc_arg[0] = PM_SIP_SVC | pm_api_id; |
| 208 | smc_arg[1] = ((u64)arg1 << 32) | arg0; | 235 | smc_arg[1] = ((u64)arg1 << 32) | arg0; |
| @@ -615,7 +642,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay); · 406 unmodified lines | |||
| 615 | */ | 642 | */ |
| 616 | int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) | 643 | int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) |
| 617 | { | 644 | { |
| 618 | return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SET_SD_TAPDELAY, | 645 | return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SD_DLL_RESET, |
| 619 | type, 0, NULL); | 646 | type, 0, NULL); |
| 620 | } | 647 | } |
| 621 | EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); | 648 | EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); |
| @@ -1252,9 +1279,17 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) · 630 unmodified lines | |||
| 1252 | 1279 | ||
| 1253 | static int zynqmp_firmware_remove(struct platform_device *pdev) | 1280 | static int zynqmp_firmware_remove(struct platform_device *pdev) |
| 1254 | { | 1281 | { |
| 1282 | struct pm_api_feature_data *feature_data; | ||
| 1283 | int i; | ||
| 1284 | |||
| 1255 | mfd_remove_devices(&pdev->dev); | 1285 | mfd_remove_devices(&pdev->dev); |
| 1256 | zynqmp_pm_api_debugfs_exit(); | 1286 | zynqmp_pm_api_debugfs_exit(); |
| 1257 | 1287 | ||
| 1288 | hash_for_each(pm_api_features_map, i, feature_data, hentry) { | ||
| 1289 | hash_del(&feature_data->hentry); | ||
| 1290 | kfree(feature_data); | ||
| 1291 | } | ||
| 1292 | |||
| 1258 | return 0; | 1293 | return 0; |
| 1259 | } | 1294 | } |
| 1260 | 1295 | ||
| @@ -4852,7 +4852,7 @@ int amdgpu_device_baco_enter(struct drm_device *dev) · 4851 unmodified lines | |||
| 4852 | if (!amdgpu_device_supports_baco(adev_to_drm(adev))) | 4852 | if (!amdgpu_device_supports_baco(adev_to_drm(adev))) |
| 4853 | return -ENOTSUPP; | 4853 | return -ENOTSUPP; |
| 4854 | 4854 | ||
| 4855 | if (ras && ras->supported) | 4855 | if (ras && ras->supported && adev->nbio.funcs->enable_doorbell_interrupt) |
| 4856 | adev->nbio.funcs->enable_doorbell_interrupt(adev, false); | 4856 | adev->nbio.funcs->enable_doorbell_interrupt(adev, false); |
| 4857 | 4857 | ||
| 4858 | return amdgpu_dpm_baco_enter(adev); | 4858 | return amdgpu_dpm_baco_enter(adev); |
| @@ -4871,7 +4871,7 @@ int amdgpu_device_baco_exit(struct drm_device *dev) · 12 unmodified lines | |||
| 4871 | if (ret) | 4871 | if (ret) |
| 4872 | return ret; | 4872 | return ret; |
| 4873 | 4873 | ||
| 4874 | if (ras && ras->supported) | 4874 | if (ras && ras->supported && adev->nbio.funcs->enable_doorbell_interrupt) |
| 4875 | adev->nbio.funcs->enable_doorbell_interrupt(adev, true); | 4875 | adev->nbio.funcs->enable_doorbell_interrupt(adev, true); |
| 4876 | 4876 | ||
| 4877 | return 0; | 4877 | return 0; |
| @@ -1055,10 +1055,10 @@ static const struct pci_device_id pciidlist[] = { · 1054 unmodified lines | |||
| 1055 | {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, | 1055 | {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, |
| 1056 | {0x1002, 0x15d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, | 1056 | {0x1002, 0x15d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, |
| 1057 | /* Arcturus */ | 1057 | /* Arcturus */ |
| 1058 | {0x1002, 0x738C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT}, | 1058 | {0x1002, 0x738C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS}, |
| 1059 | {0x1002, 0x7388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT}, | 1059 | {0x1002, 0x7388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS}, |
| 1060 | {0x1002, 0x738E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT}, | 1060 | {0x1002, 0x738E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS}, |
| 1061 | {0x1002, 0x7390, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT}, | 1061 | {0x1002, 0x7390, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS}, |
| 1062 | /* Navi10 */ | 1062 | /* Navi10 */ |
| 1063 | {0x1002, 0x7310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, | 1063 | {0x1002, 0x7310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, |
| 1064 | {0x1002, 0x7312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, | 1064 | {0x1002, 0x7312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, |
| @@ -69,10 +69,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_bo_device *bdev, · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev, | 70 | static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev, |
| 71 | unsigned int type, | 71 | unsigned int type, |
| 72 | uint64_t size) | 72 | uint64_t size_in_page) |
| 73 | { | 73 | { |
| 74 | return ttm_range_man_init(&adev->mman.bdev, type, | 74 | return ttm_range_man_init(&adev->mman.bdev, type, |
| 75 | false, size >> PAGE_SHIFT); | 75 | false, size_in_page); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /** | 78 | /** |
| @@ -67,6 +67,7 @@ struct amdgpu_uvd { · 66 unmodified lines | |||
| 67 | unsigned harvest_config; | 67 | unsigned harvest_config; |
| 68 | /* store image width to adjust nb memory state */ | 68 | /* store image width to adjust nb memory state */ |
| 69 | unsigned decode_image_width; | 69 | unsigned decode_image_width; |
| 70 | uint32_t keyselect; | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | int amdgpu_uvd_sw_init(struct amdgpu_device *adev); | 73 | int amdgpu_uvd_sw_init(struct amdgpu_device *adev); |
| @@ -3105,6 +3105,8 @@ static const struct soc15_reg_golden golden_settings_gc_10_3[] = · 3104 unmodified lines | |||
| 3105 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000280), | 3105 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000280), |
| 3106 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000), | 3106 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000), |
| 3107 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000), | 3107 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000), |
| 3108 | SOC15_REG_GOLDEN_VALUE(GC, 0 ,mmGCEA_SDP_TAG_RESERVE0, 0xffffffff, 0x10100100), | ||
| 3109 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCEA_SDP_TAG_RESERVE1, 0xffffffff, 0x17000088), | ||
| 3108 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL_Sienna_Cichlid, 0x1ff1ffff, 0x00000500), | 3110 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL_Sienna_Cichlid, 0x1ff1ffff, 0x00000500), |
| 3109 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGE_PC_CNTL, 0x003fffff, 0x00280400), | 3111 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGE_PC_CNTL, 0x003fffff, 0x00280400), |
| 3110 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xffffffcf), | 3112 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xffffffcf), |
| @@ -277,15 +277,8 @@ static void uvd_v3_1_mc_resume(struct amdgpu_device *adev) · 276 unmodified lines | |||
| 277 | */ | 277 | */ |
| 278 | static int uvd_v3_1_fw_validate(struct amdgpu_device *adev) | 278 | static int uvd_v3_1_fw_validate(struct amdgpu_device *adev) |
| 279 | { | 279 | { |
| 280 | void *ptr; | 280 | int i; |
| 281 | uint32_t ucode_len, i; | 281 | uint32_t keysel = adev->uvd.keyselect; |
| 282 | uint32_t keysel; | ||
| 283 | |||
| 284 | ptr = adev->uvd.inst[0].cpu_addr; | ||
| 285 | ptr += 192 + 16; | ||
| 286 | memcpy(&ucode_len, ptr, 4); | ||
| 287 | ptr += ucode_len; | ||
| 288 | memcpy(&keysel, ptr, 4); | ||
| 289 | 282 | ||
| 290 | WREG32(mmUVD_FW_START, keysel); | 283 | WREG32(mmUVD_FW_START, keysel); |
| 291 | 284 | ||
| @@ -550,6 +543,8 @@ static int uvd_v3_1_sw_init(void *handle) · 258 unmodified lines | |||
| 550 | struct amdgpu_ring *ring; | 543 | struct amdgpu_ring *ring; |
| 551 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 544 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 552 | int r; | 545 | int r; |
| 546 | void *ptr; | ||
| 547 | uint32_t ucode_len; | ||
| 553 | 548 | ||
| 554 | /* UVD TRAP */ | 549 | /* UVD TRAP */ |
| 555 | r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); | 550 | r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); |
| @@ -571,6 +566,13 @@ static int uvd_v3_1_sw_init(void *handle) · 15 unmodified lines | |||
| 571 | if (r) | 566 | if (r) |
| 572 | return r; | 567 | return r; |
| 573 | 568 | ||
| 569 | /* Retrieval firmware validate key */ | ||
| 570 | ptr = adev->uvd.inst[0].cpu_addr; | ||
| 571 | ptr += 192 + 16; | ||
| 572 | memcpy(&ucode_len, ptr, 4); | ||
| 573 | ptr += ucode_len; | ||
| 574 | memcpy(&adev->uvd.keyselect, ptr, 4); | ||
| 575 | |||
| 574 | r = amdgpu_uvd_entity_init(adev); | 576 | r = amdgpu_uvd_entity_init(adev); |
| 575 | 577 | ||
| 576 | return r; | 578 | return r; |
| @@ -1041,7 +1041,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 1040 unmodified lines | |||
| 1041 | amdgpu_dm_init_color_mod(); | 1041 | amdgpu_dm_init_color_mod(); |
| 1042 | 1042 | ||
| 1043 | #ifdef CONFIG_DRM_AMD_DC_HDCP | 1043 | #ifdef CONFIG_DRM_AMD_DC_HDCP |
| 1044 | if (adev->asic_type >= CHIP_RAVEN) { | 1044 | if (adev->dm.dc->caps.max_links > 0 && adev->asic_type >= CHIP_RAVEN) { |
| 1045 | adev->dm.hdcp_workqueue = hdcp_create_workqueue(adev, &init_params.cp_psp, adev->dm.dc); | 1045 | adev->dm.hdcp_workqueue = hdcp_create_workqueue(adev, &init_params.cp_psp, adev->dm.dc); |
| 1046 | 1046 | ||
| 1047 | if (!adev->dm.hdcp_workqueue) | 1047 | if (!adev->dm.hdcp_workqueue) |
| @@ -7506,7 +7506,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 6458 unmodified lines | |||
| 7506 | bool mode_set_reset_required = false; | 7506 | bool mode_set_reset_required = false; |
| 7507 | 7507 | ||
| 7508 | drm_atomic_helper_update_legacy_modeset_state(dev, state); | 7508 | drm_atomic_helper_update_legacy_modeset_state(dev, state); |
| 7509 | drm_atomic_helper_calc_timestamping_constants(state); | ||
| 7510 | 7509 | ||
| 7511 | dm_state = dm_atomic_get_new_state(state); | 7510 | dm_state = dm_atomic_get_new_state(state); |
| 7512 | if (dm_state && dm_state->context) { | 7511 | if (dm_state && dm_state->context) { |
| @@ -7533,6 +7532,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 20 unmodified lines | |||
| 7533 | } | 7532 | } |
| 7534 | } | 7533 | } |
| 7535 | 7534 | ||
| 7535 | drm_atomic_helper_calc_timestamping_constants(state); | ||
| 7536 | |||
| 7536 | /* update changed items */ | 7537 | /* update changed items */ |
| 7537 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | 7538 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 7538 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); | 7539 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); |
| @@ -299,8 +299,8 @@ irq_source_info_dcn20[DAL_IRQ_SOURCES_NUMBER] = { · 298 unmodified lines | |||
| 299 | pflip_int_entry(1), | 299 | pflip_int_entry(1), |
| 300 | pflip_int_entry(2), | 300 | pflip_int_entry(2), |
| 301 | pflip_int_entry(3), | 301 | pflip_int_entry(3), |
| 302 | [DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(), | 302 | pflip_int_entry(4), |
| 303 | [DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(), | 303 | pflip_int_entry(5), |
| 304 | [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(), | 304 | [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(), |
| 305 | gpio_pad_int_entry(0), | 305 | gpio_pad_int_entry(0), |
| 306 | gpio_pad_int_entry(1), | 306 | gpio_pad_int_entry(1), |
| @@ -742,7 +742,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) · 741 unmodified lines | |||
| 742 | case DRM_MODE_DPMS_SUSPEND: | 742 | case DRM_MODE_DPMS_SUSPEND: |
| 743 | if (ast->tx_chip_type == AST_TX_DP501) | 743 | if (ast->tx_chip_type == AST_TX_DP501) |
| 744 | ast_set_dp501_video_output(crtc->dev, 1); | 744 | ast_set_dp501_video_output(crtc->dev, 1); |
| 745 | ast_crtc_load_lut(ast, crtc); | ||
| 746 | break; | 745 | break; |
| 747 | case DRM_MODE_DPMS_OFF: | 746 | case DRM_MODE_DPMS_OFF: |
| 748 | if (ast->tx_chip_type == AST_TX_DP501) | 747 | if (ast->tx_chip_type == AST_TX_DP501) |
| @@ -777,6 +776,21 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, · 28 unmodified lines | |||
| 777 | return 0; | 776 | return 0; |
| 778 | } | 777 | } |
| 779 | 778 | ||
| 779 | static void | ||
| 780 | ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) | ||
| 781 | { | ||
| 782 | struct ast_private *ast = to_ast_private(crtc->dev); | ||
| 783 | struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state); | ||
| 784 | struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); | ||
| 785 | |||
| 786 | /* | ||
| 787 | * The gamma LUT has to be reloaded after changing the primary | ||
| 788 | * plane's color format. | ||
| 789 | */ | ||
| 790 | if (old_ast_crtc_state->format != ast_crtc_state->format) | ||
| 791 | ast_crtc_load_lut(ast, crtc); | ||
| 792 | } | ||
| 793 | |||
| 780 | static void | 794 | static void |
| 781 | ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, | 795 | ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, |
| 782 | struct drm_crtc_state *old_crtc_state) | 796 | struct drm_crtc_state *old_crtc_state) |
| @@ -830,6 +844,7 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, · 47 unmodified lines | |||
| 830 | 844 | ||
| 831 | static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { | 845 | static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { |
| 832 | .atomic_check = ast_crtc_helper_atomic_check, | 846 | .atomic_check = ast_crtc_helper_atomic_check, |
| 847 | .atomic_flush = ast_crtc_helper_atomic_flush, | ||
| 833 | .atomic_enable = ast_crtc_helper_atomic_enable, | 848 | .atomic_enable = ast_crtc_helper_atomic_enable, |
| 834 | .atomic_disable = ast_crtc_helper_atomic_disable, | 849 | .atomic_disable = ast_crtc_helper_atomic_disable, |
| 835 | }; | 850 | }; |
| @@ -2327,12 +2327,6 @@ static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi) · 2326 unmodified lines | |||
| 2327 | { | 2327 | { |
| 2328 | enum drm_connector_status result; | 2328 | enum drm_connector_status result; |
| 2329 | 2329 | ||
| 2330 | mutex_lock(&hdmi->mutex); | ||
| 2331 | hdmi->force = DRM_FORCE_UNSPECIFIED; | ||
| 2332 | dw_hdmi_update_power(hdmi); | ||
| 2333 | dw_hdmi_update_phy_mask(hdmi); | ||
| 2334 | mutex_unlock(&hdmi->mutex); | ||
| 2335 | |||
| 2336 | result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); | 2330 | result = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); |
| 2337 | 2331 | ||
| 2338 | mutex_lock(&hdmi->mutex); | 2332 | mutex_lock(&hdmi->mutex); |
| @@ -140,7 +140,7 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, · 139 unmodified lines | |||
| 140 | unsigned int c = 0; | 140 | unsigned int c = 0; |
| 141 | 141 | ||
| 142 | if (pl_flag & DRM_GEM_VRAM_PL_FLAG_TOPDOWN) | 142 | if (pl_flag & DRM_GEM_VRAM_PL_FLAG_TOPDOWN) |
| 143 | pl_flag = TTM_PL_FLAG_TOPDOWN; | 143 | invariant_flags = TTM_PL_FLAG_TOPDOWN; |
| 144 | 144 | ||
| 145 | gbo->placement.placement = gbo->placements; | 145 | gbo->placement.placement = gbo->placements; |
| 146 | gbo->placement.busy_placement = gbo->placements; | 146 | gbo->placement.busy_placement = gbo->placements; |
| @@ -1,7 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | config DRM_EXYNOS | 2 | config DRM_EXYNOS |
| 3 | tristate "DRM Support for Samsung SoC Exynos Series" | 3 | tristate "DRM Support for Samsung SoC Exynos Series" |
| 4 | depends on OF && DRM && (ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_MULTIPLATFORM || COMPILE_TEST) | 4 | depends on OF && DRM && COMMON_CLK |
| 5 | depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_MULTIPLATFORM || COMPILE_TEST | ||
| 5 | depends on MMU | 6 | depends on MMU |
| 6 | select DRM_KMS_HELPER | 7 | select DRM_KMS_HELPER |
| 7 | select VIDEOMODE_HELPERS | 8 | select VIDEOMODE_HELPERS |
| @@ -12878,10 +12878,11 @@ compute_sink_pipe_bpp(const struct drm_connector_state *conn_state, · 12877 unmodified lines | |||
| 12878 | case 10 ... 11: | 12878 | case 10 ... 11: |
| 12879 | bpp = 10 * 3; | 12879 | bpp = 10 * 3; |
| 12880 | break; | 12880 | break; |
| 12881 | case 12: | 12881 | case 12 ... 16: |
| 12882 | bpp = 12 * 3; | 12882 | bpp = 12 * 3; |
| 12883 | break; | 12883 | break; |
| 12884 | default: | 12884 | default: |
| 12885 | MISSING_CASE(conn_state->max_bpc); | ||
| 12885 | return -EINVAL; | 12886 | return -EINVAL; |
| 12886 | } | 12887 | } |
| 12887 | 12888 | ||
| @@ -30,18 +30,21 @@ · 29 unmodified lines | |||
| 30 | #include "i915_trace.h" | 30 | #include "i915_trace.h" |
| 31 | #include "intel_breadcrumbs.h" | 31 | #include "intel_breadcrumbs.h" |
| 32 | #include "intel_context.h" | 32 | #include "intel_context.h" |
| 33 | #include "intel_engine_pm.h" | ||
| 33 | #include "intel_gt_pm.h" | 34 | #include "intel_gt_pm.h" |
| 34 | #include "intel_gt_requests.h" | 35 | #include "intel_gt_requests.h" |
| 35 | 36 | ||
| 36 | static void irq_enable(struct intel_engine_cs *engine) | 37 | static bool irq_enable(struct intel_engine_cs *engine) |
| 37 | { | 38 | { |
| 38 | if (!engine->irq_enable) | 39 | if (!engine->irq_enable) |
| 39 | return; | 40 | return false; |
| 40 | 41 | ||
| 41 | /* Caller disables interrupts */ | 42 | /* Caller disables interrupts */ |
| 42 | spin_lock(&engine->gt->irq_lock); | 43 | spin_lock(&engine->gt->irq_lock); |
| 43 | engine->irq_enable(engine); | 44 | engine->irq_enable(engine); |
| 44 | spin_unlock(&engine->gt->irq_lock); | 45 | spin_unlock(&engine->gt->irq_lock); |
| 46 | |||
| 47 | return true; | ||
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | static void irq_disable(struct intel_engine_cs *engine) | 50 | static void irq_disable(struct intel_engine_cs *engine) |
| @@ -57,12 +60,11 @@ static void irq_disable(struct intel_engine_cs *engine) · 9 unmodified lines | |||
| 57 | 60 | ||
| 58 | static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) | 61 | static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) |
| 59 | { | 62 | { |
| 60 | lockdep_assert_held(&b->irq_lock); | 63 | /* |
| 61 | 64 | * Since we are waiting on a request, the GPU should be busy | |
| 62 | if (!b->irq_engine || b->irq_armed) | 65 | * and should have its own rpm reference. |
| 63 | return; | 66 | */ |
| 64 | 67 | if (GEM_WARN_ON(!intel_gt_pm_get_if_awake(b->irq_engine->gt))) | |
| 65 | if (!intel_gt_pm_get_if_awake(b->irq_engine->gt)) | ||
| 66 | return; | 68 | return; |
| 67 | 69 | ||
| 68 | /* | 70 | /* |
| @@ -73,25 +75,24 @@ static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) · 4 unmodified lines | |||
| 73 | */ | 75 | */ |
| 74 | WRITE_ONCE(b->irq_armed, true); | 76 | WRITE_ONCE(b->irq_armed, true); |
| 75 | 77 | ||
| 76 | /* | 78 | /* Requests may have completed before we could enable the interrupt. */ |
| 77 | * Since we are waiting on a request, the GPU should be busy | 79 | if (!b->irq_enabled++ && irq_enable(b->irq_engine)) |
| 78 | * and should have its own rpm reference. This is tracked | 80 | irq_work_queue(&b->irq_work); |
| 79 | * by i915->gt.awake, we can forgo holding our own wakref | ||
| 80 | * for the interrupt as before i915->gt.awake is released (when | ||
| 81 | * the driver is idle) we disarm the breadcrumbs. | ||
| 82 | */ | ||
| 83 | |||
| 84 | if (!b->irq_enabled++) | ||
| 85 | irq_enable(b->irq_engine); | ||
| 86 | } | 81 | } |
| 87 | 82 | ||
| 88 | static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) | 83 | static void intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) |
| 89 | { | 84 | { |
| 90 | lockdep_assert_held(&b->irq_lock); | 85 | if (!b->irq_engine) |
| 91 | |||
| 92 | if (!b->irq_engine || !b->irq_armed) | ||
| 93 | return; | 86 | return; |
| 94 | 87 | ||
| 88 | spin_lock(&b->irq_lock); | ||
| 89 | if (!b->irq_armed) | ||
| 90 | __intel_breadcrumbs_arm_irq(b); | ||
| 91 | spin_unlock(&b->irq_lock); | ||
| 92 | } | ||
| 93 | |||
| 94 | static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) | ||
| 95 | { | ||
| 95 | GEM_BUG_ON(!b->irq_enabled); | 96 | GEM_BUG_ON(!b->irq_enabled); |
| 96 | if (!--b->irq_enabled) | 97 | if (!--b->irq_enabled) |
| 97 | irq_disable(b->irq_engine); | 98 | irq_disable(b->irq_engine); |
| @@ -105,8 +106,6 @@ static void add_signaling_context(struct intel_breadcrumbs *b, · 7 unmodified lines | |||
| 105 | { | 106 | { |
| 106 | intel_context_get(ce); | 107 | intel_context_get(ce); |
| 107 | list_add_tail(&ce->signal_link, &b->signalers); | 108 | list_add_tail(&ce->signal_link, &b->signalers); |
| 108 | if (list_is_first(&ce->signal_link, &b->signalers)) | ||
| 109 | __intel_breadcrumbs_arm_irq(b); | ||
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | static void remove_signaling_context(struct intel_breadcrumbs *b, | 111 | static void remove_signaling_context(struct intel_breadcrumbs *b, |
| @@ -174,34 +173,65 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl) · 61 unmodified lines | |||
| 174 | intel_engine_add_retire(b->irq_engine, tl); | 173 | intel_engine_add_retire(b->irq_engine, tl); |
| 175 | } | 174 | } |
| 176 | 175 | ||
| 177 | static bool __signal_request(struct i915_request *rq, struct list_head *signals) | 176 | static bool __signal_request(struct i915_request *rq) |
| 178 | { | 177 | { |
| 179 | clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); | ||
| 180 | |||
| 181 | if (!__dma_fence_signal(&rq->fence)) { | 178 | if (!__dma_fence_signal(&rq->fence)) { |
| 182 | i915_request_put(rq); | 179 | i915_request_put(rq); |
| 183 | return false; | 180 | return false; |
| 184 | } | 181 | } |
| 185 | 182 | ||
| 186 | list_add_tail(&rq->signal_link, signals); | ||
| 187 | return true; | 183 | return true; |
| 188 | } | 184 | } |
| 189 | 185 | ||
| 186 | static struct llist_node * | ||
| 187 | slist_add(struct llist_node *node, struct llist_node *head) | ||
| 188 | { | ||
| 189 | node->next = head; | ||
| 190 | return node; | ||
| 191 | } | ||
| 192 | |||
| 190 | static void signal_irq_work(struct irq_work *work) | 193 | static void signal_irq_work(struct irq_work *work) |
| 191 | { | 194 | { |
| 192 | struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work); | 195 | struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work); |
| 193 | const ktime_t timestamp = ktime_get(); | 196 | const ktime_t timestamp = ktime_get(); |
| 197 | struct llist_node *signal, *sn; | ||
| 194 | struct intel_context *ce, *cn; | 198 | struct intel_context *ce, *cn; |
| 195 | struct list_head *pos, *next; | 199 | struct list_head *pos, *next; |
| 196 | LIST_HEAD(signal); | 200 | |
| 201 | signal = NULL; | ||
| 202 | if (unlikely(!llist_empty(&b->signaled_requests))) | ||
| 203 | signal = llist_del_all(&b->signaled_requests); | ||
| 197 | 204 | ||
| 198 | spin_lock(&b->irq_lock); | 205 | spin_lock(&b->irq_lock); |
| 199 | 206 | ||
| 200 | if (list_empty(&b->signalers)) | 207 | /* |
| 208 | * Keep the irq armed until the interrupt after all listeners are gone. | ||
| 209 | * | ||
| 210 | * Enabling/disabling the interrupt is rather costly, roughly a couple | ||
| 211 | * of hundred microseconds. If we are proactive and enable/disable | ||
| 212 | * the interrupt around every request that wants a breadcrumb, we | ||
| 213 | * quickly drown in the extra orders of magnitude of latency imposed | ||
| 214 | * on request submission. | ||
| 215 | * | ||
| 216 | * So we try to be lazy, and keep the interrupts enabled until no | ||
| 217 | * more listeners appear within a breadcrumb interrupt interval (that | ||
| 218 | * is until a request completes that no one cares about). The | ||
| 219 | * observation is that listeners come in batches, and will often | ||
| 220 | * listen to a bunch of requests in succession. Though note on icl+, | ||
| 221 | * interrupts are always enabled due to concerns with rc6 being | ||
| 222 | * dysfunctional with per-engine interrupt masking. | ||
| 223 | * | ||
| 224 | * We also try to avoid raising too many interrupts, as they may | ||
| 225 | * be generated by userspace batches and it is unfortunately rather | ||
| 226 | * too easy to drown the CPU under a flood of GPU interrupts. Thus | ||
| 227 | * whenever no one appears to be listening, we turn off the interrupts. | ||
| 228 | * Fewer interrupts should conserve power -- at the very least, fewer | ||
| 229 | * interrupt draw less ire from other users of the system and tools | ||
| 230 | * like powertop. | ||
| 231 | */ | ||
| 232 | if (!signal && b->irq_armed && list_empty(&b->signalers)) | ||
| 201 | __intel_breadcrumbs_disarm_irq(b); | 233 | __intel_breadcrumbs_disarm_irq(b); |
| 202 | 234 | ||
| 203 | list_splice_init(&b->signaled_requests, &signal); | ||
| 204 | |||
| 205 | list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) { | 235 | list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) { |
| 206 | GEM_BUG_ON(list_empty(&ce->signals)); | 236 | GEM_BUG_ON(list_empty(&ce->signals)); |
| 207 | 237 | ||
| @@ -218,7 +248,10 @@ static void signal_irq_work(struct irq_work *work) · 10 unmodified lines | |||
| 218 | * spinlock as the callback chain may end up adding | 248 | * spinlock as the callback chain may end up adding |
| 219 | * more signalers to the same context or engine. | 249 | * more signalers to the same context or engine. |
| 220 | */ | 250 | */ |
| 221 | __signal_request(rq, &signal); | 251 | clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); |
| 252 | if (__signal_request(rq)) | ||
| 253 | /* We own signal_node now, xfer to local list */ | ||
| 254 | signal = slist_add(&rq->signal_node, signal); | ||
| 222 | } | 255 | } |
| 223 | 256 | ||
| 224 | /* | 257 | /* |
| @@ -238,9 +271,9 @@ static void signal_irq_work(struct irq_work *work) · 13 unmodified lines | |||
| 238 | 271 | ||
| 239 | spin_unlock(&b->irq_lock); | 272 | spin_unlock(&b->irq_lock); |
| 240 | 273 | ||
| 241 | list_for_each_safe(pos, next, &signal) { | 274 | llist_for_each_safe(signal, sn, signal) { |
| 242 | struct i915_request *rq = | 275 | struct i915_request *rq = |
| 243 | list_entry(pos, typeof(*rq), signal_link); | 276 | llist_entry(signal, typeof(*rq), signal_node); |
| 244 | struct list_head cb_list; | 277 | struct list_head cb_list; |
| 245 | 278 | ||
| 246 | spin_lock(&rq->lock); | 279 | spin_lock(&rq->lock); |
| @@ -251,6 +284,9 @@ static void signal_irq_work(struct irq_work *work) · 4 unmodified lines | |||
| 251 | 284 | ||
| 252 | i915_request_put(rq); | 285 | i915_request_put(rq); |
| 253 | } | 286 | } |
| 287 | |||
| 288 | if (!READ_ONCE(b->irq_armed) && !list_empty(&b->signalers)) | ||
| 289 | intel_breadcrumbs_arm_irq(b); | ||
| 254 | } | 290 | } |
| 255 | 291 | ||
| 256 | struct intel_breadcrumbs * | 292 | struct intel_breadcrumbs * |
| @@ -264,7 +300,7 @@ intel_breadcrumbs_create(struct intel_engine_cs *irq_engine) · 7 unmodified lines | |||
| 264 | 300 | ||
| 265 | spin_lock_init(&b->irq_lock); | 301 | spin_lock_init(&b->irq_lock); |
| 266 | INIT_LIST_HEAD(&b->signalers); | 302 | INIT_LIST_HEAD(&b->signalers); |
| 267 | INIT_LIST_HEAD(&b->signaled_requests); | 303 | init_llist_head(&b->signaled_requests); |
| 268 | 304 | ||
| 269 | init_irq_work(&b->irq_work, signal_irq_work); | 305 | init_irq_work(&b->irq_work, signal_irq_work); |
| 270 | 306 | ||
| @@ -292,21 +328,22 @@ void intel_breadcrumbs_reset(struct intel_breadcrumbs *b) · 21 unmodified lines | |||
| 292 | 328 | ||
| 293 | void intel_breadcrumbs_park(struct intel_breadcrumbs *b) | 329 | void intel_breadcrumbs_park(struct intel_breadcrumbs *b) |
| 294 | { | 330 | { |
| 295 | unsigned long flags; | 331 | /* Kick the work once more to drain the signalers */ |
| 296 | 332 | irq_work_sync(&b->irq_work); | |
| 297 | if (!READ_ONCE(b->irq_armed)) | 333 | while (unlikely(READ_ONCE(b->irq_armed))) { |
| 298 | return; | 334 | local_irq_disable(); |
| 299 | 335 | signal_irq_work(&b->irq_work); | |
| 300 | spin_lock_irqsave(&b->irq_lock, flags); | 336 | local_irq_enable(); |
| 301 | __intel_breadcrumbs_disarm_irq(b); | 337 | cond_resched(); |
| 302 | spin_unlock_irqrestore(&b->irq_lock, flags); | 338 | } |
| 303 | 339 | GEM_BUG_ON(!list_empty(&b->signalers)); | |
| 304 | if (!list_empty(&b->signalers)) | ||
| 305 | irq_work_queue(&b->irq_work); | ||
| 306 | } | 340 | } |
| 307 | 341 | ||
| 308 | void intel_breadcrumbs_free(struct intel_breadcrumbs *b) | 342 | void intel_breadcrumbs_free(struct intel_breadcrumbs *b) |
| 309 | { | 343 | { |
| 344 | irq_work_sync(&b->irq_work); | ||
| 345 | GEM_BUG_ON(!list_empty(&b->signalers)); | ||
| 346 | GEM_BUG_ON(b->irq_armed); | ||
| 310 | kfree(b); | 347 | kfree(b); |
| 311 | } | 348 | } |
| 312 | 349 | ||
| @@ -327,7 +364,8 @@ static void insert_breadcrumb(struct i915_request *rq, · 14 unmodified lines | |||
| 327 | * its signal completion. | 364 | * its signal completion. |
| 328 | */ | 365 | */ |
| 329 | if (__request_completed(rq)) { | 366 | if (__request_completed(rq)) { |
| 330 | if (__signal_request(rq, &b->signaled_requests)) | 367 | if (__signal_request(rq) && |
| 368 | llist_add(&rq->signal_node, &b->signaled_requests)) | ||
| 331 | irq_work_queue(&b->irq_work); | 369 | irq_work_queue(&b->irq_work); |
| 332 | return; | 370 | return; |
| 333 | } | 371 | } |
| @@ -362,9 +400,12 @@ static void insert_breadcrumb(struct i915_request *rq, · 28 unmodified lines | |||
| 362 | GEM_BUG_ON(!check_signal_order(ce, rq)); | 400 | GEM_BUG_ON(!check_signal_order(ce, rq)); |
| 363 | set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); | 401 | set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); |
| 364 | 402 | ||
| 365 | /* Check after attaching to irq, interrupt may have already fired. */ | 403 | /* |
| 366 | if (__request_completed(rq)) | 404 | * Defer enabling the interrupt to after HW submission and recheck |
| 367 | irq_work_queue(&b->irq_work); | 405 | * the request as it may have completed and raised the interrupt as |
| 406 | * we were attaching it into the lists. | ||
| 407 | */ | ||
| 408 | irq_work_queue(&b->irq_work); | ||
| 368 | } | 409 | } |
| 369 | 410 | ||
| 370 | bool i915_request_enable_breadcrumb(struct i915_request *rq) | 411 | bool i915_request_enable_breadcrumb(struct i915_request *rq) |
| @@ -35,7 +35,7 @@ struct intel_breadcrumbs { · 34 unmodified lines | |||
| 35 | struct intel_engine_cs *irq_engine; | 35 | struct intel_engine_cs *irq_engine; |
| 36 | 36 | ||
| 37 | struct list_head signalers; | 37 | struct list_head signalers; |
| 38 | struct list_head signaled_requests; | 38 | struct llist_head signaled_requests; |
| 39 | 39 | ||
| 40 | struct irq_work irq_work; /* for use from inside irq_lock */ | 40 | struct irq_work irq_work; /* for use from inside irq_lock */ |
| 41 | 41 | ||
| @@ -182,6 +182,7 @@ · 181 unmodified lines | |||
| 182 | struct virtual_engine { | 182 | struct virtual_engine { |
| 183 | struct intel_engine_cs base; | 183 | struct intel_engine_cs base; |
| 184 | struct intel_context context; | 184 | struct intel_context context; |
| 185 | struct rcu_work rcu; | ||
| 185 | 186 | ||
| 186 | /* | 187 | /* |
| 187 | * We allow only a single request through the virtual engine at a time | 188 | * We allow only a single request through the virtual engine at a time |
| @@ -5425,44 +5426,90 @@ static struct list_head *virtual_queue(struct virtual_engine *ve) · 5237 unmodified lines | |||
| 5425 | return &ve->base.execlists.default_priolist.requests[0]; | 5426 | return &ve->base.execlists.default_priolist.requests[0]; |
| 5426 | } | 5427 | } |
| 5427 | 5428 | ||
| 5428 | static void virtual_context_destroy(struct kref *kref) | 5429 | static void rcu_virtual_context_destroy(struct work_struct *wrk) |
| 5429 | { | 5430 | { |
| 5430 | struct virtual_engine *ve = | 5431 | struct virtual_engine *ve = |
| 5431 | container_of(kref, typeof(*ve), context.ref); | 5432 | container_of(wrk, typeof(*ve), rcu.work); |
| 5432 | unsigned int n; | 5433 | unsigned int n; |
| 5433 | 5434 | ||
| 5434 | GEM_BUG_ON(!list_empty(virtual_queue(ve))); | ||
| 5435 | GEM_BUG_ON(ve->request); | ||
| 5436 | GEM_BUG_ON(ve->context.inflight); | 5435 | GEM_BUG_ON(ve->context.inflight); |
| 5437 | 5436 | ||
| 5437 | /* Preempt-to-busy may leave a stale request behind. */ | ||
| 5438 | if (unlikely(ve->request)) { | ||
| 5439 | struct i915_request *old; | ||
| 5440 | |||
| 5441 | spin_lock_irq(&ve->base.active.lock); | ||
| 5442 | |||
| 5443 | old = fetch_and_zero(&ve->request); | ||
| 5444 | if (old) { | ||
| 5445 | GEM_BUG_ON(!i915_request_completed(old)); | ||
| 5446 | __i915_request_submit(old); | ||
| 5447 | i915_request_put(old); | ||
| 5448 | } | ||
| 5449 | |||
| 5450 | spin_unlock_irq(&ve->base.active.lock); | ||
| 5451 | } | ||
| 5452 | |||
| 5453 | /* | ||
| 5454 | * Flush the tasklet in case it is still running on another core. | ||
| 5455 | * | ||
| 5456 | * This needs to be done before we remove ourselves from the siblings' | ||
| 5457 | * rbtrees as in the case it is running in parallel, it may reinsert | ||
| 5458 | * the rb_node into a sibling. | ||
| 5459 | */ | ||
| 5460 | tasklet_kill(&ve->base.execlists.tasklet); | ||
| 5461 | |||
| 5462 | /* Decouple ourselves from the siblings, no more access allowed. */ | ||
| 5438 | for (n = 0; n < ve->num_siblings; n++) { | 5463 | for (n = 0; n < ve->num_siblings; n++) { |
| 5439 | struct intel_engine_cs *sibling = ve->siblings[n]; | 5464 | struct intel_engine_cs *sibling = ve->siblings[n]; |
| 5440 | struct rb_node *node = &ve->nodes[sibling->id].rb; | 5465 | struct rb_node *node = &ve->nodes[sibling->id].rb; |
| 5441 | unsigned long flags; | ||
| 5442 | 5466 | ||
| 5443 | if (RB_EMPTY_NODE(node)) | 5467 | if (RB_EMPTY_NODE(node)) |
| 5444 | continue; | 5468 | continue; |
| 5445 | 5469 | ||
| 5446 | spin_lock_irqsave(&sibling->active.lock, flags); | 5470 | spin_lock_irq(&sibling->active.lock); |
| 5447 | 5471 | ||
| 5448 | /* Detachment is lazily performed in the execlists tasklet */ | 5472 | /* Detachment is lazily performed in the execlists tasklet */ |
| 5449 | if (!RB_EMPTY_NODE(node)) | 5473 | if (!RB_EMPTY_NODE(node)) |
| 5450 | rb_erase_cached(node, &sibling->execlists.virtual); | 5474 | rb_erase_cached(node, &sibling->execlists.virtual); |
| 5451 | 5475 | ||
| 5452 | spin_unlock_irqrestore(&sibling->active.lock, flags); | 5476 | spin_unlock_irq(&sibling->active.lock); |
| 5453 | } | 5477 | } |
| 5454 | GEM_BUG_ON(__tasklet_is_scheduled(&ve->base.execlists.tasklet)); | 5478 | GEM_BUG_ON(__tasklet_is_scheduled(&ve->base.execlists.tasklet)); |
| 5479 | GEM_BUG_ON(!list_empty(virtual_queue(ve))); | ||
| 5455 | 5480 | ||
| 5456 | if (ve->context.state) | 5481 | if (ve->context.state) |
| 5457 | __execlists_context_fini(&ve->context); | 5482 | __execlists_context_fini(&ve->context); |
| 5458 | intel_context_fini(&ve->context); | 5483 | intel_context_fini(&ve->context); |
| 5459 | 5484 | ||
| 5485 | intel_breadcrumbs_free(ve->base.breadcrumbs); | ||
| 5460 | intel_engine_free_request_pool(&ve->base); | 5486 | intel_engine_free_request_pool(&ve->base); |
| 5461 | 5487 | ||
| 5462 | kfree(ve->bonds); | 5488 | kfree(ve->bonds); |
| 5463 | kfree(ve); | 5489 | kfree(ve); |
| 5464 | } | 5490 | } |
| 5465 | 5491 | ||
| 5492 | static void virtual_context_destroy(struct kref *kref) | ||
| 5493 | { | ||
| 5494 | struct virtual_engine *ve = | ||
| 5495 | container_of(kref, typeof(*ve), context.ref); | ||
| 5496 | |||
| 5497 | GEM_BUG_ON(!list_empty(&ve->context.signals)); | ||
| 5498 | |||
| 5499 | /* | ||
| 5500 | * When destroying the virtual engine, we have to be aware that | ||
| 5501 | * it may still be in use from an hardirq/softirq context causing | ||
| 5502 | * the resubmission of a completed request (background completion | ||
| 5503 | * due to preempt-to-busy). Before we can free the engine, we need | ||
| 5504 | * to flush the submission code and tasklets that are still potentially | ||
| 5505 | * accessing the engine. Flushing the tasklets requires process context, | ||
| 5506 | * and since we can guard the resubmit onto the engine with an RCU read | ||
| 5507 | * lock, we can delegate the free of the engine to an RCU worker. | ||
| 5508 | */ | ||
| 5509 | INIT_RCU_WORK(&ve->rcu, rcu_virtual_context_destroy); | ||
| 5510 | queue_rcu_work(system_wq, &ve->rcu); | ||
| 5511 | } | ||
| 5512 | |||
| 5466 | static void virtual_engine_initial_hint(struct virtual_engine *ve) | 5513 | static void virtual_engine_initial_hint(struct virtual_engine *ve) |
| 5467 | { | 5514 | { |
| 5468 | int swp; | 5515 | int swp; |
| @@ -243,8 +243,9 @@ static const struct drm_i915_mocs_entry tgl_mocs_table[] = { · 242 unmodified lines | |||
| 243 | * only, __init_mocs_table() take care to program unused index with | 243 | * only, __init_mocs_table() take care to program unused index with |
| 244 | * this entry. | 244 | * this entry. |
| 245 | */ | 245 | */ |
| 246 | MOCS_ENTRY(1, LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), | 246 | MOCS_ENTRY(I915_MOCS_PTE, |
| 247 | L3_3_WB), | 247 | LE_0_PAGETABLE | LE_TC_0_PAGETABLE, |
| 248 | L3_1_UC), | ||
| 248 | GEN11_MOCS_ENTRIES, | 249 | GEN11_MOCS_ENTRIES, |
| 249 | 250 | ||
| 250 | /* Implicitly enable L1 - HDC:L1 + L3 + LLC */ | 251 | /* Implicitly enable L1 - HDC:L1 + L3 + LLC */ |
| @@ -56,9 +56,12 @@ static inline void set(struct intel_uncore *uncore, i915_reg_t reg, u32 val) · 55 unmodified lines | |||
| 56 | 56 | ||
| 57 | static void gen11_rc6_enable(struct intel_rc6 *rc6) | 57 | static void gen11_rc6_enable(struct intel_rc6 *rc6) |
| 58 | { | 58 | { |
| 59 | struct intel_uncore *uncore = rc6_to_uncore(rc6); | 59 | struct intel_gt *gt = rc6_to_gt(rc6); |
| 60 | struct intel_uncore *uncore = gt->uncore; | ||
| 60 | struct intel_engine_cs *engine; | 61 | struct intel_engine_cs *engine; |
| 61 | enum intel_engine_id id; | 62 | enum intel_engine_id id; |
| 63 | u32 pg_enable; | ||
| 64 | int i; | ||
| 62 | 65 | ||
| 63 | /* 2b: Program RC6 thresholds.*/ | 66 | /* 2b: Program RC6 thresholds.*/ |
| 64 | set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85); | 67 | set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85); |
| @@ -102,10 +105,19 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6) · 37 unmodified lines | |||
| 102 | GEN6_RC_CTL_RC6_ENABLE | | 105 | GEN6_RC_CTL_RC6_ENABLE | |
| 103 | GEN6_RC_CTL_EI_MODE(1); | 106 | GEN6_RC_CTL_EI_MODE(1); |
| 104 | 107 | ||
| 105 | set(uncore, GEN9_PG_ENABLE, | 108 | pg_enable = |
| 106 | GEN9_RENDER_PG_ENABLE | | 109 | GEN9_RENDER_PG_ENABLE | |
| 107 | GEN9_MEDIA_PG_ENABLE | | 110 | GEN9_MEDIA_PG_ENABLE | |
| 108 | GEN11_MEDIA_SAMPLER_PG_ENABLE); | 111 | GEN11_MEDIA_SAMPLER_PG_ENABLE; |
| 112 | |||
| 113 | if (INTEL_GEN(gt->i915) >= 12) { | ||
| 114 | for (i = 0; i < I915_MAX_VCS; i++) | ||
| 115 | if (HAS_ENGINE(gt, _VCS(i))) | ||
| 116 | pg_enable |= (VDN_HCP_POWERGATE_ENABLE(i) | | ||
| 117 | VDN_MFX_POWERGATE_ENABLE(i)); | ||
| 118 | } | ||
| 119 | |||
| 120 | set(uncore, GEN9_PG_ENABLE, pg_enable); | ||
| 109 | } | 121 | } |
| 110 | 122 | ||
| 111 | static void gen9_rc6_enable(struct intel_rc6 *rc6) | 123 | static void gen9_rc6_enable(struct intel_rc6 *rc6) |
| @@ -131,8 +131,10 @@ static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) · 130 unmodified lines | |||
| 131 | return; | 131 | return; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (wal->list) | 134 | if (wal->list) { |
| 135 | memcpy(list, wal->list, sizeof(*wa) * wal->count); | 135 | memcpy(list, wal->list, sizeof(*wa) * wal->count); |
| 136 | kfree(wal->list); | ||
| 137 | } | ||
| 136 | 138 | ||
| 137 | wal->list = list; | 139 | wal->list = list; |
| 138 | } | 140 | } |
| @@ -164,7 +164,7 @@ static unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = { · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | /* let the virtual display supports DP1.2 */ | 165 | /* let the virtual display supports DP1.2 */ |
| 166 | static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = { | 166 | static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = { |
| 167 | 0x12, 0x014, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 167 | 0x12, 0x014, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | static void emulate_monitor_status_change(struct intel_vgpu *vgpu) | 170 | static void emulate_monitor_status_change(struct intel_vgpu *vgpu) |
| @@ -255,7 +255,7 @@ struct intel_gvt_mmio { · 254 unmodified lines | |||
| 255 | #define F_CMD_ACCESS (1 << 3) | 255 | #define F_CMD_ACCESS (1 << 3) |
| 256 | /* This reg has been accessed by a VM */ | 256 | /* This reg has been accessed by a VM */ |
| 257 | #define F_ACCESSED (1 << 4) | 257 | #define F_ACCESSED (1 << 4) |
| 258 | /* This reg has been accessed through GPU commands */ | 258 | /* This reg could be accessed by unaligned address */ |
| 259 | #define F_UNALIGN (1 << 6) | 259 | #define F_UNALIGN (1 << 6) |
| 260 | /* This reg is in GVT's mmio save-restor list and in hardware | 260 | /* This reg is in GVT's mmio save-restor list and in hardware |
| 261 | * logical context image | 261 | * logical context image |
| @@ -829,8 +829,10 @@ static int intel_vgpu_open(struct mdev_device *mdev) · 828 unmodified lines | |||
| 829 | /* Take a module reference as mdev core doesn't take | 829 | /* Take a module reference as mdev core doesn't take |
| 830 | * a reference for vendor driver. | 830 | * a reference for vendor driver. |
| 831 | */ | 831 | */ |
| 832 | if (!try_module_get(THIS_MODULE)) | 832 | if (!try_module_get(THIS_MODULE)) { |
| 833 | ret = -ENODEV; | ||
| 833 | goto undo_group; | 834 | goto undo_group; |
| 835 | } | ||
| 834 | 836 | ||
| 835 | ret = kvmgt_guest_init(mdev); | 837 | ret = kvmgt_guest_init(mdev); |
| 836 | if (ret) | 838 | if (ret) |
| @@ -439,7 +439,8 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, · 438 unmodified lines | |||
| 439 | 439 | ||
| 440 | if (IS_BROADWELL(dev_priv)) | 440 | if (IS_BROADWELL(dev_priv)) |
| 441 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); | 441 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); |
| 442 | else | 442 | /* FixMe: Re-enable APL/BXT once vfio_edid enabled */ |
| 443 | else if (!IS_BROXTON(dev_priv)) | ||
| 443 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); | 444 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); |
| 444 | if (ret) | 445 | if (ret) |
| 445 | goto out_clean_sched_policy; | 446 | goto out_clean_sched_policy; |
| @@ -909,8 +909,13 @@ static int gen8_oa_read(struct i915_perf_stream *stream, · 908 unmodified lines | |||
| 909 | DRM_I915_PERF_RECORD_OA_REPORT_LOST); | 909 | DRM_I915_PERF_RECORD_OA_REPORT_LOST); |
| 910 | if (ret) | 910 | if (ret) |
| 911 | return ret; | 911 | return ret; |
| 912 | intel_uncore_write(uncore, oastatus_reg, | 912 | |
| 913 | oastatus & ~GEN8_OASTATUS_REPORT_LOST); | 913 | intel_uncore_rmw(uncore, oastatus_reg, |
| 914 | GEN8_OASTATUS_COUNTER_OVERFLOW | | ||
| 915 | GEN8_OASTATUS_REPORT_LOST, | ||
| 916 | IS_GEN_RANGE(uncore->i915, 8, 10) ? | ||
| 917 | (GEN8_OASTATUS_HEAD_POINTER_WRAP | | ||
| 918 | GEN8_OASTATUS_TAIL_POINTER_WRAP) : 0); | ||
| 914 | } | 919 | } |
| 915 | 920 | ||
| 916 | return gen8_append_oa_reports(stream, buf, count, offset); | 921 | return gen8_append_oa_reports(stream, buf, count, offset); |
| @@ -676,6 +676,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 675 unmodified lines | |||
| 676 | #define GEN7_OASTATUS2_MEM_SELECT_GGTT (1 << 0) /* 0: PPGTT, 1: GGTT */ | 676 | #define GEN7_OASTATUS2_MEM_SELECT_GGTT (1 << 0) /* 0: PPGTT, 1: GGTT */ |
| 677 | 677 | ||
| 678 | #define GEN8_OASTATUS _MMIO(0x2b08) | 678 | #define GEN8_OASTATUS _MMIO(0x2b08) |
| 679 | #define GEN8_OASTATUS_TAIL_POINTER_WRAP (1 << 17) | ||
| 680 | #define GEN8_OASTATUS_HEAD_POINTER_WRAP (1 << 16) | ||
| 679 | #define GEN8_OASTATUS_OVERRUN_STATUS (1 << 3) | 681 | #define GEN8_OASTATUS_OVERRUN_STATUS (1 << 3) |
| 680 | #define GEN8_OASTATUS_COUNTER_OVERFLOW (1 << 2) | 682 | #define GEN8_OASTATUS_COUNTER_OVERFLOW (1 << 2) |
| 681 | #define GEN8_OASTATUS_OABUFFER_OVERFLOW (1 << 1) | 683 | #define GEN8_OASTATUS_OABUFFER_OVERFLOW (1 << 1) |
| @@ -8971,10 +8973,6 @@ enum { · 8289 unmodified lines | |||
| 8971 | #define GEN9_PWRGT_MEDIA_STATUS_MASK (1 << 0) | 8973 | #define GEN9_PWRGT_MEDIA_STATUS_MASK (1 << 0) |
| 8972 | #define GEN9_PWRGT_RENDER_STATUS_MASK (1 << 1) | 8974 | #define GEN9_PWRGT_RENDER_STATUS_MASK (1 << 1) |
| 8973 | 8975 | ||
| 8974 | #define POWERGATE_ENABLE _MMIO(0xa210) | ||
| 8975 | #define VDN_HCP_POWERGATE_ENABLE(n) BIT(((n) * 2) + 3) | ||
| 8976 | #define VDN_MFX_POWERGATE_ENABLE(n) BIT(((n) * 2) + 4) | ||
| 8977 | |||
| 8978 | #define GTFIFODBG _MMIO(0x120000) | 8976 | #define GTFIFODBG _MMIO(0x120000) |
| 8979 | #define GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV (0x1f << 20) | 8977 | #define GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV (0x1f << 20) |
| 8980 | #define GT_FIFO_FREE_ENTRIES_CHV (0x7f << 13) | 8978 | #define GT_FIFO_FREE_ENTRIES_CHV (0x7f << 13) |
| @@ -9114,9 +9112,11 @@ enum { · 133 unmodified lines | |||
| 9114 | #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) | 9112 | #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) |
| 9115 | #define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8) | 9113 | #define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8) |
| 9116 | #define GEN9_PG_ENABLE _MMIO(0xA210) | 9114 | #define GEN9_PG_ENABLE _MMIO(0xA210) |
| 9117 | #define GEN9_RENDER_PG_ENABLE REG_BIT(0) | 9115 | #define GEN9_RENDER_PG_ENABLE REG_BIT(0) |
| 9118 | #define GEN9_MEDIA_PG_ENABLE REG_BIT(1) | 9116 | #define GEN9_MEDIA_PG_ENABLE REG_BIT(1) |
| 9119 | #define GEN11_MEDIA_SAMPLER_PG_ENABLE REG_BIT(2) | 9117 | #define GEN11_MEDIA_SAMPLER_PG_ENABLE REG_BIT(2) |
| 9118 | #define VDN_HCP_POWERGATE_ENABLE(n) REG_BIT(3 + 2 * (n)) | ||
| 9119 | #define VDN_MFX_POWERGATE_ENABLE(n) REG_BIT(4 + 2 * (n)) | ||
| 9120 | #define GEN8_PUSHBUS_CONTROL _MMIO(0xA248) | 9120 | #define GEN8_PUSHBUS_CONTROL _MMIO(0xA248) |
| 9121 | #define GEN8_PUSHBUS_ENABLE _MMIO(0xA250) | 9121 | #define GEN8_PUSHBUS_ENABLE _MMIO(0xA250) |
| 9122 | #define GEN8_PUSHBUS_SHIFT _MMIO(0xA25C) | 9122 | #define GEN8_PUSHBUS_SHIFT _MMIO(0xA25C) |
| @@ -176,7 +176,11 @@ struct i915_request { · 175 unmodified lines | |||
| 176 | struct intel_context *context; | 176 | struct intel_context *context; |
| 177 | struct intel_ring *ring; | 177 | struct intel_ring *ring; |
| 178 | struct intel_timeline __rcu *timeline; | 178 | struct intel_timeline __rcu *timeline; |
| 179 | struct list_head signal_link; | 179 | |
| 180 | union { | ||
| 181 | struct list_head signal_link; | ||
| 182 | struct llist_node signal_node; | ||
| 183 | }; | ||
| 180 | 184 | ||
| 181 | /* | 185 | /* |
| 182 | * The rcu epoch of when this request was allocated. Used to judiciously | 186 | * The rcu epoch of when this request was allocated. Used to judiciously |
| @@ -7118,23 +7118,10 @@ static void icl_init_clock_gating(struct drm_i915_private *dev_priv) · 7117 unmodified lines | |||
| 7118 | 7118 | ||
| 7119 | static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) | 7119 | static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7120 | { | 7120 | { |
| 7121 | u32 vd_pg_enable = 0; | ||
| 7122 | unsigned int i; | ||
| 7123 | |||
| 7124 | /* Wa_1409120013:tgl */ | 7121 | /* Wa_1409120013:tgl */ |
| 7125 | I915_WRITE(ILK_DPFC_CHICKEN, | 7122 | I915_WRITE(ILK_DPFC_CHICKEN, |
| 7126 | ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); | 7123 | ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); |
| 7127 | 7124 | ||
| 7128 | /* This is not a WA. Enable VD HCP & MFX_ENC powergate */ | ||
| 7129 | for (i = 0; i < I915_MAX_VCS; i++) { | ||
| 7130 | if (HAS_ENGINE(&dev_priv->gt, _VCS(i))) | ||
| 7131 | vd_pg_enable |= VDN_HCP_POWERGATE_ENABLE(i) | | ||
| 7132 | VDN_MFX_POWERGATE_ENABLE(i); | ||
| 7133 | } | ||
| 7134 | |||
| 7135 | I915_WRITE(POWERGATE_ENABLE, | ||
| 7136 | I915_READ(POWERGATE_ENABLE) | vd_pg_enable); | ||
| 7137 | |||
| 7138 | /* Wa_1409825376:tgl (pre-prod)*/ | 7125 | /* Wa_1409825376:tgl (pre-prod)*/ |
| 7139 | if (IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B1)) | 7126 | if (IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B1)) |
| 7140 | I915_WRITE(GEN9_CLKGATE_DIS_3, I915_READ(GEN9_CLKGATE_DIS_3) | | 7127 | I915_WRITE(GEN9_CLKGATE_DIS_3, I915_READ(GEN9_CLKGATE_DIS_3) | |
| @@ -2293,8 +2293,10 @@ static int perf_request_latency(void *arg) · 2292 unmodified lines | |||
| 2293 | struct intel_context *ce; | 2293 | struct intel_context *ce; |
| 2294 | 2294 | ||
| 2295 | ce = intel_context_create(engine); | 2295 | ce = intel_context_create(engine); |
| 2296 | if (IS_ERR(ce)) | 2296 | if (IS_ERR(ce)) { |
| 2297 | err = PTR_ERR(ce); | ||
| 2297 | goto out; | 2298 | goto out; |
| 2299 | } | ||
| 2298 | 2300 | ||
| 2299 | err = intel_context_pin(ce); | 2301 | err = intel_context_pin(ce); |
| 2300 | if (err) { | 2302 | if (err) { |
| @@ -2467,8 +2469,10 @@ static int perf_series_engines(void *arg) · 166 unmodified lines | |||
| 2467 | struct intel_context *ce; | 2469 | struct intel_context *ce; |
| 2468 | 2470 | ||
| 2469 | ce = intel_context_create(engine); | 2471 | ce = intel_context_create(engine); |
| 2470 | if (IS_ERR(ce)) | 2472 | if (IS_ERR(ce)) { |
| 2473 | err = PTR_ERR(ce); | ||
| 2471 | goto out; | 2474 | goto out; |
| 2475 | } | ||
| 2472 | 2476 | ||
| 2473 | err = intel_context_pin(ce); | 2477 | err = intel_context_pin(ce); |
| 2474 | if (err) { | 2478 | if (err) { |
| @@ -522,15 +522,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, · 521 unmodified lines | |||
| 522 | return 0; | 522 | return 0; |
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder) | ||
| 526 | { | ||
| 527 | drm_encoder_cleanup(encoder); | ||
| 528 | } | ||
| 529 | |||
| 530 | static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { | ||
| 531 | .destroy = mtk_dpi_encoder_destroy, | ||
| 532 | }; | ||
| 533 | |||
| 534 | static int mtk_dpi_bridge_attach(struct drm_bridge *bridge, | 525 | static int mtk_dpi_bridge_attach(struct drm_bridge *bridge, |
| 535 | enum drm_bridge_attach_flags flags) | 526 | enum drm_bridge_attach_flags flags) |
| 536 | { | 527 | { |
| @@ -444,7 +444,10 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) · 443 unmodified lines | |||
| 444 | u32 horizontal_sync_active_byte; | 444 | u32 horizontal_sync_active_byte; |
| 445 | u32 horizontal_backporch_byte; | 445 | u32 horizontal_backporch_byte; |
| 446 | u32 horizontal_frontporch_byte; | 446 | u32 horizontal_frontporch_byte; |
| 447 | u32 horizontal_front_back_byte; | ||
| 448 | u32 data_phy_cycles_byte; | ||
| 447 | u32 dsi_tmp_buf_bpp, data_phy_cycles; | 449 | u32 dsi_tmp_buf_bpp, data_phy_cycles; |
| 450 | u32 delta; | ||
| 448 | struct mtk_phy_timing *timing = &dsi->phy_timing; | 451 | struct mtk_phy_timing *timing = &dsi->phy_timing; |
| 449 | 452 | ||
| 450 | struct videomode *vm = &dsi->vm; | 453 | struct videomode *vm = &dsi->vm; |
| @@ -466,50 +469,30 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) · 15 unmodified lines | |||
| 466 | horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10); | 469 | horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10); |
| 467 | 470 | ||
| 468 | if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) | 471 | if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
| 469 | horizontal_backporch_byte = vm->hback_porch * dsi_tmp_buf_bpp; | 472 | horizontal_backporch_byte = vm->hback_porch * dsi_tmp_buf_bpp - 10; |
| 470 | else | 473 | else |
| 471 | horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) * | 474 | horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) * |
| 472 | dsi_tmp_buf_bpp; | 475 | dsi_tmp_buf_bpp - 10; |
| 473 | 476 | ||
| 474 | data_phy_cycles = timing->lpx + timing->da_hs_prepare + | 477 | data_phy_cycles = timing->lpx + timing->da_hs_prepare + |
| 475 | timing->da_hs_zero + timing->da_hs_exit; | 478 | timing->da_hs_zero + timing->da_hs_exit + 3; |
| 476 | 479 | ||
| 477 | if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { | 480 | delta = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST ? 18 : 12; |
| 478 | if ((vm->hfront_porch + vm->hback_porch) * dsi_tmp_buf_bpp > | 481 | |
| 479 | data_phy_cycles * dsi->lanes + 18) { | 482 | horizontal_frontporch_byte = vm->hfront_porch * dsi_tmp_buf_bpp; |
| 480 | horizontal_frontporch_byte = | 483 | horizontal_front_back_byte = horizontal_frontporch_byte + horizontal_backporch_byte; |
| 481 | vm->hfront_porch * dsi_tmp_buf_bpp - | 484 | data_phy_cycles_byte = data_phy_cycles * dsi->lanes + delta; |
| 482 | (data_phy_cycles * dsi->lanes + 18) * | 485 | |
| 483 | vm->hfront_porch / | 486 | if (horizontal_front_back_byte > data_phy_cycles_byte) { |
| 484 | (vm->hfront_porch + vm->hback_porch); | 487 | horizontal_frontporch_byte -= data_phy_cycles_byte * |
| 485 | 488 | horizontal_frontporch_byte / | |
| 486 | horizontal_backporch_byte = | 489 | horizontal_front_back_byte; |
| 487 | horizontal_backporch_byte - | 490 | |
| 488 | (data_phy_cycles * dsi->lanes + 18) * | 491 | horizontal_backporch_byte -= data_phy_cycles_byte * |
| 489 | vm->hback_porch / | 492 | horizontal_backporch_byte / |
| 490 | (vm->hfront_porch + vm->hback_porch); | 493 | horizontal_front_back_byte; |
| 491 | } else { | ||
| 492 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); | ||
| 493 | horizontal_frontporch_byte = vm->hfront_porch * | ||
| 494 | dsi_tmp_buf_bpp; | ||
| 495 | } | ||
| 496 | } else { | 494 | } else { |
| 497 | if ((vm->hfront_porch + vm->hback_porch) * dsi_tmp_buf_bpp > | 495 | DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n"); |
| 498 | data_phy_cycles * dsi->lanes + 12) { | ||
| 499 | horizontal_frontporch_byte = | ||
| 500 | vm->hfront_porch * dsi_tmp_buf_bpp - | ||
| 501 | (data_phy_cycles * dsi->lanes + 12) * | ||
| 502 | vm->hfront_porch / | ||
| 503 | (vm->hfront_porch + vm->hback_porch); | ||
| 504 | horizontal_backporch_byte = horizontal_backporch_byte - | ||
| 505 | (data_phy_cycles * dsi->lanes + 12) * | ||
| 506 | vm->hback_porch / | ||
| 507 | (vm->hfront_porch + vm->hback_porch); | ||
| 508 | } else { | ||
| 509 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); | ||
| 510 | horizontal_frontporch_byte = vm->hfront_porch * | ||
| 511 | dsi_tmp_buf_bpp; | ||
| 512 | } | ||
| 513 | } | 496 | } |
| 514 | 497 | ||
| 515 | writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC); | 498 | writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC); |
| @@ -558,8 +558,10 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, · 557 unmodified lines | |||
| 558 | NV_PRINTK(err, cli, "validating bo list\n"); | 558 | NV_PRINTK(err, cli, "validating bo list\n"); |
| 559 | validate_fini(op, chan, NULL, NULL); | 559 | validate_fini(op, chan, NULL, NULL); |
| 560 | return ret; | 560 | return ret; |
| 561 | } else if (ret > 0) { | ||
| 562 | *apply_relocs = true; | ||
| 561 | } | 563 | } |
| 562 | *apply_relocs = ret; | 564 | |
| 563 | return 0; | 565 | return 0; |
| 564 | } | 566 | } |
| 565 | 567 | ||
| @@ -662,7 +664,6 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, · 96 unmodified lines | |||
| 662 | nouveau_bo_wr32(nvbo, r->reloc_bo_offset >> 2, data); | 664 | nouveau_bo_wr32(nvbo, r->reloc_bo_offset >> 2, data); |
| 663 | } | 665 | } |
| 664 | 666 | ||
| 665 | u_free(reloc); | ||
| 666 | return ret; | 667 | return ret; |
| 667 | } | 668 | } |
| 668 | 669 | ||
| @@ -872,9 +873,10 @@ out: · 203 unmodified lines | |||
| 872 | break; | 873 | break; |
| 873 | } | 874 | } |
| 874 | } | 875 | } |
| 875 | u_free(reloc); | ||
| 876 | } | 876 | } |
| 877 | out_prevalid: | 877 | out_prevalid: |
| 878 | if (!IS_ERR(reloc)) | ||
| 879 | u_free(reloc); | ||
| 878 | u_free(bo); | 880 | u_free(bo); |
| 879 | u_free(push); | 881 | u_free(push); |
| 880 | 882 | ||
| @@ -814,9 +814,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, · 813 unmodified lines | |||
| 814 | * | 814 | * |
| 815 | * XXX(hch): this has no business in a driver and needs to move | 815 | * XXX(hch): this has no business in a driver and needs to move |
| 816 | * to the device tree. | 816 | * to the device tree. |
| 817 | * | ||
| 818 | * If we have two subsequent calls to dma_direct_set_offset | ||
| 819 | * returns -EINVAL. Unfortunately, this happens when we have two | ||
| 820 | * backends in the system, and will result in the driver | ||
| 821 | * reporting an error while it has been setup properly before. | ||
| 822 | * Ignore EINVAL, but it should really be removed eventually. | ||
| 817 | */ | 823 | */ |
| 818 | ret = dma_direct_set_offset(drm->dev, PHYS_OFFSET, 0, SZ_4G); | 824 | ret = dma_direct_set_offset(drm->dev, PHYS_OFFSET, 0, SZ_4G); |
| 819 | if (ret) | 825 | if (ret && ret != -EINVAL) |
| 820 | return ret; | 826 | return ret; |
| 821 | } | 827 | } |
| 822 | 828 | ||
| @@ -208,6 +208,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, · 207 unmodified lines | |||
| 208 | phy_node = of_parse_phandle(dev->of_node, "phys", 0); | 208 | phy_node = of_parse_phandle(dev->of_node, "phys", 0); |
| 209 | if (!phy_node) { | 209 | if (!phy_node) { |
| 210 | dev_err(dev, "Can't found PHY phandle\n"); | 210 | dev_err(dev, "Can't found PHY phandle\n"); |
| 211 | ret = -EINVAL; | ||
| 211 | goto err_disable_clk_tmds; | 212 | goto err_disable_clk_tmds; |
| 212 | } | 213 | } |
| 213 | 214 | ||
| @@ -219,6 +219,7 @@ struct vc4_dev { · 218 unmodified lines | |||
| 219 | 219 | ||
| 220 | struct drm_modeset_lock ctm_state_lock; | 220 | struct drm_modeset_lock ctm_state_lock; |
| 221 | struct drm_private_obj ctm_manager; | 221 | struct drm_private_obj ctm_manager; |
| 222 | struct drm_private_obj hvs_channels; | ||
| 222 | struct drm_private_obj load_tracker; | 223 | struct drm_private_obj load_tracker; |
| 223 | 224 | ||
| 224 | /* List of vc4_debugfs_info_entry for adding to debugfs once | 225 | /* List of vc4_debugfs_info_entry for adding to debugfs once |
| @@ -531,6 +532,9 @@ struct vc4_crtc_state { · 306 unmodified lines | |||
| 531 | unsigned int top; | 532 | unsigned int top; |
| 532 | unsigned int bottom; | 533 | unsigned int bottom; |
| 533 | } margins; | 534 | } margins; |
| 535 | |||
| 536 | /* Transitional state below, only valid during atomic commits */ | ||
| 537 | bool update_muxing; | ||
| 534 | }; | 538 | }; |
| 535 | 539 | ||
| 536 | #define VC4_HVS_CHANNEL_DISABLED ((unsigned int)-1) | 540 | #define VC4_HVS_CHANNEL_DISABLED ((unsigned int)-1) |
| @@ -760,12 +760,54 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder) · 759 unmodified lines | |||
| 760 | { | 760 | { |
| 761 | } | 761 | } |
| 762 | 762 | ||
| 763 | #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL | ||
| 764 | #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL | ||
| 765 | |||
| 766 | static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, | ||
| 767 | struct drm_crtc_state *crtc_state, | ||
| 768 | struct drm_connector_state *conn_state) | ||
| 769 | { | ||
| 770 | struct drm_display_mode *mode = &crtc_state->adjusted_mode; | ||
| 771 | struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); | ||
| 772 | unsigned long long pixel_rate = mode->clock * 1000; | ||
| 773 | unsigned long long tmds_rate; | ||
| 774 | |||
| 775 | if (vc4_hdmi->variant->unsupported_odd_h_timings && | ||
| 776 | ((mode->hdisplay % 2) || (mode->hsync_start % 2) || | ||
| 777 | (mode->hsync_end % 2) || (mode->htotal % 2))) | ||
| 778 | return -EINVAL; | ||
| 779 | |||
| 780 | /* | ||
| 781 | * The 1440p@60 pixel rate is in the same range than the first | ||
| 782 | * WiFi channel (between 2.4GHz and 2.422GHz with 22MHz | ||
| 783 | * bandwidth). Slightly lower the frequency to bring it out of | ||
| 784 | * the WiFi range. | ||
| 785 | */ | ||
| 786 | tmds_rate = pixel_rate * 10; | ||
| 787 | if (vc4_hdmi->disable_wifi_frequencies && | ||
| 788 | (tmds_rate >= WIFI_2_4GHz_CH1_MIN_FREQ && | ||
| 789 | tmds_rate <= WIFI_2_4GHz_CH1_MAX_FREQ)) { | ||
| 790 | mode->clock = 238560; | ||
| 791 | pixel_rate = mode->clock * 1000; | ||
| 792 | } | ||
| 793 | |||
| 794 | if (pixel_rate > vc4_hdmi->variant->max_pixel_clock) | ||
| 795 | return -EINVAL; | ||
| 796 | |||
| 797 | return 0; | ||
| 798 | } | ||
| 799 | |||
| 763 | static enum drm_mode_status | 800 | static enum drm_mode_status |
| 764 | vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, | 801 | vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, |
| 765 | const struct drm_display_mode *mode) | 802 | const struct drm_display_mode *mode) |
| 766 | { | 803 | { |
| 767 | struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); | 804 | struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); |
| 768 | 805 | ||
| 806 | if (vc4_hdmi->variant->unsupported_odd_h_timings && | ||
| 807 | ((mode->hdisplay % 2) || (mode->hsync_start % 2) || | ||
| 808 | (mode->hsync_end % 2) || (mode->htotal % 2))) | ||
| 809 | return MODE_H_ILLEGAL; | ||
| 810 | |||
| 769 | if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock) | 811 | if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock) |
| 770 | return MODE_CLOCK_HIGH; | 812 | return MODE_CLOCK_HIGH; |
| 771 | 813 | ||
| @@ -773,6 +815,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, · 1 unmodified line | |||
| 773 | } | 815 | } |
| 774 | 816 | ||
| 775 | static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { | 817 | static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { |
| 818 | .atomic_check = vc4_hdmi_encoder_atomic_check, | ||
| 776 | .mode_valid = vc4_hdmi_encoder_mode_valid, | 819 | .mode_valid = vc4_hdmi_encoder_mode_valid, |
| 777 | .disable = vc4_hdmi_encoder_disable, | 820 | .disable = vc4_hdmi_encoder_disable, |
| 778 | .enable = vc4_hdmi_encoder_enable, | 821 | .enable = vc4_hdmi_encoder_enable, |
| @@ -1694,6 +1737,9 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) · 915 unmodified lines | |||
| 1694 | vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW; | 1737 | vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW; |
| 1695 | } | 1738 | } |
| 1696 | 1739 | ||
| 1740 | vc4_hdmi->disable_wifi_frequencies = | ||
| 1741 | of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence"); | ||
| 1742 | |||
| 1697 | pm_runtime_enable(dev); | 1743 | pm_runtime_enable(dev); |
| 1698 | 1744 | ||
| 1699 | drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); | 1745 | drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); |
| @@ -1817,6 +1863,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = { · 117 unmodified lines | |||
| 1817 | PHY_LANE_2, | 1863 | PHY_LANE_2, |
| 1818 | PHY_LANE_CK, | 1864 | PHY_LANE_CK, |
| 1819 | }, | 1865 | }, |
| 1866 | .unsupported_odd_h_timings = true, | ||
| 1820 | 1867 | ||
| 1821 | .init_resources = vc5_hdmi_init_resources, | 1868 | .init_resources = vc5_hdmi_init_resources, |
| 1822 | .csc_setup = vc5_hdmi_csc_setup, | 1869 | .csc_setup = vc5_hdmi_csc_setup, |
| @@ -1842,6 +1889,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { · 19 unmodified lines | |||
| 1842 | PHY_LANE_CK, | 1889 | PHY_LANE_CK, |
| 1843 | PHY_LANE_2, | 1890 | PHY_LANE_2, |
| 1844 | }, | 1891 | }, |
| 1892 | .unsupported_odd_h_timings = true, | ||
| 1845 | 1893 | ||
| 1846 | .init_resources = vc5_hdmi_init_resources, | 1894 | .init_resources = vc5_hdmi_init_resources, |
| 1847 | .csc_setup = vc5_hdmi_csc_setup, | 1895 | .csc_setup = vc5_hdmi_csc_setup, |
| @@ -62,6 +62,9 @@ struct vc4_hdmi_variant { · 61 unmodified lines | |||
| 62 | */ | 62 | */ |
| 63 | enum vc4_hdmi_phy_channel phy_lane_mapping[4]; | 63 | enum vc4_hdmi_phy_channel phy_lane_mapping[4]; |
| 64 | 64 | ||
| 65 | /* The BCM2711 cannot deal with odd horizontal pixel timings */ | ||
| 66 | bool unsupported_odd_h_timings; | ||
| 67 | |||
| 65 | /* Callback to get the resources (memory region, interrupts, | 68 | /* Callback to get the resources (memory region, interrupts, |
| 66 | * clocks, etc) for that variant. | 69 | * clocks, etc) for that variant. |
| 67 | */ | 70 | */ |
| @@ -139,6 +142,14 @@ struct vc4_hdmi { · 71 unmodified lines | |||
| 139 | int hpd_gpio; | 142 | int hpd_gpio; |
| 140 | bool hpd_active_low; | 143 | bool hpd_active_low; |
| 141 | 144 | ||
| 145 | /* | ||
| 146 | * On some systems (like the RPi4), some modes are in the same | ||
| 147 | * frequency range than the WiFi channels (1440p@60Hz for | ||
| 148 | * example). Should we take evasive actions because that system | ||
| 149 | * has a wifi adapter? | ||
| 150 | */ | ||
| 151 | bool disable_wifi_frequencies; | ||
| 152 | |||
| 142 | struct cec_adapter *cec_adap; | 153 | struct cec_adapter *cec_adap; |
| 143 | struct cec_msg cec_rx_msg; | 154 | struct cec_msg cec_rx_msg; |
| 144 | bool cec_tx_ok; | 155 | bool cec_tx_ok; |
| @@ -24,6 +24,8 @@ · 23 unmodified lines | |||
| 24 | #include "vc4_drv.h" | 24 | #include "vc4_drv.h" |
| 25 | #include "vc4_regs.h" | 25 | #include "vc4_regs.h" |
| 26 | 26 | ||
| 27 | #define HVS_NUM_CHANNELS 3 | ||
| 28 | |||
| 27 | struct vc4_ctm_state { | 29 | struct vc4_ctm_state { |
| 28 | struct drm_private_state base; | 30 | struct drm_private_state base; |
| 29 | struct drm_color_ctm *ctm; | 31 | struct drm_color_ctm *ctm; |
| @@ -35,6 +37,17 @@ static struct vc4_ctm_state *to_vc4_ctm_state(struct drm_private_state *priv) · 5 unmodified lines | |||
| 35 | return container_of(priv, struct vc4_ctm_state, base); | 37 | return container_of(priv, struct vc4_ctm_state, base); |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 40 | struct vc4_hvs_state { | ||
| 41 | struct drm_private_state base; | ||
| 42 | unsigned int unassigned_channels; | ||
| 43 | }; | ||
| 44 | |||
| 45 | static struct vc4_hvs_state * | ||
| 46 | to_vc4_hvs_state(struct drm_private_state *priv) | ||
| 47 | { | ||
| 48 | return container_of(priv, struct vc4_hvs_state, base); | ||
| 49 | } | ||
| 50 | |||
| 38 | struct vc4_load_tracker_state { | 51 | struct vc4_load_tracker_state { |
| 39 | struct drm_private_state base; | 52 | struct drm_private_state base; |
| 40 | u64 hvs_load; | 53 | u64 hvs_load; |
| @@ -113,7 +126,7 @@ static int vc4_ctm_obj_init(struct vc4_dev *vc4) · 72 unmodified lines | |||
| 113 | drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, &ctm_state->base, | 126 | drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, &ctm_state->base, |
| 114 | &vc4_ctm_state_funcs); | 127 | &vc4_ctm_state_funcs); |
| 115 | 128 | ||
| 116 | return drmm_add_action(&vc4->base, vc4_ctm_obj_fini, NULL); | 129 | return drmm_add_action_or_reset(&vc4->base, vc4_ctm_obj_fini, NULL); |
| 117 | } | 130 | } |
| 118 | 131 | ||
| 119 | /* Converts a DRM S31.32 value to the HW S0.9 format. */ | 132 | /* Converts a DRM S31.32 value to the HW S0.9 format. */ |
| @@ -169,6 +182,19 @@ vc4_ctm_commit(struct vc4_dev *vc4, struct drm_atomic_state *state) · 49 unmodified lines | |||
| 169 | VC4_SET_FIELD(ctm_state->fifo, SCALER_OLEDOFFS_DISPFIFO)); | 182 | VC4_SET_FIELD(ctm_state->fifo, SCALER_OLEDOFFS_DISPFIFO)); |
| 170 | } | 183 | } |
| 171 | 184 | ||
| 185 | static struct vc4_hvs_state * | ||
| 186 | vc4_hvs_get_global_state(struct drm_atomic_state *state) | ||
| 187 | { | ||
| 188 | struct vc4_dev *vc4 = to_vc4_dev(state->dev); | ||
| 189 | struct drm_private_state *priv_state; | ||
| 190 | |||
| 191 | priv_state = drm_atomic_get_private_obj_state(state, &vc4->hvs_channels); | ||
| 192 | if (IS_ERR(priv_state)) | ||
| 193 | return ERR_CAST(priv_state); | ||
| 194 | |||
| 195 | return to_vc4_hvs_state(priv_state); | ||
| 196 | } | ||
| 197 | |||
| 172 | static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4, | 198 | static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4, |
| 173 | struct drm_atomic_state *state) | 199 | struct drm_atomic_state *state) |
| 174 | { | 200 | { |
| @@ -213,10 +239,7 @@ static void vc5_hvs_pv_muxing_commit(struct vc4_dev *vc4, · 38 unmodified lines | |||
| 213 | { | 239 | { |
| 214 | struct drm_crtc_state *crtc_state; | 240 | struct drm_crtc_state *crtc_state; |
| 215 | struct drm_crtc *crtc; | 241 | struct drm_crtc *crtc; |
| 216 | unsigned char dsp2_mux = 0; | 242 | unsigned char mux; |
| 217 | unsigned char dsp3_mux = 3; | ||
| 218 | unsigned char dsp4_mux = 3; | ||
| 219 | unsigned char dsp5_mux = 3; | ||
| 220 | unsigned int i; | 243 | unsigned int i; |
| 221 | u32 reg; | 244 | u32 reg; |
| 222 | 245 | ||
| @@ -224,50 +247,59 @@ static void vc5_hvs_pv_muxing_commit(struct vc4_dev *vc4, · 1 unmodified line | |||
| 224 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); | 247 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); |
| 225 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); | 248 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
| 226 | 249 | ||
| 227 | if (!crtc_state->active) | 250 | if (!vc4_state->update_muxing) |
| 228 | continue; | 251 | continue; |
| 229 | 252 | ||
| 230 | switch (vc4_crtc->data->hvs_output) { | 253 | switch (vc4_crtc->data->hvs_output) { |
| 231 | case 2: | 254 | case 2: |
| 232 | dsp2_mux = (vc4_state->assigned_channel == 2) ? 0 : 1; | 255 | mux = (vc4_state->assigned_channel == 2) ? 0 : 1; |
| 256 | reg = HVS_READ(SCALER_DISPECTRL); | ||
| 257 | HVS_WRITE(SCALER_DISPECTRL, | ||
| 258 | (reg & ~SCALER_DISPECTRL_DSP2_MUX_MASK) | | ||
| 259 | VC4_SET_FIELD(mux, SCALER_DISPECTRL_DSP2_MUX)); | ||
| 233 | break; | 260 | break; |
| 234 | 261 | ||
| 235 | case 3: | 262 | case 3: |
| 236 | dsp3_mux = vc4_state->assigned_channel; | 263 | if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) |
| 264 | mux = 3; | ||
| 265 | else | ||
| 266 | mux = vc4_state->assigned_channel; | ||
| 267 | |||
| 268 | reg = HVS_READ(SCALER_DISPCTRL); | ||
| 269 | HVS_WRITE(SCALER_DISPCTRL, | ||
| 270 | (reg & ~SCALER_DISPCTRL_DSP3_MUX_MASK) | | ||
| 271 | VC4_SET_FIELD(mux, SCALER_DISPCTRL_DSP3_MUX)); | ||
| 237 | break; | 272 | break; |
| 238 | 273 | ||
| 239 | case 4: | 274 | case 4: |
| 240 | dsp4_mux = vc4_state->assigned_channel; | 275 | if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) |
| 276 | mux = 3; | ||
| 277 | else | ||
| 278 | mux = vc4_state->assigned_channel; | ||
| 279 | |||
| 280 | reg = HVS_READ(SCALER_DISPEOLN); | ||
| 281 | HVS_WRITE(SCALER_DISPEOLN, | ||
| 282 | (reg & ~SCALER_DISPEOLN_DSP4_MUX_MASK) | | ||
| 283 | VC4_SET_FIELD(mux, SCALER_DISPEOLN_DSP4_MUX)); | ||
| 284 | |||
| 241 | break; | 285 | break; |
| 242 | 286 | ||
| 243 | case 5: | 287 | case 5: |
| 244 | dsp5_mux = vc4_state->assigned_channel; | 288 | if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) |
| 289 | mux = 3; | ||
| 290 | else | ||
| 291 | mux = vc4_state->assigned_channel; | ||
| 292 | |||
| 293 | reg = HVS_READ(SCALER_DISPDITHER); | ||
| 294 | HVS_WRITE(SCALER_DISPDITHER, | ||
| 295 | (reg & ~SCALER_DISPDITHER_DSP5_MUX_MASK) | | ||
| 296 | VC4_SET_FIELD(mux, SCALER_DISPDITHER_DSP5_MUX)); | ||
| 245 | break; | 297 | break; |
| 246 | 298 | ||
| 247 | default: | 299 | default: |
| 248 | break; | 300 | break; |
| 249 | } | 301 | } |
| 250 | } | 302 | } |
| 251 | |||
| 252 | reg = HVS_READ(SCALER_DISPECTRL); | ||
| 253 | HVS_WRITE(SCALER_DISPECTRL, | ||
| 254 | (reg & ~SCALER_DISPECTRL_DSP2_MUX_MASK) | | ||
| 255 | VC4_SET_FIELD(dsp2_mux, SCALER_DISPECTRL_DSP2_MUX)); | ||
| 256 | |||
| 257 | reg = HVS_READ(SCALER_DISPCTRL); | ||
| 258 | HVS_WRITE(SCALER_DISPCTRL, | ||
| 259 | (reg & ~SCALER_DISPCTRL_DSP3_MUX_MASK) | | ||
| 260 | VC4_SET_FIELD(dsp3_mux, SCALER_DISPCTRL_DSP3_MUX)); | ||
| 261 | |||
| 262 | reg = HVS_READ(SCALER_DISPEOLN); | ||
| 263 | HVS_WRITE(SCALER_DISPEOLN, | ||
| 264 | (reg & ~SCALER_DISPEOLN_DSP4_MUX_MASK) | | ||
| 265 | VC4_SET_FIELD(dsp4_mux, SCALER_DISPEOLN_DSP4_MUX)); | ||
| 266 | |||
| 267 | reg = HVS_READ(SCALER_DISPDITHER); | ||
| 268 | HVS_WRITE(SCALER_DISPDITHER, | ||
| 269 | (reg & ~SCALER_DISPDITHER_DSP5_MUX_MASK) | | ||
| 270 | VC4_SET_FIELD(dsp5_mux, SCALER_DISPDITHER_DSP5_MUX)); | ||
| 271 | } | 303 | } |
| 272 | 304 | ||
| 273 | static void | 305 | static void |
| @@ -657,53 +689,123 @@ static int vc4_load_tracker_obj_init(struct vc4_dev *vc4) · 383 unmodified lines | |||
| 657 | &load_state->base, | 689 | &load_state->base, |
| 658 | &vc4_load_tracker_state_funcs); | 690 | &vc4_load_tracker_state_funcs); |
| 659 | 691 | ||
| 660 | return drmm_add_action(&vc4->base, vc4_load_tracker_obj_fini, NULL); | 692 | return drmm_add_action_or_reset(&vc4->base, vc4_load_tracker_obj_fini, NULL); |
| 661 | } | 693 | } |
| 662 | 694 | ||
| 663 | #define NUM_OUTPUTS 6 | 695 | static struct drm_private_state * |
| 664 | #define NUM_CHANNELS 3 | 696 | vc4_hvs_channels_duplicate_state(struct drm_private_obj *obj) |
| 697 | { | ||
| 698 | struct vc4_hvs_state *old_state = to_vc4_hvs_state(obj->state); | ||
| 699 | struct vc4_hvs_state *state; | ||
| 700 | |||
| 701 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
| 702 | if (!state) | ||
| 703 | return NULL; | ||
| 665 | 704 | ||
| 666 | static int | 705 | __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); |
| 667 | vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) | 706 | |
| 707 | state->unassigned_channels = old_state->unassigned_channels; | ||
| 708 | |||
| 709 | return &state->base; | ||
| 710 | } | ||
| 711 | |||
| 712 | static void vc4_hvs_channels_destroy_state(struct drm_private_obj *obj, | ||
| 713 | struct drm_private_state *state) | ||
| 668 | { | 714 | { |
| 669 | unsigned long unassigned_channels = GENMASK(NUM_CHANNELS - 1, 0); | 715 | struct vc4_hvs_state *hvs_state = to_vc4_hvs_state(state); |
| 670 | struct drm_crtc_state *old_crtc_state, *new_crtc_state; | ||
| 671 | struct drm_crtc *crtc; | ||
| 672 | int i, ret; | ||
| 673 | 716 | ||
| 674 | /* | 717 | kfree(hvs_state); |
| 675 | * Since the HVS FIFOs are shared across all the pixelvalves and | 718 | } |
| 676 | * the TXP (and thus all the CRTCs), we need to pull the current | ||
| 677 | * state of all the enabled CRTCs so that an update to a single | ||
| 678 | * CRTC still keeps the previous FIFOs enabled and assigned to | ||
| 679 | * the same CRTCs, instead of evaluating only the CRTC being | ||
| 680 | * modified. | ||
| 681 | */ | ||
| 682 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
| 683 | struct drm_crtc_state *crtc_state; | ||
| 684 | 719 | ||
| 685 | if (!crtc->state->enable) | 720 | static const struct drm_private_state_funcs vc4_hvs_state_funcs = { |
| 686 | continue; | 721 | .atomic_duplicate_state = vc4_hvs_channels_duplicate_state, |
| 722 | .atomic_destroy_state = vc4_hvs_channels_destroy_state, | ||
| 723 | }; | ||
| 687 | 724 | ||
| 688 | crtc_state = drm_atomic_get_crtc_state(state, crtc); | 725 | static void vc4_hvs_channels_obj_fini(struct drm_device *dev, void *unused) |
| 689 | if (IS_ERR(crtc_state)) | 726 | { |
| 690 | return PTR_ERR(crtc_state); | 727 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 691 | } | 728 | |
| 729 | drm_atomic_private_obj_fini(&vc4->hvs_channels); | ||
| 730 | } | ||
| 731 | |||
| 732 | static int vc4_hvs_channels_obj_init(struct vc4_dev *vc4) | ||
| 733 | { | ||
| 734 | struct vc4_hvs_state *state; | ||
| 735 | |||
| 736 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
| 737 | if (!state) | ||
| 738 | return -ENOMEM; | ||
| 739 | |||
| 740 | state->unassigned_channels = GENMASK(HVS_NUM_CHANNELS - 1, 0); | ||
| 741 | drm_atomic_private_obj_init(&vc4->base, &vc4->hvs_channels, | ||
| 742 | &state->base, | ||
| 743 | &vc4_hvs_state_funcs); | ||
| 744 | |||
| 745 | return drmm_add_action_or_reset(&vc4->base, vc4_hvs_channels_obj_fini, NULL); | ||
| 746 | } | ||
| 747 | |||
| 748 | /* | ||
| 749 | * The BCM2711 HVS has up to 7 outputs connected to the pixelvalves and | ||
| 750 | * the TXP (and therefore all the CRTCs found on that platform). | ||
| 751 | * | ||
| 752 | * The naive (and our initial) implementation would just iterate over | ||
| 753 | * all the active CRTCs, try to find a suitable FIFO, and then remove it | ||
| 754 | * from the pool of available FIFOs. However, there are a few corner | ||
| 755 | * cases that need to be considered: | ||
| 756 | * | ||
| 757 | * - When running in a dual-display setup (so with two CRTCs involved), | ||
| 758 | * we can update the state of a single CRTC (for example by changing | ||
| 759 | * its mode using xrandr under X11) without affecting the other. In | ||
| 760 | * this case, the other CRTC wouldn't be in the state at all, so we | ||
| 761 | * need to consider all the running CRTCs in the DRM device to assign | ||
| 762 | * a FIFO, not just the one in the state. | ||
| 763 | * | ||
| 764 | * - To fix the above, we can't use drm_atomic_get_crtc_state on all | ||
| 765 | * enabled CRTCs to pull their CRTC state into the global state, since | ||
| 766 | * a page flip would start considering their vblank to complete. Since | ||
| 767 | * we don't have a guarantee that they are actually active, that | ||
| 768 | * vblank might never happen, and shouldn't even be considered if we | ||
| 769 | * want to do a page flip on a single CRTC. That can be tested by | ||
| 770 | * doing a modetest -v first on HDMI1 and then on HDMI0. | ||
| 771 | * | ||
| 772 | * - Since we need the pixelvalve to be disabled and enabled back when | ||
| 773 | * the FIFO is changed, we should keep the FIFO assigned for as long | ||
| 774 | * as the CRTC is enabled, only considering it free again once that | ||
| 775 | * CRTC has been disabled. This can be tested by booting X11 on a | ||
| 776 | * single display, and changing the resolution down and then back up. | ||
| 777 | */ | ||
| 778 | static int vc4_pv_muxing_atomic_check(struct drm_device *dev, | ||
| 779 | struct drm_atomic_state *state) | ||
| 780 | { | ||
| 781 | struct vc4_hvs_state *hvs_new_state; | ||
| 782 | struct drm_crtc_state *old_crtc_state, *new_crtc_state; | ||
| 783 | struct drm_crtc *crtc; | ||
| 784 | unsigned int i; | ||
| 785 | |||
| 786 | hvs_new_state = vc4_hvs_get_global_state(state); | ||
| 787 | if (!hvs_new_state) | ||
| 788 | return -EINVAL; | ||
| 692 | 789 | ||
| 693 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | 790 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 791 | struct vc4_crtc_state *old_vc4_crtc_state = | ||
| 792 | to_vc4_crtc_state(old_crtc_state); | ||
| 694 | struct vc4_crtc_state *new_vc4_crtc_state = | 793 | struct vc4_crtc_state *new_vc4_crtc_state = |
| 695 | to_vc4_crtc_state(new_crtc_state); | 794 | to_vc4_crtc_state(new_crtc_state); |
| 696 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); | 795 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
| 697 | unsigned int matching_channels; | 796 | unsigned int matching_channels; |
| 698 | 797 | ||
| 699 | if (old_crtc_state->enable && !new_crtc_state->enable) | 798 | /* Nothing to do here, let's skip it */ |
| 700 | new_vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED; | 799 | if (old_crtc_state->enable == new_crtc_state->enable) |
| 701 | |||
| 702 | if (!new_crtc_state->enable) | ||
| 703 | continue; | 800 | continue; |
| 704 | 801 | ||
| 705 | if (new_vc4_crtc_state->assigned_channel != VC4_HVS_CHANNEL_DISABLED) { | 802 | /* Muxing will need to be modified, mark it as such */ |
| 706 | unassigned_channels &= ~BIT(new_vc4_crtc_state->assigned_channel); | 803 | new_vc4_crtc_state->update_muxing = true; |
| 804 | |||
| 805 | /* If we're disabling our CRTC, we put back our channel */ | ||
| 806 | if (!new_crtc_state->enable) { | ||
| 807 | hvs_new_state->unassigned_channels |= BIT(old_vc4_crtc_state->assigned_channel); | ||
| 808 | new_vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED; | ||
| 707 | continue; | 809 | continue; |
| 708 | } | 810 | } |
| 709 | 811 | ||
| @@ -731,17 +833,29 @@ vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) · 21 unmodified lines | |||
| 731 | * the future, we will need to have something smarter, | 833 | * the future, we will need to have something smarter, |
| 732 | * but it works so far. | 834 | * but it works so far. |
| 733 | */ | 835 | */ |
| 734 | matching_channels = unassigned_channels & vc4_crtc->data->hvs_available_channels; | 836 | matching_channels = hvs_new_state->unassigned_channels & vc4_crtc->data->hvs_available_channels; |
| 735 | if (matching_channels) { | 837 | if (matching_channels) { |
| 736 | unsigned int channel = ffs(matching_channels) - 1; | 838 | unsigned int channel = ffs(matching_channels) - 1; |
| 737 | 839 | ||
| 738 | new_vc4_crtc_state->assigned_channel = channel; | 840 | new_vc4_crtc_state->assigned_channel = channel; |
| 739 | unassigned_channels &= ~BIT(channel); | 841 | hvs_new_state->unassigned_channels &= ~BIT(channel); |
| 740 | } else { | 842 | } else { |
| 741 | return -EINVAL; | 843 | return -EINVAL; |
| 742 | } | 844 | } |
| 743 | } | 845 | } |
| 744 | 846 | ||
| 847 | return 0; | ||
| 848 | } | ||
| 849 | |||
| 850 | static int | ||
| 851 | vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) | ||
| 852 | { | ||
| 853 | int ret; | ||
| 854 | |||
| 855 | ret = vc4_pv_muxing_atomic_check(dev, state); | ||
| 856 | if (ret) | ||
| 857 | return ret; | ||
| 858 | |||
| 745 | ret = vc4_ctm_atomic_check(dev, state); | 859 | ret = vc4_ctm_atomic_check(dev, state); |
| 746 | if (ret < 0) | 860 | if (ret < 0) |
| 747 | return ret; | 861 | return ret; |
| @@ -808,6 +922,10 @@ int vc4_kms_load(struct drm_device *dev) · 60 unmodified lines | |||
| 808 | if (ret) | 922 | if (ret) |
| 809 | return ret; | 923 | return ret; |
| 810 | 924 | ||
| 925 | ret = vc4_hvs_channels_obj_init(vc4); | ||
| 926 | if (ret) | ||
| 927 | return ret; | ||
| 928 | |||
| 811 | drm_mode_config_reset(dev); | 929 | drm_mode_config_reset(dev); |
| 812 | 930 | ||
| 813 | drm_kms_helper_poll_init(dev); | 931 | drm_kms_helper_poll_init(dev); |
| @@ -23,19 +23,17 @@ · 22 unmodified lines | |||
| 23 | #define CP_2WHEEL_MOUSE_HACK 0x02 | 23 | #define CP_2WHEEL_MOUSE_HACK 0x02 |
| 24 | #define CP_2WHEEL_MOUSE_HACK_ON 0x04 | 24 | #define CP_2WHEEL_MOUSE_HACK_ON 0x04 |
| 25 | 25 | ||
| 26 | #define VA_INVAL_LOGICAL_BOUNDARY 0x08 | ||
| 27 | |||
| 26 | /* | 28 | /* |
| 27 | * Some USB barcode readers from cypress have usage min and usage max in | 29 | * Some USB barcode readers from cypress have usage min and usage max in |
| 28 | * the wrong order | 30 | * the wrong order |
| 29 | */ | 31 | */ |
| 30 | static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 32 | static __u8 *cp_rdesc_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 31 | unsigned int *rsize) | 33 | unsigned int *rsize) |
| 32 | { | 34 | { |
| 33 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | ||
| 34 | unsigned int i; | 35 | unsigned int i; |
| 35 | 36 | ||
| 36 | if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) | ||
| 37 | return rdesc; | ||
| 38 | |||
| 39 | if (*rsize < 4) | 37 | if (*rsize < 4) |
| 40 | return rdesc; | 38 | return rdesc; |
| 41 | 39 | ||
| @@ -48,6 +46,40 @@ static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, · 6 unmodified lines | |||
| 48 | return rdesc; | 46 | return rdesc; |
| 49 | } | 47 | } |
| 50 | 48 | ||
| 49 | static __u8 *va_logical_boundary_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 50 | unsigned int *rsize) | ||
| 51 | { | ||
| 52 | /* | ||
| 53 | * Varmilo VA104M (with VID Cypress and device ID 07B1) incorrectly | ||
| 54 | * reports Logical Minimum of its Consumer Control device as 572 | ||
| 55 | * (0x02 0x3c). Fix this by setting its Logical Minimum to zero. | ||
| 56 | */ | ||
| 57 | if (*rsize == 25 && | ||
| 58 | rdesc[0] == 0x05 && rdesc[1] == 0x0c && | ||
| 59 | rdesc[2] == 0x09 && rdesc[3] == 0x01 && | ||
| 60 | rdesc[6] == 0x19 && rdesc[7] == 0x00 && | ||
| 61 | rdesc[11] == 0x16 && rdesc[12] == 0x3c && rdesc[13] == 0x02) { | ||
| 62 | hid_info(hdev, | ||
| 63 | "fixing up varmilo VA104M consumer control report descriptor\n"); | ||
| 64 | rdesc[12] = 0x00; | ||
| 65 | rdesc[13] = 0x00; | ||
| 66 | } | ||
| 67 | return rdesc; | ||
| 68 | } | ||
| 69 | |||
| 70 | static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 71 | unsigned int *rsize) | ||
| 72 | { | ||
| 73 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | ||
| 74 | |||
| 75 | if (quirks & CP_RDESC_SWAPPED_MIN_MAX) | ||
| 76 | rdesc = cp_rdesc_fixup(hdev, rdesc, rsize); | ||
| 77 | if (quirks & VA_INVAL_LOGICAL_BOUNDARY) | ||
| 78 | rdesc = va_logical_boundary_fixup(hdev, rdesc, rsize); | ||
| 79 | |||
| 80 | return rdesc; | ||
| 81 | } | ||
| 82 | |||
| 51 | static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 83 | static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
| 52 | struct hid_field *field, struct hid_usage *usage, | 84 | struct hid_field *field, struct hid_usage *usage, |
| 53 | unsigned long **bit, int *max) | 85 | unsigned long **bit, int *max) |
| @@ -128,6 +160,8 @@ static const struct hid_device_id cp_devices[] = { · 74 unmodified lines | |||
| 128 | .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, | 160 | .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, |
| 129 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), | 161 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), |
| 130 | .driver_data = CP_2WHEEL_MOUSE_HACK }, | 162 | .driver_data = CP_2WHEEL_MOUSE_HACK }, |
| 163 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1), | ||
| 164 | .driver_data = VA_INVAL_LOGICAL_BOUNDARY }, | ||
| 131 | { } | 165 | { } |
| 132 | }; | 166 | }; |
| 133 | MODULE_DEVICE_TABLE(hid, cp_devices); | 167 | MODULE_DEVICE_TABLE(hid, cp_devices); |
| @@ -331,6 +331,8 @@ · 330 unmodified lines | |||
| 331 | #define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 | 331 | #define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 |
| 332 | #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 | 332 | #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 |
| 333 | 333 | ||
| 334 | #define USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1 0X07b1 | ||
| 335 | |||
| 334 | #define USB_VENDOR_ID_DATA_MODUL 0x7374 | 336 | #define USB_VENDOR_ID_DATA_MODUL 0x7374 |
| 335 | #define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201 | 337 | #define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201 |
| 336 | 338 | ||
| @@ -443,6 +445,10 @@ · 106 unmodified lines | |||
| 443 | #define USB_VENDOR_ID_FRUCTEL 0x25B6 | 445 | #define USB_VENDOR_ID_FRUCTEL 0x25B6 |
| 444 | #define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002 | 446 | #define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002 |
| 445 | 447 | ||
| 448 | #define USB_VENDOR_ID_GAMEVICE 0x27F8 | ||
| 449 | #define USB_DEVICE_ID_GAMEVICE_GV186 0x0BBE | ||
| 450 | #define USB_DEVICE_ID_GAMEVICE_KISHI 0x0BBF | ||
| 451 | |||
| 446 | #define USB_VENDOR_ID_GAMERON 0x0810 | 452 | #define USB_VENDOR_ID_GAMERON 0x0810 |
| 447 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 | 453 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 |
| 448 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 | 454 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 |
| @@ -485,6 +491,7 @@ · 36 unmodified lines | |||
| 485 | #define USB_DEVICE_ID_PENPOWER 0x00f4 | 491 | #define USB_DEVICE_ID_PENPOWER 0x00f4 |
| 486 | 492 | ||
| 487 | #define USB_VENDOR_ID_GREENASIA 0x0e8f | 493 | #define USB_VENDOR_ID_GREENASIA 0x0e8f |
| 494 | #define USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR 0x3010 | ||
| 488 | #define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013 | 495 | #define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013 |
| 489 | 496 | ||
| 490 | #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 | 497 | #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 |
| @@ -743,6 +750,7 @@ · 252 unmodified lines | |||
| 743 | #define USB_VENDOR_ID_LOGITECH 0x046d | 750 | #define USB_VENDOR_ID_LOGITECH 0x046d |
| 744 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e | 751 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
| 745 | #define USB_DEVICE_ID_LOGITECH_T651 0xb00c | 752 | #define USB_DEVICE_ID_LOGITECH_T651 0xb00c |
| 753 | #define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309 | ||
| 746 | #define USB_DEVICE_ID_LOGITECH_C007 0xc007 | 754 | #define USB_DEVICE_ID_LOGITECH_C007 0xc007 |
| 747 | #define USB_DEVICE_ID_LOGITECH_C077 0xc077 | 755 | #define USB_DEVICE_ID_LOGITECH_C077 0xc077 |
| 748 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 756 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
| @@ -1298,6 +1306,7 @@ · 549 unmodified lines | |||
| 1298 | 1306 | ||
| 1299 | #define USB_VENDOR_ID_UGTIZER 0x2179 | 1307 | #define USB_VENDOR_ID_UGTIZER 0x2179 |
| 1300 | #define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053 | 1308 | #define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053 |
| 1309 | #define USB_DEVICE_ID_UGTIZER_TABLET_GT5040 0x0077 | ||
| 1301 | 1310 | ||
| 1302 | #define USB_VENDOR_ID_VIEWSONIC 0x0543 | 1311 | #define USB_VENDOR_ID_VIEWSONIC 0x0543 |
| 1303 | #define USB_DEVICE_ID_VIEWSONIC_PD1011 0xe621 | 1312 | #define USB_DEVICE_ID_VIEWSONIC_PD1011 0xe621 |
| @@ -319,6 +319,9 @@ static const struct hid_device_id hid_battery_quirks[] = { · 318 unmodified lines | |||
| 319 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, | 319 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, |
| 320 | USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), | 320 | USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), |
| 321 | HID_BATTERY_QUIRK_IGNORE }, | 321 | HID_BATTERY_QUIRK_IGNORE }, |
| 322 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, | ||
| 323 | USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD), | ||
| 324 | HID_BATTERY_QUIRK_IGNORE }, | ||
| 322 | {} | 325 | {} |
| 323 | }; | 326 | }; |
| 324 | 327 | ||
| @@ -11,6 +11,48 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include "hid-ids.h" | 12 | #include "hid-ids.h" |
| 13 | 13 | ||
| 14 | #define QUIRK_TOUCHPAD_ON_OFF_REPORT BIT(0) | ||
| 15 | |||
| 16 | static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) | ||
| 17 | { | ||
| 18 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | ||
| 19 | |||
| 20 | if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) { | ||
| 21 | if (*rsize == 188 && rdesc[162] == 0x81 && rdesc[163] == 0x02) { | ||
| 22 | hid_info(hdev, "Fixing up ITE keyboard report descriptor\n"); | ||
| 23 | rdesc[163] = HID_MAIN_ITEM_RELATIVE; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | return rdesc; | ||
| 28 | } | ||
| 29 | |||
| 30 | static int ite_input_mapping(struct hid_device *hdev, | ||
| 31 | struct hid_input *hi, struct hid_field *field, | ||
| 32 | struct hid_usage *usage, unsigned long **bit, | ||
| 33 | int *max) | ||
| 34 | { | ||
| 35 | |||
| 36 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | ||
| 37 | |||
| 38 | if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) && | ||
| 39 | (usage->hid & HID_USAGE_PAGE) == 0x00880000) { | ||
| 40 | if (usage->hid == 0x00880078) { | ||
| 41 | /* Touchpad on, userspace expects F22 for this */ | ||
| 42 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F22); | ||
| 43 | return 1; | ||
| 44 | } | ||
| 45 | if (usage->hid == 0x00880079) { | ||
| 46 | /* Touchpad off, userspace expects F23 for this */ | ||
| 47 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F23); | ||
| 48 | return 1; | ||
| 49 | } | ||
| 50 | return -1; | ||
| 51 | } | ||
| 52 | |||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 14 | static int ite_event(struct hid_device *hdev, struct hid_field *field, | 56 | static int ite_event(struct hid_device *hdev, struct hid_field *field, |
| 15 | struct hid_usage *usage, __s32 value) | 57 | struct hid_usage *usage, __s32 value) |
| 16 | { | 58 | { |
| @@ -37,13 +79,27 @@ static int ite_event(struct hid_device *hdev, struct hid_field *field, · 20 unmodified lines | |||
| 37 | return 0; | 79 | return 0; |
| 38 | } | 80 | } |
| 39 | 81 | ||
| 82 | static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
| 83 | { | ||
| 84 | int ret; | ||
| 85 | |||
| 86 | hid_set_drvdata(hdev, (void *)id->driver_data); | ||
| 87 | |||
| 88 | ret = hid_open_report(hdev); | ||
| 89 | if (ret) | ||
| 90 | return ret; | ||
| 91 | |||
| 92 | return hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 93 | } | ||
| 94 | |||
| 40 | static const struct hid_device_id ite_devices[] = { | 95 | static const struct hid_device_id ite_devices[] = { |
| 41 | { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, | 96 | { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, |
| 42 | { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, | 97 | { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, |
| 43 | /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ | 98 | /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ |
| 44 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 99 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 45 | USB_VENDOR_ID_SYNAPTICS, | 100 | USB_VENDOR_ID_SYNAPTICS, |
| 46 | USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, | 101 | USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012), |
| 102 | .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, | ||
| 47 | /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ | 103 | /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ |
| 48 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 104 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 49 | USB_VENDOR_ID_SYNAPTICS, | 105 | USB_VENDOR_ID_SYNAPTICS, |
| @@ -55,6 +111,9 @@ MODULE_DEVICE_TABLE(hid, ite_devices); · 5 unmodified lines | |||
| 55 | static struct hid_driver ite_driver = { | 111 | static struct hid_driver ite_driver = { |
| 56 | .name = "itetech", | 112 | .name = "itetech", |
| 57 | .id_table = ite_devices, | 113 | .id_table = ite_devices, |
| 114 | .probe = ite_probe, | ||
| 115 | .report_fixup = ite_report_fixup, | ||
| 116 | .input_mapping = ite_input_mapping, | ||
| 58 | .event = ite_event, | 117 | .event = ite_event, |
| 59 | }; | 118 | }; |
| 60 | module_hid_driver(ite_driver); | 119 | module_hid_driver(ite_driver); |
| @@ -328,7 +328,7 @@ static const char mse_bluetooth_descriptor[] = { · 327 unmodified lines | |||
| 328 | 0x25, 0x01, /* LOGICAL_MAX (1) */ | 328 | 0x25, 0x01, /* LOGICAL_MAX (1) */ |
| 329 | 0x75, 0x01, /* REPORT_SIZE (1) */ | 329 | 0x75, 0x01, /* REPORT_SIZE (1) */ |
| 330 | 0x95, 0x04, /* REPORT_COUNT (4) */ | 330 | 0x95, 0x04, /* REPORT_COUNT (4) */ |
| 331 | 0x81, 0x06, /* INPUT */ | 331 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ |
| 332 | 0xC0, /* END_COLLECTION */ | 332 | 0xC0, /* END_COLLECTION */ |
| 333 | 0xC0, /* END_COLLECTION */ | 333 | 0xC0, /* END_COLLECTION */ |
| 334 | }; | 334 | }; |
| @@ -866,11 +866,24 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev, · 531 unmodified lines | |||
| 866 | schedule_work(&djrcv_dev->work); | 866 | schedule_work(&djrcv_dev->work); |
| 867 | } | 867 | } |
| 868 | 868 | ||
| 869 | /* | ||
| 870 | * Some quad/bluetooth keyboards have a builtin touchpad in this case we see | ||
| 871 | * only 1 paired device with a device_type of REPORT_TYPE_KEYBOARD. For the | ||
| 872 | * touchpad to work we must also forward mouse input reports to the dj_hiddev | ||
| 873 | * created for the keyboard (instead of forwarding them to a second paired | ||
| 874 | * device with a device_type of REPORT_TYPE_MOUSE as we normally would). | ||
| 875 | */ | ||
| 876 | static const u16 kbd_builtin_touchpad_ids[] = { | ||
| 877 | 0xb309, /* Dinovo Edge */ | ||
| 878 | 0xb30c, /* Dinovo Mini */ | ||
| 879 | }; | ||
| 880 | |||
| 869 | static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, | 881 | static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, |
| 870 | struct hidpp_event *hidpp_report, | 882 | struct hidpp_event *hidpp_report, |
| 871 | struct dj_workitem *workitem) | 883 | struct dj_workitem *workitem) |
| 872 | { | 884 | { |
| 873 | struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); | 885 | struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); |
| 886 | int i, id; | ||
| 874 | 887 | ||
| 875 | workitem->type = WORKITEM_TYPE_PAIRED; | 888 | workitem->type = WORKITEM_TYPE_PAIRED; |
| 876 | workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & | 889 | workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & |
| @@ -882,6 +895,13 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, · 5 unmodified lines | |||
| 882 | workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA | | 895 | workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA | |
| 883 | POWER_KEYS | MEDIA_CENTER | | 896 | POWER_KEYS | MEDIA_CENTER | |
| 884 | HIDPP; | 897 | HIDPP; |
| 898 | id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb; | ||
| 899 | for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) { | ||
| 900 | if (id == kbd_builtin_touchpad_ids[i]) { | ||
| 901 | workitem->reports_supported |= STD_MOUSE; | ||
| 902 | break; | ||
| 903 | } | ||
| 904 | } | ||
| 885 | break; | 905 | break; |
| 886 | case REPORT_TYPE_MOUSE: | 906 | case REPORT_TYPE_MOUSE: |
| 887 | workitem->reports_supported |= STD_MOUSE | HIDPP; | 907 | workitem->reports_supported |= STD_MOUSE | HIDPP; |
| @@ -93,6 +93,8 @@ MODULE_PARM_DESC(disable_tap_to_click, · 92 unmodified lines | |||
| 93 | #define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3) | 93 | #define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3) |
| 94 | #define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4) | 94 | #define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4) |
| 95 | 95 | ||
| 96 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) | ||
| 97 | |||
| 96 | /* | 98 | /* |
| 97 | * There are two hidpp protocols in use, the first version hidpp10 is known | 99 | * There are two hidpp protocols in use, the first version hidpp10 is known |
| 98 | * as register access protocol or RAP, the second version hidpp20 is known as | 100 | * as register access protocol or RAP, the second version hidpp20 is known as |
| @@ -2950,6 +2952,26 @@ static int g920_get_config(struct hidpp_device *hidpp, · 2851 unmodified lines | |||
| 2950 | return g920_ff_set_autocenter(hidpp, data); | 2952 | return g920_ff_set_autocenter(hidpp, data); |
| 2951 | } | 2953 | } |
| 2952 | 2954 | ||
| 2955 | /* -------------------------------------------------------------------------- */ | ||
| 2956 | /* Logitech Dinovo Mini keyboard with builtin touchpad */ | ||
| 2957 | /* -------------------------------------------------------------------------- */ | ||
| 2958 | #define DINOVO_MINI_PRODUCT_ID 0xb30c | ||
| 2959 | |||
| 2960 | static int lg_dinovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 2961 | struct hid_field *field, struct hid_usage *usage, | ||
| 2962 | unsigned long **bit, int *max) | ||
| 2963 | { | ||
| 2964 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | ||
| 2965 | return 0; | ||
| 2966 | |||
| 2967 | switch (usage->hid & HID_USAGE) { | ||
| 2968 | case 0x00d: lg_map_key_clear(KEY_MEDIA); break; | ||
| 2969 | default: | ||
| 2970 | return 0; | ||
| 2971 | } | ||
| 2972 | return 1; | ||
| 2973 | } | ||
| 2974 | |||
| 2953 | /* -------------------------------------------------------------------------- */ | 2975 | /* -------------------------------------------------------------------------- */ |
| 2954 | /* HID++1.0 devices which use HID++ reports for their wheels */ | 2976 | /* HID++1.0 devices which use HID++ reports for their wheels */ |
| 2955 | /* -------------------------------------------------------------------------- */ | 2977 | /* -------------------------------------------------------------------------- */ |
| @@ -3185,6 +3207,9 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 229 unmodified lines | |||
| 3185 | field->application != HID_GD_MOUSE) | 3207 | field->application != HID_GD_MOUSE) |
| 3186 | return m560_input_mapping(hdev, hi, field, usage, bit, max); | 3208 | return m560_input_mapping(hdev, hi, field, usage, bit, max); |
| 3187 | 3209 | ||
| 3210 | if (hdev->product == DINOVO_MINI_PRODUCT_ID) | ||
| 3211 | return lg_dinovo_input_mapping(hdev, hi, field, usage, bit, max); | ||
| 3212 | |||
| 3188 | return 0; | 3213 | return 0; |
| 3189 | } | 3214 | } |
| 3190 | 3215 | ||
| @@ -3947,6 +3972,7 @@ static const struct hid_device_id hidpp_devices[] = { · 756 unmodified lines | |||
| 3947 | LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 3972 | LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 3948 | { /* Mouse Logitech MX Anywhere 2 */ | 3973 | { /* Mouse Logitech MX Anywhere 2 */ |
| 3949 | LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 3974 | LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 3975 | { LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3950 | { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 3976 | { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 3951 | { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 3977 | { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 3952 | { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 3978 | { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| @@ -3971,6 +3997,9 @@ static const struct hid_device_id hidpp_devices[] = { · 18 unmodified lines | |||
| 3971 | { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */ | 3997 | { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */ |
| 3972 | LDJ_DEVICE(0xb305), | 3998 | LDJ_DEVICE(0xb305), |
| 3973 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | 3999 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, |
| 4000 | { /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */ | ||
| 4001 | LDJ_DEVICE(0xb309), | ||
| 4002 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | ||
| 3974 | { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */ | 4003 | { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */ |
| 3975 | LDJ_DEVICE(0xb30b), | 4004 | LDJ_DEVICE(0xb30b), |
| 3976 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | 4005 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, |
| @@ -4013,6 +4042,9 @@ static const struct hid_device_id hidpp_devices[] = { · 36 unmodified lines | |||
| 4013 | { /* MX5000 keyboard over Bluetooth */ | 4042 | { /* MX5000 keyboard over Bluetooth */ |
| 4014 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305), | 4043 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305), |
| 4015 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | 4044 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, |
| 4045 | { /* Dinovo Edge keyboard over Bluetooth */ | ||
| 4046 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb309), | ||
| 4047 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | ||
| 4016 | { /* MX5500 keyboard over Bluetooth */ | 4048 | { /* MX5500 keyboard over Bluetooth */ |
| 4017 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b), | 4049 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b), |
| 4018 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | 4050 | .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, |
| @@ -49,6 +49,36 @@ enum { · 48 unmodified lines | |||
| 49 | MCP2221_ALT_F_NOT_GPIOD = 0xEF, | 49 | MCP2221_ALT_F_NOT_GPIOD = 0xEF, |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | /* MCP GPIO direction encoding */ | ||
| 53 | enum { | ||
| 54 | MCP2221_DIR_OUT = 0x00, | ||
| 55 | MCP2221_DIR_IN = 0x01, | ||
| 56 | }; | ||
| 57 | |||
| 58 | #define MCP_NGPIO 4 | ||
| 59 | |||
| 60 | /* MCP GPIO set command layout */ | ||
| 61 | struct mcp_set_gpio { | ||
| 62 | u8 cmd; | ||
| 63 | u8 dummy; | ||
| 64 | struct { | ||
| 65 | u8 change_value; | ||
| 66 | u8 value; | ||
| 67 | u8 change_direction; | ||
| 68 | u8 direction; | ||
| 69 | } gpio[MCP_NGPIO]; | ||
| 70 | } __packed; | ||
| 71 | |||
| 72 | /* MCP GPIO get command layout */ | ||
| 73 | struct mcp_get_gpio { | ||
| 74 | u8 cmd; | ||
| 75 | u8 dummy; | ||
| 76 | struct { | ||
| 77 | u8 direction; | ||
| 78 | u8 value; | ||
| 79 | } gpio[MCP_NGPIO]; | ||
| 80 | } __packed; | ||
| 81 | |||
| 52 | /* | 82 | /* |
| 53 | * There is no way to distinguish responses. Therefore next command | 83 | * There is no way to distinguish responses. Therefore next command |
| 54 | * is sent only after response to previous has been received. Mutex | 84 | * is sent only after response to previous has been received. Mutex |
| @@ -542,7 +572,7 @@ static int mcp_gpio_get(struct gpio_chip *gc, · 487 unmodified lines | |||
| 542 | 572 | ||
| 543 | mcp->txbuf[0] = MCP2221_GPIO_GET; | 573 | mcp->txbuf[0] = MCP2221_GPIO_GET; |
| 544 | 574 | ||
| 545 | mcp->gp_idx = (offset + 1) * 2; | 575 | mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].value); |
| 546 | 576 | ||
| 547 | mutex_lock(&mcp->lock); | 577 | mutex_lock(&mcp->lock); |
| 548 | ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); | 578 | ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); |
| @@ -559,7 +589,7 @@ static void mcp_gpio_set(struct gpio_chip *gc, · 10 unmodified lines | |||
| 559 | memset(mcp->txbuf, 0, 18); | 589 | memset(mcp->txbuf, 0, 18); |
| 560 | mcp->txbuf[0] = MCP2221_GPIO_SET; | 590 | mcp->txbuf[0] = MCP2221_GPIO_SET; |
| 561 | 591 | ||
| 562 | mcp->gp_idx = ((offset + 1) * 4) - 1; | 592 | mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].value); |
| 563 | 593 | ||
| 564 | mcp->txbuf[mcp->gp_idx - 1] = 1; | 594 | mcp->txbuf[mcp->gp_idx - 1] = 1; |
| 565 | mcp->txbuf[mcp->gp_idx] = !!value; | 595 | mcp->txbuf[mcp->gp_idx] = !!value; |
| @@ -575,7 +605,7 @@ static int mcp_gpio_dir_set(struct mcp2221 *mcp, · 9 unmodified lines | |||
| 575 | memset(mcp->txbuf, 0, 18); | 605 | memset(mcp->txbuf, 0, 18); |
| 576 | mcp->txbuf[0] = MCP2221_GPIO_SET; | 606 | mcp->txbuf[0] = MCP2221_GPIO_SET; |
| 577 | 607 | ||
| 578 | mcp->gp_idx = (offset + 1) * 5; | 608 | mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].direction); |
| 579 | 609 | ||
| 580 | mcp->txbuf[mcp->gp_idx - 1] = 1; | 610 | mcp->txbuf[mcp->gp_idx - 1] = 1; |
| 581 | mcp->txbuf[mcp->gp_idx] = val; | 611 | mcp->txbuf[mcp->gp_idx] = val; |
| @@ -590,7 +620,7 @@ static int mcp_gpio_direction_input(struct gpio_chip *gc, · 8 unmodified lines | |||
| 590 | struct mcp2221 *mcp = gpiochip_get_data(gc); | 620 | struct mcp2221 *mcp = gpiochip_get_data(gc); |
| 591 | 621 | ||
| 592 | mutex_lock(&mcp->lock); | 622 | mutex_lock(&mcp->lock); |
| 593 | ret = mcp_gpio_dir_set(mcp, offset, 0); | 623 | ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_IN); |
| 594 | mutex_unlock(&mcp->lock); | 624 | mutex_unlock(&mcp->lock); |
| 595 | 625 | ||
| 596 | return ret; | 626 | return ret; |
| @@ -603,7 +633,7 @@ static int mcp_gpio_direction_output(struct gpio_chip *gc, · 6 unmodified lines | |||
| 603 | struct mcp2221 *mcp = gpiochip_get_data(gc); | 633 | struct mcp2221 *mcp = gpiochip_get_data(gc); |
| 604 | 634 | ||
| 605 | mutex_lock(&mcp->lock); | 635 | mutex_lock(&mcp->lock); |
| 606 | ret = mcp_gpio_dir_set(mcp, offset, 1); | 636 | ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_OUT); |
| 607 | mutex_unlock(&mcp->lock); | 637 | mutex_unlock(&mcp->lock); |
| 608 | 638 | ||
| 609 | /* Can't configure as output, bailout early */ | 639 | /* Can't configure as output, bailout early */ |
| @@ -623,7 +653,7 @@ static int mcp_gpio_get_direction(struct gpio_chip *gc, · 13 unmodified lines | |||
| 623 | 653 | ||
| 624 | mcp->txbuf[0] = MCP2221_GPIO_GET; | 654 | mcp->txbuf[0] = MCP2221_GPIO_GET; |
| 625 | 655 | ||
| 626 | mcp->gp_idx = (offset + 1) * 2; | 656 | mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].direction); |
| 627 | 657 | ||
| 628 | mutex_lock(&mcp->lock); | 658 | mutex_lock(&mcp->lock); |
| 629 | ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); | 659 | ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); |
| @@ -632,7 +662,7 @@ static int mcp_gpio_get_direction(struct gpio_chip *gc, · 2 unmodified lines | |||
| 632 | if (ret) | 662 | if (ret) |
| 633 | return ret; | 663 | return ret; |
| 634 | 664 | ||
| 635 | if (mcp->gpio_dir) | 665 | if (mcp->gpio_dir == MCP2221_DIR_IN) |
| 636 | return GPIO_LINE_DIRECTION_IN; | 666 | return GPIO_LINE_DIRECTION_IN; |
| 637 | 667 | ||
| 638 | return GPIO_LINE_DIRECTION_OUT; | 668 | return GPIO_LINE_DIRECTION_OUT; |
| @@ -758,7 +788,7 @@ static int mcp2221_raw_event(struct hid_device *hdev, · 119 unmodified lines | |||
| 758 | mcp->status = -ENOENT; | 788 | mcp->status = -ENOENT; |
| 759 | } else { | 789 | } else { |
| 760 | mcp->status = !!data[mcp->gp_idx]; | 790 | mcp->status = !!data[mcp->gp_idx]; |
| 761 | mcp->gpio_dir = !!data[mcp->gp_idx + 1]; | 791 | mcp->gpio_dir = data[mcp->gp_idx + 1]; |
| 762 | } | 792 | } |
| 763 | break; | 793 | break; |
| 764 | default: | 794 | default: |
| @@ -860,7 +890,7 @@ static int mcp2221_probe(struct hid_device *hdev, · 95 unmodified lines | |||
| 860 | mcp->gc->get_direction = mcp_gpio_get_direction; | 890 | mcp->gc->get_direction = mcp_gpio_get_direction; |
| 861 | mcp->gc->set = mcp_gpio_set; | 891 | mcp->gc->set = mcp_gpio_set; |
| 862 | mcp->gc->get = mcp_gpio_get; | 892 | mcp->gc->get = mcp_gpio_get; |
| 863 | mcp->gc->ngpio = 4; | 893 | mcp->gc->ngpio = MCP_NGPIO; |
| 864 | mcp->gc->base = -1; | 894 | mcp->gc->base = -1; |
| 865 | mcp->gc->can_sleep = 1; | 895 | mcp->gc->can_sleep = 1; |
| 866 | mcp->gc->parent = &hdev->dev; | 896 | mcp->gc->parent = &hdev->dev; |
| @@ -83,7 +83,12 @@ static const struct hid_device_id hid_quirks[] = { · 82 unmodified lines | |||
| 83 | { HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS }, | 83 | { HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS }, |
| 84 | { HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET }, | 84 | { HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET }, |
| 85 | { HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS }, | 85 | { HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS }, |
| 86 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR), HID_QUIRK_MULTI_INPUT }, | ||
| 86 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT }, | 87 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT }, |
| 88 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_GV186), | ||
| 89 | HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, | ||
| 90 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI), | ||
| 91 | HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, | ||
| 87 | { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 92 | { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
| 88 | { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 93 | { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
| 89 | { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 94 | { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
| @@ -483,7 +483,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev, · 482 unmodified lines | |||
| 483 | return 1; | 483 | return 1; |
| 484 | 484 | ||
| 485 | ptr = raw_data; | 485 | ptr = raw_data; |
| 486 | ptr++; /* Skip report id */ | 486 | if (report->id) |
| 487 | ptr++; /* Skip report id */ | ||
| 487 | 488 | ||
| 488 | spin_lock_irqsave(&pdata->lock, flags); | 489 | spin_lock_irqsave(&pdata->lock, flags); |
| 489 | 490 | ||
| @@ -385,6 +385,8 @@ static const struct hid_device_id uclogic_devices[] = { · 384 unmodified lines | |||
| 385 | USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) }, | 385 | USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) }, |
| 386 | { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, | 386 | { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, |
| 387 | USB_DEVICE_ID_UGTIZER_TABLET_GP0610) }, | 387 | USB_DEVICE_ID_UGTIZER_TABLET_GP0610) }, |
| 388 | { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, | ||
| 389 | USB_DEVICE_ID_UGTIZER_TABLET_GT5040) }, | ||
| 388 | { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, | 390 | { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, |
| 389 | USB_DEVICE_ID_UGEE_TABLET_G5) }, | 391 | USB_DEVICE_ID_UGEE_TABLET_G5) }, |
| 390 | { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, | 392 | { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, |
| @@ -997,6 +997,8 @@ int uclogic_params_init(struct uclogic_params *params, · 996 unmodified lines | |||
| 997 | break; | 997 | break; |
| 998 | case VID_PID(USB_VENDOR_ID_UGTIZER, | 998 | case VID_PID(USB_VENDOR_ID_UGTIZER, |
| 999 | USB_DEVICE_ID_UGTIZER_TABLET_GP0610): | 999 | USB_DEVICE_ID_UGTIZER_TABLET_GP0610): |
| 1000 | case VID_PID(USB_VENDOR_ID_UGTIZER, | ||
| 1001 | USB_DEVICE_ID_UGTIZER_TABLET_GT5040): | ||
| 1000 | case VID_PID(USB_VENDOR_ID_UGEE, | 1002 | case VID_PID(USB_VENDOR_ID_UGEE, |
| 1001 | USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540): | 1003 | USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540): |
| 1002 | case VID_PID(USB_VENDOR_ID_UGEE, | 1004 | case VID_PID(USB_VENDOR_ID_UGEE, |
| @@ -943,6 +943,11 @@ static void i2c_hid_acpi_enable_wakeup(struct device *dev) · 942 unmodified lines | |||
| 943 | } | 943 | } |
| 944 | } | 944 | } |
| 945 | 945 | ||
| 946 | static void i2c_hid_acpi_shutdown(struct device *dev) | ||
| 947 | { | ||
| 948 | acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D3_COLD); | ||
| 949 | } | ||
| 950 | |||
| 946 | static const struct acpi_device_id i2c_hid_acpi_match[] = { | 951 | static const struct acpi_device_id i2c_hid_acpi_match[] = { |
| 947 | {"ACPI0C50", 0 }, | 952 | {"ACPI0C50", 0 }, |
| 948 | {"PNP0C50", 0 }, | 953 | {"PNP0C50", 0 }, |
| @@ -959,6 +964,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client, · 10 unmodified lines | |||
| 959 | static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} | 964 | static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} |
| 960 | 965 | ||
| 961 | static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {} | 966 | static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {} |
| 967 | |||
| 968 | static inline void i2c_hid_acpi_shutdown(struct device *dev) {} | ||
| 962 | #endif | 969 | #endif |
| 963 | 970 | ||
| 964 | #ifdef CONFIG_OF | 971 | #ifdef CONFIG_OF |
| @@ -1175,6 +1182,8 @@ static void i2c_hid_shutdown(struct i2c_client *client) · 210 unmodified lines | |||
| 1175 | 1182 | ||
| 1176 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | 1183 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
| 1177 | free_irq(client->irq, ihid); | 1184 | free_irq(client->irq, ihid); |
| 1185 | |||
| 1186 | i2c_hid_acpi_shutdown(&client->dev); | ||
| 1178 | } | 1187 | } |
| 1179 | 1188 | ||
| 1180 | #ifdef CONFIG_PM_SLEEP | 1189 | #ifdef CONFIG_PM_SLEEP |
| @@ -126,6 +126,12 @@ enum kx_chipset { · 125 unmodified lines | |||
| 126 | KX_MAX_CHIPS /* this must be last */ | 126 | KX_MAX_CHIPS /* this must be last */ |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | enum kx_acpi_type { | ||
| 130 | ACPI_GENERIC, | ||
| 131 | ACPI_SMO8500, | ||
| 132 | ACPI_KIOX010A, | ||
| 133 | }; | ||
| 134 | |||
| 129 | struct kxcjk1013_data { | 135 | struct kxcjk1013_data { |
| 130 | struct i2c_client *client; | 136 | struct i2c_client *client; |
| 131 | struct iio_trigger *dready_trig; | 137 | struct iio_trigger *dready_trig; |
| @@ -143,7 +149,7 @@ struct kxcjk1013_data { · 11 unmodified lines | |||
| 143 | bool motion_trigger_on; | 149 | bool motion_trigger_on; |
| 144 | int64_t timestamp; | 150 | int64_t timestamp; |
| 145 | enum kx_chipset chipset; | 151 | enum kx_chipset chipset; |
| 146 | bool is_smo8500_device; | 152 | enum kx_acpi_type acpi_type; |
| 147 | }; | 153 | }; |
| 148 | 154 | ||
| 149 | enum kxcjk1013_axis { | 155 | enum kxcjk1013_axis { |
| @@ -270,6 +276,32 @@ static const struct { · 120 unmodified lines | |||
| 270 | {19163, 1, 0}, | 276 | {19163, 1, 0}, |
| 271 | {38326, 0, 1} }; | 277 | {38326, 0, 1} }; |
| 272 | 278 | ||
| 279 | #ifdef CONFIG_ACPI | ||
| 280 | enum kiox010a_fn_index { | ||
| 281 | KIOX010A_SET_LAPTOP_MODE = 1, | ||
| 282 | KIOX010A_SET_TABLET_MODE = 2, | ||
| 283 | }; | ||
| 284 | |||
| 285 | static int kiox010a_dsm(struct device *dev, int fn_index) | ||
| 286 | { | ||
| 287 | acpi_handle handle = ACPI_HANDLE(dev); | ||
| 288 | guid_t kiox010a_dsm_guid; | ||
| 289 | union acpi_object *obj; | ||
| 290 | |||
| 291 | if (!handle) | ||
| 292 | return -ENODEV; | ||
| 293 | |||
| 294 | guid_parse("1f339696-d475-4e26-8cad-2e9f8e6d7a91", &kiox010a_dsm_guid); | ||
| 295 | |||
| 296 | obj = acpi_evaluate_dsm(handle, &kiox010a_dsm_guid, 1, fn_index, NULL); | ||
| 297 | if (!obj) | ||
| 298 | return -EIO; | ||
| 299 | |||
| 300 | ACPI_FREE(obj); | ||
| 301 | return 0; | ||
| 302 | } | ||
| 303 | #endif | ||
| 304 | |||
| 273 | static int kxcjk1013_set_mode(struct kxcjk1013_data *data, | 305 | static int kxcjk1013_set_mode(struct kxcjk1013_data *data, |
| 274 | enum kxcjk1013_mode mode) | 306 | enum kxcjk1013_mode mode) |
| 275 | { | 307 | { |
| @@ -347,6 +379,13 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) · 71 unmodified lines | |||
| 347 | { | 379 | { |
| 348 | int ret; | 380 | int ret; |
| 349 | 381 | ||
| 382 | #ifdef CONFIG_ACPI | ||
| 383 | if (data->acpi_type == ACPI_KIOX010A) { | ||
| 384 | /* Make sure the kbd and touchpad on 2-in-1s using 2 KXCJ91008-s work */ | ||
| 385 | kiox010a_dsm(&data->client->dev, KIOX010A_SET_LAPTOP_MODE); | ||
| 386 | } | ||
| 387 | #endif | ||
| 388 | |||
| 350 | ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I); | 389 | ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I); |
| 351 | if (ret < 0) { | 390 | if (ret < 0) { |
| 352 | dev_err(&data->client->dev, "Error reading who_am_i\n"); | 391 | dev_err(&data->client->dev, "Error reading who_am_i\n"); |
| @@ -1247,7 +1286,7 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private) · 894 unmodified lines | |||
| 1247 | 1286 | ||
| 1248 | static const char *kxcjk1013_match_acpi_device(struct device *dev, | 1287 | static const char *kxcjk1013_match_acpi_device(struct device *dev, |
| 1249 | enum kx_chipset *chipset, | 1288 | enum kx_chipset *chipset, |
| 1250 | bool *is_smo8500_device) | 1289 | enum kx_acpi_type *acpi_type) |
| 1251 | { | 1290 | { |
| 1252 | const struct acpi_device_id *id; | 1291 | const struct acpi_device_id *id; |
| 1253 | 1292 | ||
| @@ -1256,7 +1295,9 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev, · 2 unmodified lines | |||
| 1256 | return NULL; | 1295 | return NULL; |
| 1257 | 1296 | ||
| 1258 | if (strcmp(id->id, "SMO8500") == 0) | 1297 | if (strcmp(id->id, "SMO8500") == 0) |
| 1259 | *is_smo8500_device = true; | 1298 | *acpi_type = ACPI_SMO8500; |
| 1299 | else if (strcmp(id->id, "KIOX010A") == 0) | ||
| 1300 | *acpi_type = ACPI_KIOX010A; | ||
| 1260 | 1301 | ||
| 1261 | *chipset = (enum kx_chipset)id->driver_data; | 1302 | *chipset = (enum kx_chipset)id->driver_data; |
| 1262 | 1303 | ||
| @@ -1299,7 +1340,7 @@ static int kxcjk1013_probe(struct i2c_client *client, · 36 unmodified lines | |||
| 1299 | } else if (ACPI_HANDLE(&client->dev)) { | 1340 | } else if (ACPI_HANDLE(&client->dev)) { |
| 1300 | name = kxcjk1013_match_acpi_device(&client->dev, | 1341 | name = kxcjk1013_match_acpi_device(&client->dev, |
| 1301 | &data->chipset, | 1342 | &data->chipset, |
| 1302 | &data->is_smo8500_device); | 1343 | &data->acpi_type); |
| 1303 | } else | 1344 | } else |
| 1304 | return -ENODEV; | 1345 | return -ENODEV; |
| 1305 | 1346 | ||
| @@ -1316,7 +1357,7 @@ static int kxcjk1013_probe(struct i2c_client *client, · 10 unmodified lines | |||
| 1316 | indio_dev->modes = INDIO_DIRECT_MODE; | 1357 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 1317 | indio_dev->info = &kxcjk1013_info; | 1358 | indio_dev->info = &kxcjk1013_info; |
| 1318 | 1359 | ||
| 1319 | if (client->irq > 0 && !data->is_smo8500_device) { | 1360 | if (client->irq > 0 && data->acpi_type != ACPI_SMO8500) { |
| 1320 | ret = devm_request_threaded_irq(&client->dev, client->irq, | 1361 | ret = devm_request_threaded_irq(&client->dev, client->irq, |
| 1321 | kxcjk1013_data_rdy_trig_poll, | 1362 | kxcjk1013_data_rdy_trig_poll, |
| 1322 | kxcjk1013_event_handler, | 1363 | kxcjk1013_event_handler, |
| @@ -71,7 +71,7 @@ · 70 unmodified lines | |||
| 71 | #define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10 | 71 | #define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10 |
| 72 | #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986) | 72 | #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986) |
| 73 | #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12 | 73 | #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12 |
| 74 | #define JZ4770_ADC_BATTERY_VREF 6600 | 74 | #define JZ4770_ADC_BATTERY_VREF 1200 |
| 75 | #define JZ4770_ADC_BATTERY_VREF_BITS 12 | 75 | #define JZ4770_ADC_BATTERY_VREF_BITS 12 |
| 76 | 76 | ||
| 77 | #define JZ_ADC_IRQ_AUX BIT(0) | 77 | #define JZ_ADC_IRQ_AUX BIT(0) |
| @@ -177,13 +177,12 @@ static void ingenic_adc_set_config(struct ingenic_adc *adc, · 99 unmodified lines | |||
| 177 | mutex_unlock(&adc->lock); | 177 | mutex_unlock(&adc->lock); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | static void ingenic_adc_enable(struct ingenic_adc *adc, | 180 | static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc, |
| 181 | int engine, | 181 | int engine, |
| 182 | bool enabled) | 182 | bool enabled) |
| 183 | { | 183 | { |
| 184 | u8 val; | 184 | u8 val; |
| 185 | 185 | ||
| 186 | mutex_lock(&adc->lock); | ||
| 187 | val = readb(adc->base + JZ_ADC_REG_ENABLE); | 186 | val = readb(adc->base + JZ_ADC_REG_ENABLE); |
| 188 | 187 | ||
| 189 | if (enabled) | 188 | if (enabled) |
| @@ -192,20 +191,41 @@ static void ingenic_adc_enable(struct ingenic_adc *adc, · 2 unmodified lines | |||
| 192 | val &= ~BIT(engine); | 191 | val &= ~BIT(engine); |
| 193 | 192 | ||
| 194 | writeb(val, adc->base + JZ_ADC_REG_ENABLE); | 193 | writeb(val, adc->base + JZ_ADC_REG_ENABLE); |
| 194 | } | ||
| 195 | |||
| 196 | static void ingenic_adc_enable(struct ingenic_adc *adc, | ||
| 197 | int engine, | ||
| 198 | bool enabled) | ||
| 199 | { | ||
| 200 | mutex_lock(&adc->lock); | ||
| 201 | ingenic_adc_enable_unlocked(adc, engine, enabled); | ||
| 195 | mutex_unlock(&adc->lock); | 202 | mutex_unlock(&adc->lock); |
| 196 | } | 203 | } |
| 197 | 204 | ||
| 198 | static int ingenic_adc_capture(struct ingenic_adc *adc, | 205 | static int ingenic_adc_capture(struct ingenic_adc *adc, |
| 199 | int engine) | 206 | int engine) |
| 200 | { | 207 | { |
| 208 | u32 cfg; | ||
| 201 | u8 val; | 209 | u8 val; |
| 202 | int ret; | 210 | int ret; |
| 203 | 211 | ||
| 204 | ingenic_adc_enable(adc, engine, true); | 212 | /* |
| 213 | * Disable CMD_SEL temporarily, because it causes wrong VBAT readings, | ||
| 214 | * probably due to the switch of VREF. We must keep the lock here to | ||
| 215 | * avoid races with the buffer enable/disable functions. | ||
| 216 | */ | ||
| 217 | mutex_lock(&adc->lock); | ||
| 218 | cfg = readl(adc->base + JZ_ADC_REG_CFG); | ||
| 219 | writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base + JZ_ADC_REG_CFG); | ||
| 220 | |||
| 221 | ingenic_adc_enable_unlocked(adc, engine, true); | ||
| 205 | ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val, | 222 | ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val, |
| 206 | !(val & BIT(engine)), 250, 1000); | 223 | !(val & BIT(engine)), 250, 1000); |
| 207 | if (ret) | 224 | if (ret) |
| 208 | ingenic_adc_enable(adc, engine, false); | 225 | ingenic_adc_enable_unlocked(adc, engine, false); |
| 226 | |||
| 227 | writel(cfg, adc->base + JZ_ADC_REG_CFG); | ||
| 228 | mutex_unlock(&adc->lock); | ||
| 209 | 229 | ||
| 210 | return ret; | 230 | return ret; |
| 211 | } | 231 | } |
| @@ -9,9 +9,9 @@ · 8 unmodified lines | |||
| 9 | #include <linux/err.h> | 9 | #include <linux/err.h> |
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/of.h> | 12 | #include <linux/mod_devicetable.h> |
| 13 | #include <linux/of_device.h> | ||
| 14 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 14 | #include <linux/property.h> | ||
| 15 | #include <linux/iopoll.h> | 15 | #include <linux/iopoll.h> |
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/iio/iio.h> | 17 | #include <linux/iio/iio.h> |
| @@ -276,6 +276,8 @@ static int mt6577_auxadc_probe(struct platform_device *pdev) · 258 unmodified lines | |||
| 276 | goto err_disable_clk; | 276 | goto err_disable_clk; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | adc_dev->dev_comp = device_get_match_data(&pdev->dev); | ||
| 280 | |||
| 279 | mutex_init(&adc_dev->lock); | 281 | mutex_init(&adc_dev->lock); |
| 280 | 282 | ||
| 281 | mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC, | 283 | mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC, |
| @@ -41,18 +41,16 @@ · 40 unmodified lines | |||
| 41 | * struct stm32_adc_common_regs - stm32 common registers | 41 | * struct stm32_adc_common_regs - stm32 common registers |
| 42 | * @csr: common status register offset | 42 | * @csr: common status register offset |
| 43 | * @ccr: common control register offset | 43 | * @ccr: common control register offset |
| 44 | * @eoc1_msk: adc1 end of conversion flag in @csr | 44 | * @eoc_msk: array of eoc (end of conversion flag) masks in csr for adc1..n |
| 45 | * @eoc2_msk: adc2 end of conversion flag in @csr | 45 | * @ovr_msk: array of ovr (overrun flag) masks in csr for adc1..n |
| 46 | * @eoc3_msk: adc3 end of conversion flag in @csr | ||
| 47 | * @ier: interrupt enable register offset for each adc | 46 | * @ier: interrupt enable register offset for each adc |
| 48 | * @eocie_msk: end of conversion interrupt enable mask in @ier | 47 | * @eocie_msk: end of conversion interrupt enable mask in @ier |
| 49 | */ | 48 | */ |
| 50 | struct stm32_adc_common_regs { | 49 | struct stm32_adc_common_regs { |
| 51 | u32 csr; | 50 | u32 csr; |
| 52 | u32 ccr; | 51 | u32 ccr; |
| 53 | u32 eoc1_msk; | 52 | u32 eoc_msk[STM32_ADC_MAX_ADCS]; |
| 54 | u32 eoc2_msk; | 53 | u32 ovr_msk[STM32_ADC_MAX_ADCS]; |
| 55 | u32 eoc3_msk; | ||
| 56 | u32 ier; | 54 | u32 ier; |
| 57 | u32 eocie_msk; | 55 | u32 eocie_msk; |
| 58 | }; | 56 | }; |
| @@ -282,21 +280,20 @@ out: · 223 unmodified lines | |||
| 282 | static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { | 280 | static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { |
| 283 | .csr = STM32F4_ADC_CSR, | 281 | .csr = STM32F4_ADC_CSR, |
| 284 | .ccr = STM32F4_ADC_CCR, | 282 | .ccr = STM32F4_ADC_CCR, |
| 285 | .eoc1_msk = STM32F4_EOC1 | STM32F4_OVR1, | 283 | .eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3}, |
| 286 | .eoc2_msk = STM32F4_EOC2 | STM32F4_OVR2, | 284 | .ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3}, |
| 287 | .eoc3_msk = STM32F4_EOC3 | STM32F4_OVR3, | ||
| 288 | .ier = STM32F4_ADC_CR1, | 285 | .ier = STM32F4_ADC_CR1, |
| 289 | .eocie_msk = STM32F4_EOCIE | STM32F4_OVRIE, | 286 | .eocie_msk = STM32F4_EOCIE, |
| 290 | }; | 287 | }; |
| 291 | 288 | ||
| 292 | /* STM32H7 common registers definitions */ | 289 | /* STM32H7 common registers definitions */ |
| 293 | static const struct stm32_adc_common_regs stm32h7_adc_common_regs = { | 290 | static const struct stm32_adc_common_regs stm32h7_adc_common_regs = { |
| 294 | .csr = STM32H7_ADC_CSR, | 291 | .csr = STM32H7_ADC_CSR, |
| 295 | .ccr = STM32H7_ADC_CCR, | 292 | .ccr = STM32H7_ADC_CCR, |
| 296 | .eoc1_msk = STM32H7_EOC_MST | STM32H7_OVR_MST, | 293 | .eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV}, |
| 297 | .eoc2_msk = STM32H7_EOC_SLV | STM32H7_OVR_SLV, | 294 | .ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV}, |
| 298 | .ier = STM32H7_ADC_IER, | 295 | .ier = STM32H7_ADC_IER, |
| 299 | .eocie_msk = STM32H7_EOCIE | STM32H7_OVRIE, | 296 | .eocie_msk = STM32H7_EOCIE, |
| 300 | }; | 297 | }; |
| 301 | 298 | ||
| 302 | static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = { | 299 | static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = { |
| @@ -318,6 +315,7 @@ static void stm32_adc_irq_handler(struct irq_desc *desc) · 15 unmodified lines | |||
| 318 | { | 315 | { |
| 319 | struct stm32_adc_priv *priv = irq_desc_get_handler_data(desc); | 316 | struct stm32_adc_priv *priv = irq_desc_get_handler_data(desc); |
| 320 | struct irq_chip *chip = irq_desc_get_chip(desc); | 317 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 318 | int i; | ||
| 321 | u32 status; | 319 | u32 status; |
| 322 | 320 | ||
| 323 | chained_irq_enter(chip, desc); | 321 | chained_irq_enter(chip, desc); |
| @@ -335,17 +333,12 @@ static void stm32_adc_irq_handler(struct irq_desc *desc) · 11 unmodified lines | |||
| 335 | * before invoking the interrupt handler (e.g. call ISR only for | 333 | * before invoking the interrupt handler (e.g. call ISR only for |
| 336 | * IRQ-enabled ADCs). | 334 | * IRQ-enabled ADCs). |
| 337 | */ | 335 | */ |
| 338 | if (status & priv->cfg->regs->eoc1_msk && | 336 | for (i = 0; i < priv->cfg->num_irqs; i++) { |
| 339 | stm32_adc_eoc_enabled(priv, 0)) | 337 | if ((status & priv->cfg->regs->eoc_msk[i] && |
| 340 | generic_handle_irq(irq_find_mapping(priv->domain, 0)); | 338 | stm32_adc_eoc_enabled(priv, i)) || |
| 341 | 339 | (status & priv->cfg->regs->ovr_msk[i])) | |
| 342 | if (status & priv->cfg->regs->eoc2_msk && | 340 | generic_handle_irq(irq_find_mapping(priv->domain, i)); |
| 343 | stm32_adc_eoc_enabled(priv, 1)) | 341 | } |
| 344 | generic_handle_irq(irq_find_mapping(priv->domain, 1)); | ||
| 345 | |||
| 346 | if (status & priv->cfg->regs->eoc3_msk && | ||
| 347 | stm32_adc_eoc_enabled(priv, 2)) | ||
| 348 | generic_handle_irq(irq_find_mapping(priv->domain, 2)); | ||
| 349 | 342 | ||
| 350 | chained_irq_exit(chip, desc); | 343 | chained_irq_exit(chip, desc); |
| 351 | }; | 344 | }; |
| @@ -154,6 +154,7 @@ struct stm32_adc; · 153 unmodified lines | |||
| 154 | * @start_conv: routine to start conversions | 154 | * @start_conv: routine to start conversions |
| 155 | * @stop_conv: routine to stop conversions | 155 | * @stop_conv: routine to stop conversions |
| 156 | * @unprepare: optional unprepare routine (disable, power-down) | 156 | * @unprepare: optional unprepare routine (disable, power-down) |
| 157 | * @irq_clear: routine to clear irqs | ||
| 157 | * @smp_cycles: programmable sampling time (ADC clock cycles) | 158 | * @smp_cycles: programmable sampling time (ADC clock cycles) |
| 158 | */ | 159 | */ |
| 159 | struct stm32_adc_cfg { | 160 | struct stm32_adc_cfg { |
| @@ -166,6 +167,7 @@ struct stm32_adc_cfg { · 6 unmodified lines | |||
| 166 | void (*start_conv)(struct iio_dev *, bool dma); | 167 | void (*start_conv)(struct iio_dev *, bool dma); |
| 167 | void (*stop_conv)(struct iio_dev *); | 168 | void (*stop_conv)(struct iio_dev *); |
| 168 | void (*unprepare)(struct iio_dev *); | 169 | void (*unprepare)(struct iio_dev *); |
| 170 | void (*irq_clear)(struct iio_dev *indio_dev, u32 msk); | ||
| 169 | const unsigned int *smp_cycles; | 171 | const unsigned int *smp_cycles; |
| 170 | }; | 172 | }; |
| 171 | 173 | ||
| @@ -621,6 +623,13 @@ static void stm32f4_adc_stop_conv(struct iio_dev *indio_dev) · 449 unmodified lines | |||
| 621 | STM32F4_ADON | STM32F4_DMA | STM32F4_DDS); | 623 | STM32F4_ADON | STM32F4_DMA | STM32F4_DDS); |
| 622 | } | 624 | } |
| 623 | 625 | ||
| 626 | static void stm32f4_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) | ||
| 627 | { | ||
| 628 | struct stm32_adc *adc = iio_priv(indio_dev); | ||
| 629 | |||
| 630 | stm32_adc_clr_bits(adc, adc->cfg->regs->isr_eoc.reg, msk); | ||
| 631 | } | ||
| 632 | |||
| 624 | static void stm32h7_adc_start_conv(struct iio_dev *indio_dev, bool dma) | 633 | static void stm32h7_adc_start_conv(struct iio_dev *indio_dev, bool dma) |
| 625 | { | 634 | { |
| 626 | struct stm32_adc *adc = iio_priv(indio_dev); | 635 | struct stm32_adc *adc = iio_priv(indio_dev); |
| @@ -659,6 +668,13 @@ static void stm32h7_adc_stop_conv(struct iio_dev *indio_dev) · 32 unmodified lines | |||
| 659 | stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK); | 668 | stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK); |
| 660 | } | 669 | } |
| 661 | 670 | ||
| 671 | static void stm32h7_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) | ||
| 672 | { | ||
| 673 | struct stm32_adc *adc = iio_priv(indio_dev); | ||
| 674 | /* On STM32H7 IRQs are cleared by writing 1 into ISR register */ | ||
| 675 | stm32_adc_set_bits(adc, adc->cfg->regs->isr_eoc.reg, msk); | ||
| 676 | } | ||
| 677 | |||
| 662 | static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) | 678 | static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) |
| 663 | { | 679 | { |
| 664 | struct stm32_adc *adc = iio_priv(indio_dev); | 680 | struct stm32_adc *adc = iio_priv(indio_dev); |
| @@ -1235,17 +1251,40 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev, · 570 unmodified lines | |||
| 1235 | } | 1251 | } |
| 1236 | } | 1252 | } |
| 1237 | 1253 | ||
| 1254 | static void stm32_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) | ||
| 1255 | { | ||
| 1256 | struct stm32_adc *adc = iio_priv(indio_dev); | ||
| 1257 | |||
| 1258 | adc->cfg->irq_clear(indio_dev, msk); | ||
| 1259 | } | ||
| 1260 | |||
| 1238 | static irqreturn_t stm32_adc_threaded_isr(int irq, void *data) | 1261 | static irqreturn_t stm32_adc_threaded_isr(int irq, void *data) |
| 1239 | { | 1262 | { |
| 1240 | struct iio_dev *indio_dev = data; | 1263 | struct iio_dev *indio_dev = data; |
| 1241 | struct stm32_adc *adc = iio_priv(indio_dev); | 1264 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1242 | const struct stm32_adc_regspec *regs = adc->cfg->regs; | 1265 | const struct stm32_adc_regspec *regs = adc->cfg->regs; |
| 1243 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); | 1266 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); |
| 1267 | u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg); | ||
| 1244 | 1268 | ||
| 1245 | if (status & regs->isr_ovr.mask) | 1269 | /* Check ovr status right now, as ovr mask should be already disabled */ |
| 1270 | if (status & regs->isr_ovr.mask) { | ||
| 1271 | /* | ||
| 1272 | * Clear ovr bit to avoid subsequent calls to IRQ handler. | ||
| 1273 | * This requires to stop ADC first. OVR bit state in ISR, | ||
| 1274 | * is propaged to CSR register by hardware. | ||
| 1275 | */ | ||
| 1276 | adc->cfg->stop_conv(indio_dev); | ||
| 1277 | stm32_adc_irq_clear(indio_dev, regs->isr_ovr.mask); | ||
| 1246 | dev_err(&indio_dev->dev, "Overrun, stopping: restart needed\n"); | 1278 | dev_err(&indio_dev->dev, "Overrun, stopping: restart needed\n"); |
| 1279 | return IRQ_HANDLED; | ||
| 1280 | } | ||
| 1247 | 1281 | ||
| 1248 | return IRQ_HANDLED; | 1282 | if (!(status & mask)) |
| 1283 | dev_err_ratelimited(&indio_dev->dev, | ||
| 1284 | "Unexpected IRQ: IER=0x%08x, ISR=0x%08x\n", | ||
| 1285 | mask, status); | ||
| 1286 | |||
| 1287 | return IRQ_NONE; | ||
| 1249 | } | 1288 | } |
| 1250 | 1289 | ||
| 1251 | static irqreturn_t stm32_adc_isr(int irq, void *data) | 1290 | static irqreturn_t stm32_adc_isr(int irq, void *data) |
| @@ -1254,6 +1293,10 @@ static irqreturn_t stm32_adc_isr(int irq, void *data) · 2 unmodified lines | |||
| 1254 | struct stm32_adc *adc = iio_priv(indio_dev); | 1293 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1255 | const struct stm32_adc_regspec *regs = adc->cfg->regs; | 1294 | const struct stm32_adc_regspec *regs = adc->cfg->regs; |
| 1256 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); | 1295 | u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); |
| 1296 | u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg); | ||
| 1297 | |||
| 1298 | if (!(status & mask)) | ||
| 1299 | return IRQ_WAKE_THREAD; | ||
| 1257 | 1300 | ||
| 1258 | if (status & regs->isr_ovr.mask) { | 1301 | if (status & regs->isr_ovr.mask) { |
| 1259 | /* | 1302 | /* |
| @@ -2046,6 +2089,7 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = { · 786 unmodified lines | |||
| 2046 | .start_conv = stm32f4_adc_start_conv, | 2089 | .start_conv = stm32f4_adc_start_conv, |
| 2047 | .stop_conv = stm32f4_adc_stop_conv, | 2090 | .stop_conv = stm32f4_adc_stop_conv, |
| 2048 | .smp_cycles = stm32f4_adc_smp_cycles, | 2091 | .smp_cycles = stm32f4_adc_smp_cycles, |
| 2092 | .irq_clear = stm32f4_adc_irq_clear, | ||
| 2049 | }; | 2093 | }; |
| 2050 | 2094 | ||
| 2051 | static const struct stm32_adc_cfg stm32h7_adc_cfg = { | 2095 | static const struct stm32_adc_cfg stm32h7_adc_cfg = { |
| @@ -2057,6 +2101,7 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = { · 5 unmodified lines | |||
| 2057 | .prepare = stm32h7_adc_prepare, | 2101 | .prepare = stm32h7_adc_prepare, |
| 2058 | .unprepare = stm32h7_adc_unprepare, | 2102 | .unprepare = stm32h7_adc_unprepare, |
| 2059 | .smp_cycles = stm32h7_adc_smp_cycles, | 2103 | .smp_cycles = stm32h7_adc_smp_cycles, |
| 2104 | .irq_clear = stm32h7_adc_irq_clear, | ||
| 2060 | }; | 2105 | }; |
| 2061 | 2106 | ||
| 2062 | static const struct stm32_adc_cfg stm32mp1_adc_cfg = { | 2107 | static const struct stm32_adc_cfg stm32mp1_adc_cfg = { |
| @@ -2069,6 +2114,7 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { · 6 unmodified lines | |||
| 2069 | .prepare = stm32h7_adc_prepare, | 2114 | .prepare = stm32h7_adc_prepare, |
| 2070 | .unprepare = stm32h7_adc_unprepare, | 2115 | .unprepare = stm32h7_adc_unprepare, |
| 2071 | .smp_cycles = stm32h7_adc_smp_cycles, | 2116 | .smp_cycles = stm32h7_adc_smp_cycles, |
| 2117 | .irq_clear = stm32h7_adc_irq_clear, | ||
| 2072 | }; | 2118 | }; |
| 2073 | 2119 | ||
| 2074 | static const struct of_device_id stm32_adc_of_match[] = { | 2120 | static const struct of_device_id stm32_adc_of_match[] = { |
| @@ -256,7 +256,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, · 255 unmodified lines | |||
| 256 | struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent); | 256 | struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent); |
| 257 | struct cros_ec_dev *ec = sensor_hub->ec; | 257 | struct cros_ec_dev *ec = sensor_hub->ec; |
| 258 | struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); | 258 | struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); |
| 259 | u32 ver_mask; | 259 | u32 ver_mask, temp; |
| 260 | int frequencies[ARRAY_SIZE(state->frequencies) / 2] = { 0 }; | 260 | int frequencies[ARRAY_SIZE(state->frequencies) / 2] = { 0 }; |
| 261 | int ret, i; | 261 | int ret, i; |
| 262 | 262 | ||
| @@ -311,10 +311,16 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, · 48 unmodified lines | |||
| 311 | &frequencies[2], | 311 | &frequencies[2], |
| 312 | &state->fifo_max_event_count); | 312 | &state->fifo_max_event_count); |
| 313 | } else { | 313 | } else { |
| 314 | frequencies[1] = state->resp->info_3.min_frequency; | 314 | if (state->resp->info_3.max_frequency == 0) { |
| 315 | frequencies[2] = state->resp->info_3.max_frequency; | 315 | get_default_min_max_freq(state->resp->info.type, |
| 316 | state->fifo_max_event_count = | 316 | &frequencies[1], |
| 317 | state->resp->info_3.fifo_max_event_count; | 317 | &frequencies[2], |
| 318 | &temp); | ||
| 319 | } else { | ||
| 320 | frequencies[1] = state->resp->info_3.min_frequency; | ||
| 321 | frequencies[2] = state->resp->info_3.max_frequency; | ||
| 322 | } | ||
| 323 | state->fifo_max_event_count = state->resp->info_3.fifo_max_event_count; | ||
| 318 | } | 324 | } |
| 319 | for (i = 0; i < ARRAY_SIZE(frequencies); i++) { | 325 | for (i = 0; i < ARRAY_SIZE(frequencies); i++) { |
| 320 | state->frequencies[2 * i] = frequencies[i] / 1000; | 326 | state->frequencies[2 * i] = frequencies[i] / 1000; |
| @@ -156,11 +156,13 @@ static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = { · 155 unmodified lines | |||
| 156 | static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) | 156 | static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) |
| 157 | { | 157 | { |
| 158 | struct st_lsm6dsx_sensor *sensor; | 158 | struct st_lsm6dsx_sensor *sensor; |
| 159 | u32 odr; | 159 | u32 odr, timeout; |
| 160 | 160 | ||
| 161 | sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); | 161 | sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); |
| 162 | odr = (hw->enable_mask & BIT(ST_LSM6DSX_ID_ACC)) ? sensor->odr : 12500; | 162 | odr = (hw->enable_mask & BIT(ST_LSM6DSX_ID_ACC)) ? sensor->odr : 12500; |
| 163 | msleep((2000000U / odr) + 1); | 163 | /* set 10ms as minimum timeout for i2c slave configuration */ |
| 164 | timeout = max_t(u32, 2000000U / odr + 1, 10); | ||
| 165 | msleep(timeout); | ||
| 164 | } | 166 | } |
| 165 | 167 | ||
| 166 | /* | 168 | /* |
| @@ -544,6 +544,7 @@ config VCNL4000 · 543 unmodified lines | |||
| 544 | 544 | ||
| 545 | config VCNL4035 | 545 | config VCNL4035 |
| 546 | tristate "VCNL4035 combined ALS and proximity sensor" | 546 | tristate "VCNL4035 combined ALS and proximity sensor" |
| 547 | select IIO_BUFFER | ||
| 547 | select IIO_TRIGGERED_BUFFER | 548 | select IIO_TRIGGERED_BUFFER |
| 548 | select REGMAP_I2C | 549 | select REGMAP_I2C |
| 549 | depends on I2C | 550 | depends on I2C |
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright(c) 2020 Cornelis Networks, Inc. | ||
| 2 | * Copyright(c) 2015-2020 Intel Corporation. | 3 | * Copyright(c) 2015-2020 Intel Corporation. |
| 3 | * | 4 | * |
| 4 | * This file is provided under a dual BSD/GPLv2 license. When using or | 5 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -206,8 +207,6 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) · 201 unmodified lines | |||
| 206 | spin_lock_init(&fd->tid_lock); | 207 | spin_lock_init(&fd->tid_lock); |
| 207 | spin_lock_init(&fd->invalid_lock); | 208 | spin_lock_init(&fd->invalid_lock); |
| 208 | fd->rec_cpu_num = -1; /* no cpu affinity by default */ | 209 | fd->rec_cpu_num = -1; /* no cpu affinity by default */ |
| 209 | fd->mm = current->mm; | ||
| 210 | mmgrab(fd->mm); | ||
| 211 | fd->dd = dd; | 210 | fd->dd = dd; |
| 212 | fp->private_data = fd; | 211 | fp->private_data = fd; |
| 213 | return 0; | 212 | return 0; |
| @@ -711,7 +710,6 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) · 497 unmodified lines | |||
| 711 | 710 | ||
| 712 | deallocate_ctxt(uctxt); | 711 | deallocate_ctxt(uctxt); |
| 713 | done: | 712 | done: |
| 714 | mmdrop(fdata->mm); | ||
| 715 | 713 | ||
| 716 | if (atomic_dec_and_test(&dd->user_refcount)) | 714 | if (atomic_dec_and_test(&dd->user_refcount)) |
| 717 | complete(&dd->user_comp); | 715 | complete(&dd->user_comp); |
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _HFI1_KERNEL_H | 1 | #ifndef _HFI1_KERNEL_H |
| 2 | #define _HFI1_KERNEL_H | 2 | #define _HFI1_KERNEL_H |
| 3 | /* | 3 | /* |
| 4 | * Copyright(c) 2020 Cornelis Networks, Inc. | ||
| 4 | * Copyright(c) 2015-2020 Intel Corporation. | 5 | * Copyright(c) 2015-2020 Intel Corporation. |
| 5 | * | 6 | * |
| 6 | * This file is provided under a dual BSD/GPLv2 license. When using or | 7 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -1451,7 +1452,6 @@ struct hfi1_filedata { · 1444 unmodified lines | |||
| 1451 | u32 invalid_tid_idx; | 1452 | u32 invalid_tid_idx; |
| 1452 | /* protect invalid_tids array and invalid_tid_idx */ | 1453 | /* protect invalid_tids array and invalid_tid_idx */ |
| 1453 | spinlock_t invalid_lock; | 1454 | spinlock_t invalid_lock; |
| 1454 | struct mm_struct *mm; | ||
| 1455 | }; | 1455 | }; |
| 1456 | 1456 | ||
| 1457 | extern struct xarray hfi1_dev_table; | 1457 | extern struct xarray hfi1_dev_table; |
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright(c) 2020 Cornelis Networks, Inc. | ||
| 2 | * Copyright(c) 2016 - 2017 Intel Corporation. | 3 | * Copyright(c) 2016 - 2017 Intel Corporation. |
| 3 | * | 4 | * |
| 4 | * This file is provided under a dual BSD/GPLv2 license. When using or | 5 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -48,23 +49,11 @@ · 43 unmodified lines | |||
| 48 | #include <linux/rculist.h> | 49 | #include <linux/rculist.h> |
| 49 | #include <linux/mmu_notifier.h> | 50 | #include <linux/mmu_notifier.h> |
| 50 | #include <linux/interval_tree_generic.h> | 51 | #include <linux/interval_tree_generic.h> |
| 52 | #include <linux/sched/mm.h> | ||
| 51 | 53 | ||
| 52 | #include "mmu_rb.h" | 54 | #include "mmu_rb.h" |
| 53 | #include "trace.h" | 55 | #include "trace.h" |
| 54 | 56 | ||
| 55 | struct mmu_rb_handler { | ||
| 56 | struct mmu_notifier mn; | ||
| 57 | struct rb_root_cached root; | ||
| 58 | void *ops_arg; | ||
| 59 | spinlock_t lock; /* protect the RB tree */ | ||
| 60 | struct mmu_rb_ops *ops; | ||
| 61 | struct mm_struct *mm; | ||
| 62 | struct list_head lru_list; | ||
| 63 | struct work_struct del_work; | ||
| 64 | struct list_head del_list; | ||
| 65 | struct workqueue_struct *wq; | ||
| 66 | }; | ||
| 67 | |||
| 68 | static unsigned long mmu_node_start(struct mmu_rb_node *); | 57 | static unsigned long mmu_node_start(struct mmu_rb_node *); |
| 69 | static unsigned long mmu_node_last(struct mmu_rb_node *); | 58 | static unsigned long mmu_node_last(struct mmu_rb_node *); |
| 70 | static int mmu_notifier_range_start(struct mmu_notifier *, | 59 | static int mmu_notifier_range_start(struct mmu_notifier *, |
| @@ -92,37 +81,36 @@ static unsigned long mmu_node_last(struct mmu_rb_node *node) · 21 unmodified lines | |||
| 92 | return PAGE_ALIGN(node->addr + node->len) - 1; | 81 | return PAGE_ALIGN(node->addr + node->len) - 1; |
| 93 | } | 82 | } |
| 94 | 83 | ||
| 95 | int hfi1_mmu_rb_register(void *ops_arg, struct mm_struct *mm, | 84 | int hfi1_mmu_rb_register(void *ops_arg, |
| 96 | struct mmu_rb_ops *ops, | 85 | struct mmu_rb_ops *ops, |
| 97 | struct workqueue_struct *wq, | 86 | struct workqueue_struct *wq, |
| 98 | struct mmu_rb_handler **handler) | 87 | struct mmu_rb_handler **handler) |
| 99 | { | 88 | { |
| 100 | struct mmu_rb_handler *handlr; | 89 | struct mmu_rb_handler *h; |
| 101 | int ret; | 90 | int ret; |
| 102 | 91 | ||
| 103 | handlr = kmalloc(sizeof(*handlr), GFP_KERNEL); | 92 | h = kmalloc(sizeof(*h), GFP_KERNEL); |
| 104 | if (!handlr) | 93 | if (!h) |
| 105 | return -ENOMEM; | 94 | return -ENOMEM; |
| 106 | 95 | ||
| 107 | handlr->root = RB_ROOT_CACHED; | 96 | h->root = RB_ROOT_CACHED; |
| 108 | handlr->ops = ops; | 97 | h->ops = ops; |
| 109 | handlr->ops_arg = ops_arg; | 98 | h->ops_arg = ops_arg; |
| 110 | INIT_HLIST_NODE(&handlr->mn.hlist); | 99 | INIT_HLIST_NODE(&h->mn.hlist); |
| 111 | spin_lock_init(&handlr->lock); | 100 | spin_lock_init(&h->lock); |
| 112 | handlr->mn.ops = &mn_opts; | 101 | h->mn.ops = &mn_opts; |
| 113 | handlr->mm = mm; | 102 | INIT_WORK(&h->del_work, handle_remove); |
| 114 | INIT_WORK(&handlr->del_work, handle_remove); | 103 | INIT_LIST_HEAD(&h->del_list); |
| 115 | INIT_LIST_HEAD(&handlr->del_list); | 104 | INIT_LIST_HEAD(&h->lru_list); |
| 116 | INIT_LIST_HEAD(&handlr->lru_list); | 105 | h->wq = wq; |
| 117 | handlr->wq = wq; | 106 | |
| 118 | 107 | ret = mmu_notifier_register(&h->mn, current->mm); | |
| 119 | ret = mmu_notifier_register(&handlr->mn, handlr->mm); | ||
| 120 | if (ret) { | 108 | if (ret) { |
| 121 | kfree(handlr); | 109 | kfree(h); |
| 122 | return ret; | 110 | return ret; |
| 123 | } | 111 | } |
| 124 | 112 | ||
| 125 | *handler = handlr; | 113 | *handler = h; |
| 126 | return 0; | 114 | return 0; |
| 127 | } | 115 | } |
| 128 | 116 | ||
| @@ -134,7 +122,7 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler) · 5 unmodified lines | |||
| 134 | struct list_head del_list; | 122 | struct list_head del_list; |
| 135 | 123 | ||
| 136 | /* Unregister first so we don't get any more notifications. */ | 124 | /* Unregister first so we don't get any more notifications. */ |
| 137 | mmu_notifier_unregister(&handler->mn, handler->mm); | 125 | mmu_notifier_unregister(&handler->mn, handler->mn.mm); |
| 138 | 126 | ||
| 139 | /* | 127 | /* |
| 140 | * Make sure the wq delete handler is finished running. It will not | 128 | * Make sure the wq delete handler is finished running. It will not |
| @@ -166,6 +154,10 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, · 25 unmodified lines | |||
| 166 | int ret = 0; | 154 | int ret = 0; |
| 167 | 155 | ||
| 168 | trace_hfi1_mmu_rb_insert(mnode->addr, mnode->len); | 156 | trace_hfi1_mmu_rb_insert(mnode->addr, mnode->len); |
| 157 | |||
| 158 | if (current->mm != handler->mn.mm) | ||
| 159 | return -EPERM; | ||
| 160 | |||
| 169 | spin_lock_irqsave(&handler->lock, flags); | 161 | spin_lock_irqsave(&handler->lock, flags); |
| 170 | node = __mmu_rb_search(handler, mnode->addr, mnode->len); | 162 | node = __mmu_rb_search(handler, mnode->addr, mnode->len); |
| 171 | if (node) { | 163 | if (node) { |
| @@ -180,6 +172,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, · 8 unmodified lines | |||
| 180 | __mmu_int_rb_remove(mnode, &handler->root); | 172 | __mmu_int_rb_remove(mnode, &handler->root); |
| 181 | list_del(&mnode->list); /* remove from LRU list */ | 173 | list_del(&mnode->list); /* remove from LRU list */ |
| 182 | } | 174 | } |
| 175 | mnode->handler = handler; | ||
| 183 | unlock: | 176 | unlock: |
| 184 | spin_unlock_irqrestore(&handler->lock, flags); | 177 | spin_unlock_irqrestore(&handler->lock, flags); |
| 185 | return ret; | 178 | return ret; |
| @@ -217,6 +210,9 @@ bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, · 31 unmodified lines | |||
| 217 | unsigned long flags; | 210 | unsigned long flags; |
| 218 | bool ret = false; | 211 | bool ret = false; |
| 219 | 212 | ||
| 213 | if (current->mm != handler->mn.mm) | ||
| 214 | return ret; | ||
| 215 | |||
| 220 | spin_lock_irqsave(&handler->lock, flags); | 216 | spin_lock_irqsave(&handler->lock, flags); |
| 221 | node = __mmu_rb_search(handler, addr, len); | 217 | node = __mmu_rb_search(handler, addr, len); |
| 222 | if (node) { | 218 | if (node) { |
| @@ -239,6 +235,9 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) · 16 unmodified lines | |||
| 239 | unsigned long flags; | 235 | unsigned long flags; |
| 240 | bool stop = false; | 236 | bool stop = false; |
| 241 | 237 | ||
| 238 | if (current->mm != handler->mn.mm) | ||
| 239 | return; | ||
| 240 | |||
| 242 | INIT_LIST_HEAD(&del_list); | 241 | INIT_LIST_HEAD(&del_list); |
| 243 | 242 | ||
| 244 | spin_lock_irqsave(&handler->lock, flags); | 243 | spin_lock_irqsave(&handler->lock, flags); |
| @@ -272,6 +271,9 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler, · 27 unmodified lines | |||
| 272 | { | 271 | { |
| 273 | unsigned long flags; | 272 | unsigned long flags; |
| 274 | 273 | ||
| 274 | if (current->mm != handler->mn.mm) | ||
| 275 | return; | ||
| 276 | |||
| 275 | /* Validity of handler and node pointers has been checked by caller. */ | 277 | /* Validity of handler and node pointers has been checked by caller. */ |
| 276 | trace_hfi1_mmu_rb_remove(node->addr, node->len); | 278 | trace_hfi1_mmu_rb_remove(node->addr, node->len); |
| 277 | spin_lock_irqsave(&handler->lock, flags); | 279 | spin_lock_irqsave(&handler->lock, flags); |
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright(c) 2020 Cornelis Networks, Inc. | ||
| 2 | * Copyright(c) 2016 Intel Corporation. | 3 | * Copyright(c) 2016 Intel Corporation. |
| 3 | * | 4 | * |
| 4 | * This file is provided under a dual BSD/GPLv2 license. When using or | 5 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -54,6 +55,7 @@ struct mmu_rb_node { · 49 unmodified lines | |||
| 54 | unsigned long len; | 55 | unsigned long len; |
| 55 | unsigned long __last; | 56 | unsigned long __last; |
| 56 | struct rb_node node; | 57 | struct rb_node node; |
| 58 | struct mmu_rb_handler *handler; | ||
| 57 | struct list_head list; | 59 | struct list_head list; |
| 58 | }; | 60 | }; |
| 59 | 61 | ||
| @@ -71,7 +73,19 @@ struct mmu_rb_ops { · 11 unmodified lines | |||
| 71 | void *evict_arg, bool *stop); | 73 | void *evict_arg, bool *stop); |
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | int hfi1_mmu_rb_register(void *ops_arg, struct mm_struct *mm, | 76 | struct mmu_rb_handler { |
| 77 | struct mmu_notifier mn; | ||
| 78 | struct rb_root_cached root; | ||
| 79 | void *ops_arg; | ||
| 80 | spinlock_t lock; /* protect the RB tree */ | ||
| 81 | struct mmu_rb_ops *ops; | ||
| 82 | struct list_head lru_list; | ||
| 83 | struct work_struct del_work; | ||
| 84 | struct list_head del_list; | ||
| 85 | struct workqueue_struct *wq; | ||
| 86 | }; | ||
| 87 | |||
| 88 | int hfi1_mmu_rb_register(void *ops_arg, | ||
| 75 | struct mmu_rb_ops *ops, | 89 | struct mmu_rb_ops *ops, |
| 76 | struct workqueue_struct *wq, | 90 | struct workqueue_struct *wq, |
| 77 | struct mmu_rb_handler **handler); | 91 | struct mmu_rb_handler **handler); |
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright(c) 2020 Cornelis Networks, Inc. | ||
| 2 | * Copyright(c) 2015-2018 Intel Corporation. | 3 | * Copyright(c) 2015-2018 Intel Corporation. |
| 3 | * | 4 | * |
| 4 | * This file is provided under a dual BSD/GPLv2 license. When using or | 5 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -173,15 +174,18 @@ static void unpin_rcv_pages(struct hfi1_filedata *fd, · 168 unmodified lines | |||
| 173 | { | 174 | { |
| 174 | struct page **pages; | 175 | struct page **pages; |
| 175 | struct hfi1_devdata *dd = fd->uctxt->dd; | 176 | struct hfi1_devdata *dd = fd->uctxt->dd; |
| 177 | struct mm_struct *mm; | ||
| 176 | 178 | ||
| 177 | if (mapped) { | 179 | if (mapped) { |
| 178 | pci_unmap_single(dd->pcidev, node->dma_addr, | 180 | pci_unmap_single(dd->pcidev, node->dma_addr, |
| 179 | node->npages * PAGE_SIZE, PCI_DMA_FROMDEVICE); | 181 | node->npages * PAGE_SIZE, PCI_DMA_FROMDEVICE); |
| 180 | pages = &node->pages[idx]; | 182 | pages = &node->pages[idx]; |
| 183 | mm = mm_from_tid_node(node); | ||
| 181 | } else { | 184 | } else { |
| 182 | pages = &tidbuf->pages[idx]; | 185 | pages = &tidbuf->pages[idx]; |
| 186 | mm = current->mm; | ||
| 183 | } | 187 | } |
| 184 | hfi1_release_user_pages(fd->mm, pages, npages, mapped); | 188 | hfi1_release_user_pages(mm, pages, npages, mapped); |
| 185 | fd->tid_n_pinned -= npages; | 189 | fd->tid_n_pinned -= npages; |
| 186 | } | 190 | } |
| 187 | 191 | ||
| @@ -216,12 +220,12 @@ static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf) · 28 unmodified lines | |||
| 216 | * pages, accept the amount pinned so far and program only that. | 220 | * pages, accept the amount pinned so far and program only that. |
| 217 | * User space knows how to deal with partially programmed buffers. | 221 | * User space knows how to deal with partially programmed buffers. |
| 218 | */ | 222 | */ |
| 219 | if (!hfi1_can_pin_pages(dd, fd->mm, fd->tid_n_pinned, npages)) { | 223 | if (!hfi1_can_pin_pages(dd, current->mm, fd->tid_n_pinned, npages)) { |
| 220 | kfree(pages); | 224 | kfree(pages); |
| 221 | return -ENOMEM; | 225 | return -ENOMEM; |
| 222 | } | 226 | } |
| 223 | 227 | ||
| 224 | pinned = hfi1_acquire_user_pages(fd->mm, vaddr, npages, true, pages); | 228 | pinned = hfi1_acquire_user_pages(current->mm, vaddr, npages, true, pages); |
| 225 | if (pinned <= 0) { | 229 | if (pinned <= 0) { |
| 226 | kfree(pages); | 230 | kfree(pages); |
| 227 | return pinned; | 231 | return pinned; |
| @@ -756,7 +760,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd, · 528 unmodified lines | |||
| 756 | 760 | ||
| 757 | if (fd->use_mn) { | 761 | if (fd->use_mn) { |
| 758 | ret = mmu_interval_notifier_insert( | 762 | ret = mmu_interval_notifier_insert( |
| 759 | &node->notifier, fd->mm, | 763 | &node->notifier, current->mm, |
| 760 | tbuf->vaddr + (pageidx * PAGE_SIZE), npages * PAGE_SIZE, | 764 | tbuf->vaddr + (pageidx * PAGE_SIZE), npages * PAGE_SIZE, |
| 761 | &tid_mn_ops); | 765 | &tid_mn_ops); |
| 762 | if (ret) | 766 | if (ret) |
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _HFI1_USER_EXP_RCV_H | 1 | #ifndef _HFI1_USER_EXP_RCV_H |
| 2 | #define _HFI1_USER_EXP_RCV_H | 2 | #define _HFI1_USER_EXP_RCV_H |
| 3 | /* | 3 | /* |
| 4 | * Copyright(c) 2020 - Cornelis Networks, Inc. | ||
| 4 | * Copyright(c) 2015 - 2017 Intel Corporation. | 5 | * Copyright(c) 2015 - 2017 Intel Corporation. |
| 5 | * | 6 | * |
| 6 | * This file is provided under a dual BSD/GPLv2 license. When using or | 7 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -95,4 +96,9 @@ int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd, · 88 unmodified lines | |||
| 95 | int hfi1_user_exp_rcv_invalid(struct hfi1_filedata *fd, | 96 | int hfi1_user_exp_rcv_invalid(struct hfi1_filedata *fd, |
| 96 | struct hfi1_tid_info *tinfo); | 97 | struct hfi1_tid_info *tinfo); |
| 97 | 98 | ||
| 99 | static inline struct mm_struct *mm_from_tid_node(struct tid_rb_node *node) | ||
| 100 | { | ||
| 101 | return node->notifier.mm; | ||
| 102 | } | ||
| 103 | |||
| 98 | #endif /* _HFI1_USER_EXP_RCV_H */ | 104 | #endif /* _HFI1_USER_EXP_RCV_H */ |
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright(c) 2020 - Cornelis Networks, Inc. | ||
| 2 | * Copyright(c) 2015 - 2018 Intel Corporation. | 3 | * Copyright(c) 2015 - 2018 Intel Corporation. |
| 3 | * | 4 | * |
| 4 | * This file is provided under a dual BSD/GPLv2 license. When using or | 5 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -188,7 +189,6 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, · 183 unmodified lines | |||
| 188 | atomic_set(&pq->n_reqs, 0); | 189 | atomic_set(&pq->n_reqs, 0); |
| 189 | init_waitqueue_head(&pq->wait); | 190 | init_waitqueue_head(&pq->wait); |
| 190 | atomic_set(&pq->n_locked, 0); | 191 | atomic_set(&pq->n_locked, 0); |
| 191 | pq->mm = fd->mm; | ||
| 192 | 192 | ||
| 193 | iowait_init(&pq->busy, 0, NULL, NULL, defer_packet_queue, | 193 | iowait_init(&pq->busy, 0, NULL, NULL, defer_packet_queue, |
| 194 | activate_packet_queue, NULL, NULL); | 194 | activate_packet_queue, NULL, NULL); |
| @@ -230,7 +230,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, · 35 unmodified lines | |||
| 230 | 230 | ||
| 231 | cq->nentries = hfi1_sdma_comp_ring_size; | 231 | cq->nentries = hfi1_sdma_comp_ring_size; |
| 232 | 232 | ||
| 233 | ret = hfi1_mmu_rb_register(pq, pq->mm, &sdma_rb_ops, dd->pport->hfi1_wq, | 233 | ret = hfi1_mmu_rb_register(pq, &sdma_rb_ops, dd->pport->hfi1_wq, |
| 234 | &pq->handler); | 234 | &pq->handler); |
| 235 | if (ret) { | 235 | if (ret) { |
| 236 | dd_dev_err(dd, "Failed to register with MMU %d", ret); | 236 | dd_dev_err(dd, "Failed to register with MMU %d", ret); |
| @@ -980,13 +980,13 @@ static int pin_sdma_pages(struct user_sdma_request *req, · 743 unmodified lines | |||
| 980 | 980 | ||
| 981 | npages -= node->npages; | 981 | npages -= node->npages; |
| 982 | retry: | 982 | retry: |
| 983 | if (!hfi1_can_pin_pages(pq->dd, pq->mm, | 983 | if (!hfi1_can_pin_pages(pq->dd, current->mm, |
| 984 | atomic_read(&pq->n_locked), npages)) { | 984 | atomic_read(&pq->n_locked), npages)) { |
| 985 | cleared = sdma_cache_evict(pq, npages); | 985 | cleared = sdma_cache_evict(pq, npages); |
| 986 | if (cleared >= npages) | 986 | if (cleared >= npages) |
| 987 | goto retry; | 987 | goto retry; |
| 988 | } | 988 | } |
| 989 | pinned = hfi1_acquire_user_pages(pq->mm, | 989 | pinned = hfi1_acquire_user_pages(current->mm, |
| 990 | ((unsigned long)iovec->iov.iov_base + | 990 | ((unsigned long)iovec->iov.iov_base + |
| 991 | (node->npages * PAGE_SIZE)), npages, 0, | 991 | (node->npages * PAGE_SIZE)), npages, 0, |
| 992 | pages + node->npages); | 992 | pages + node->npages); |
| @@ -995,7 +995,7 @@ retry: · 2 unmodified lines | |||
| 995 | return pinned; | 995 | return pinned; |
| 996 | } | 996 | } |
| 997 | if (pinned != npages) { | 997 | if (pinned != npages) { |
| 998 | unpin_vector_pages(pq->mm, pages, node->npages, pinned); | 998 | unpin_vector_pages(current->mm, pages, node->npages, pinned); |
| 999 | return -EFAULT; | 999 | return -EFAULT; |
| 1000 | } | 1000 | } |
| 1001 | kfree(node->pages); | 1001 | kfree(node->pages); |
| @@ -1008,7 +1008,8 @@ retry: · 6 unmodified lines | |||
| 1008 | static void unpin_sdma_pages(struct sdma_mmu_node *node) | 1008 | static void unpin_sdma_pages(struct sdma_mmu_node *node) |
| 1009 | { | 1009 | { |
| 1010 | if (node->npages) { | 1010 | if (node->npages) { |
| 1011 | unpin_vector_pages(node->pq->mm, node->pages, 0, node->npages); | 1011 | unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0, |
| 1012 | node->npages); | ||
| 1012 | atomic_sub(node->npages, &node->pq->n_locked); | 1013 | atomic_sub(node->npages, &node->pq->n_locked); |
| 1013 | } | 1014 | } |
| 1014 | } | 1015 | } |
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _HFI1_USER_SDMA_H | 1 | #ifndef _HFI1_USER_SDMA_H |
| 2 | #define _HFI1_USER_SDMA_H | 2 | #define _HFI1_USER_SDMA_H |
| 3 | /* | 3 | /* |
| 4 | * Copyright(c) 2020 - Cornelis Networks, Inc. | ||
| 4 | * Copyright(c) 2015 - 2018 Intel Corporation. | 5 | * Copyright(c) 2015 - 2018 Intel Corporation. |
| 5 | * | 6 | * |
| 6 | * This file is provided under a dual BSD/GPLv2 license. When using or | 7 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| @@ -133,7 +134,6 @@ struct hfi1_user_sdma_pkt_q { · 126 unmodified lines | |||
| 133 | unsigned long unpinned; | 134 | unsigned long unpinned; |
| 134 | struct mmu_rb_handler *handler; | 135 | struct mmu_rb_handler *handler; |
| 135 | atomic_t n_locked; | 136 | atomic_t n_locked; |
| 136 | struct mm_struct *mm; | ||
| 137 | }; | 137 | }; |
| 138 | 138 | ||
| 139 | struct hfi1_user_sdma_comp_q { | 139 | struct hfi1_user_sdma_comp_q { |
| @@ -250,4 +250,9 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, · 110 unmodified lines | |||
| 250 | struct iovec *iovec, unsigned long dim, | 250 | struct iovec *iovec, unsigned long dim, |
| 251 | unsigned long *count); | 251 | unsigned long *count); |
| 252 | 252 | ||
| 253 | static inline struct mm_struct *mm_from_sdma_node(struct sdma_mmu_node *node) | ||
| 254 | { | ||
| 255 | return node->rb.handler->mn.mm; | ||
| 256 | } | ||
| 257 | |||
| 253 | #endif /* _HFI1_USER_SDMA_H */ | 258 | #endif /* _HFI1_USER_SDMA_H */ |
| @@ -2936,6 +2936,7 @@ static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw) · 2935 unmodified lines | |||
| 2936 | 2936 | ||
| 2937 | roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1); | 2937 | roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1); |
| 2938 | roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1); | 2938 | roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1); |
| 2939 | roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S, 1); | ||
| 2939 | 2940 | ||
| 2940 | roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0); | 2941 | roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0); |
| 2941 | roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 1); | 2942 | roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 1); |
| @@ -4989,11 +4990,11 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, · 2047 unmodified lines | |||
| 4989 | V2_QPC_BYTE_28_AT_M, | 4990 | V2_QPC_BYTE_28_AT_M, |
| 4990 | V2_QPC_BYTE_28_AT_S); | 4991 | V2_QPC_BYTE_28_AT_S); |
| 4991 | qp_attr->retry_cnt = roce_get_field(context.byte_212_lsn, | 4992 | qp_attr->retry_cnt = roce_get_field(context.byte_212_lsn, |
| 4992 | V2_QPC_BYTE_212_RETRY_CNT_M, | 4993 | V2_QPC_BYTE_212_RETRY_NUM_INIT_M, |
| 4993 | V2_QPC_BYTE_212_RETRY_CNT_S); | 4994 | V2_QPC_BYTE_212_RETRY_NUM_INIT_S); |
| 4994 | qp_attr->rnr_retry = roce_get_field(context.byte_244_rnr_rxack, | 4995 | qp_attr->rnr_retry = roce_get_field(context.byte_244_rnr_rxack, |
| 4995 | V2_QPC_BYTE_244_RNR_CNT_M, | 4996 | V2_QPC_BYTE_244_RNR_NUM_INIT_M, |
| 4996 | V2_QPC_BYTE_244_RNR_CNT_S); | 4997 | V2_QPC_BYTE_244_RNR_NUM_INIT_S); |
| 4997 | 4998 | ||
| 4998 | done: | 4999 | done: |
| 4999 | qp_attr->cur_qp_state = qp_attr->qp_state; | 5000 | qp_attr->cur_qp_state = qp_attr->qp_state; |
| @@ -1661,7 +1661,7 @@ struct hns_roce_query_pf_caps_d { · 1660 unmodified lines | |||
| 1661 | __le32 rsv_uars_rsv_qps; | 1661 | __le32 rsv_uars_rsv_qps; |
| 1662 | }; | 1662 | }; |
| 1663 | #define V2_QUERY_PF_CAPS_D_NUM_SRQS_S 0 | 1663 | #define V2_QUERY_PF_CAPS_D_NUM_SRQS_S 0 |
| 1664 | #define V2_QUERY_PF_CAPS_D_NUM_SRQS_M GENMASK(20, 0) | 1664 | #define V2_QUERY_PF_CAPS_D_NUM_SRQS_M GENMASK(19, 0) |
| 1665 | 1665 | ||
| 1666 | #define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_S 20 | 1666 | #define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_S 20 |
| 1667 | #define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_M GENMASK(21, 20) | 1667 | #define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_M GENMASK(21, 20) |
| @@ -54,10 +54,6 @@ · 53 unmodified lines | |||
| 54 | #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ | 54 | #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ |
| 55 | __stringify(DRV_VERSION_MINOR) "." __stringify(DRV_VERSION_BUILD) | 55 | __stringify(DRV_VERSION_MINOR) "." __stringify(DRV_VERSION_BUILD) |
| 56 | 56 | ||
| 57 | static int push_mode; | ||
| 58 | module_param(push_mode, int, 0644); | ||
| 59 | MODULE_PARM_DESC(push_mode, "Low latency mode: 0=disabled (default), 1=enabled)"); | ||
| 60 | |||
| 61 | static int debug; | 57 | static int debug; |
| 62 | module_param(debug, int, 0644); | 58 | module_param(debug, int, 0644); |
| 63 | MODULE_PARM_DESC(debug, "debug flags: 0=disabled (default), 0x7fffffff=all"); | 59 | MODULE_PARM_DESC(debug, "debug flags: 0=disabled (default), 0x7fffffff=all"); |
| @@ -1580,7 +1576,6 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl, · 1516 unmodified lines | |||
| 1580 | if (status) | 1576 | if (status) |
| 1581 | goto exit; | 1577 | goto exit; |
| 1582 | iwdev->obj_next = iwdev->obj_mem; | 1578 | iwdev->obj_next = iwdev->obj_mem; |
| 1583 | iwdev->push_mode = push_mode; | ||
| 1584 | 1579 | ||
| 1585 | init_waitqueue_head(&iwdev->vchnl_waitq); | 1580 | init_waitqueue_head(&iwdev->vchnl_waitq); |
| 1586 | init_waitqueue_head(&dev->vf_reqs); | 1581 | init_waitqueue_head(&dev->vf_reqs); |
| @@ -167,39 +167,16 @@ static void i40iw_dealloc_ucontext(struct ib_ucontext *context) · 166 unmodified lines | |||
| 167 | */ | 167 | */ |
| 168 | static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | 168 | static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) |
| 169 | { | 169 | { |
| 170 | struct i40iw_ucontext *ucontext; | 170 | struct i40iw_ucontext *ucontext = to_ucontext(context); |
| 171 | u64 db_addr_offset, push_offset, pfn; | 171 | u64 dbaddr; |
| 172 | |||
| 173 | ucontext = to_ucontext(context); | ||
| 174 | if (ucontext->iwdev->sc_dev.is_pf) { | ||
| 175 | db_addr_offset = I40IW_DB_ADDR_OFFSET; | ||
| 176 | push_offset = I40IW_PUSH_OFFSET; | ||
| 177 | if (vma->vm_pgoff) | ||
| 178 | vma->vm_pgoff += I40IW_PF_FIRST_PUSH_PAGE_INDEX - 1; | ||
| 179 | } else { | ||
| 180 | db_addr_offset = I40IW_VF_DB_ADDR_OFFSET; | ||
| 181 | push_offset = I40IW_VF_PUSH_OFFSET; | ||
| 182 | if (vma->vm_pgoff) | ||
| 183 | vma->vm_pgoff += I40IW_VF_FIRST_PUSH_PAGE_INDEX - 1; | ||
| 184 | } | ||
| 185 | 172 | ||
| 186 | vma->vm_pgoff += db_addr_offset >> PAGE_SHIFT; | 173 | if (vma->vm_pgoff || vma->vm_end - vma->vm_start != PAGE_SIZE) |
| 187 | 174 | return -EINVAL; | |
| 188 | if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { | ||
| 189 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 190 | } else { | ||
| 191 | if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) | ||
| 192 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 193 | else | ||
| 194 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | ||
| 195 | } | ||
| 196 | 175 | ||
| 197 | pfn = vma->vm_pgoff + | 176 | dbaddr = I40IW_DB_ADDR_OFFSET + pci_resource_start(ucontext->iwdev->ldev->pcidev, 0); |
| 198 | (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> | ||
| 199 | PAGE_SHIFT); | ||
| 200 | 177 | ||
| 201 | return rdma_user_mmap_io(context, vma, pfn, PAGE_SIZE, | 178 | return rdma_user_mmap_io(context, vma, dbaddr >> PAGE_SHIFT, PAGE_SIZE, |
| 202 | vma->vm_page_prot, NULL); | 179 | pgprot_noncached(vma->vm_page_prot), NULL); |
| 203 | } | 180 | } |
| 204 | 181 | ||
| 205 | /** | 182 | /** |
| @@ -803,8 +803,10 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, · 802 unmodified lines | |||
| 803 | } | 803 | } |
| 804 | 804 | ||
| 805 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | 805 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
| 806 | if (IS_ERR(mailbox)) | 806 | if (IS_ERR(mailbox)) { |
| 807 | err = PTR_ERR(mailbox); | ||
| 807 | goto err_out_arm; | 808 | goto err_out_arm; |
| 809 | } | ||
| 808 | 810 | ||
| 809 | cq_context = mailbox->buf; | 811 | cq_context = mailbox->buf; |
| 810 | 812 | ||
| @@ -846,9 +848,9 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, · 35 unmodified lines | |||
| 846 | } | 848 | } |
| 847 | 849 | ||
| 848 | spin_lock_irq(&dev->cq_table.lock); | 850 | spin_lock_irq(&dev->cq_table.lock); |
| 849 | if (mthca_array_set(&dev->cq_table.cq, | 851 | err = mthca_array_set(&dev->cq_table.cq, |
| 850 | cq->cqn & (dev->limits.num_cqs - 1), | 852 | cq->cqn & (dev->limits.num_cqs - 1), cq); |
| 851 | cq)) { | 853 | if (err) { |
| 852 | spin_unlock_irq(&dev->cq_table.lock); | 854 | spin_unlock_irq(&dev->cq_table.lock); |
| 853 | goto err_out_free_mr; | 855 | goto err_out_free_mr; |
| 854 | } | 856 | } |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include <asm/iommu_table.h> | 29 | #include <asm/iommu_table.h> |
| 30 | #include <asm/io_apic.h> | 30 | #include <asm/io_apic.h> |
| 31 | #include <asm/irq_remapping.h> | 31 | #include <asm/irq_remapping.h> |
| 32 | #include <asm/set_memory.h> | ||
| 32 | 33 | ||
| 33 | #include <linux/crash_dump.h> | 34 | #include <linux/crash_dump.h> |
| 34 | 35 | ||
| @@ -672,11 +673,27 @@ static void __init free_command_buffer(struct amd_iommu *iommu) · 637 unmodified lines | |||
| 672 | free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE)); | 673 | free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE)); |
| 673 | } | 674 | } |
| 674 | 675 | ||
| 676 | static void *__init iommu_alloc_4k_pages(struct amd_iommu *iommu, | ||
| 677 | gfp_t gfp, size_t size) | ||
| 678 | { | ||
| 679 | int order = get_order(size); | ||
| 680 | void *buf = (void *)__get_free_pages(gfp, order); | ||
| 681 | |||
| 682 | if (buf && | ||
| 683 | iommu_feature(iommu, FEATURE_SNP) && | ||
| 684 | set_memory_4k((unsigned long)buf, (1 << order))) { | ||
| 685 | free_pages((unsigned long)buf, order); | ||
| 686 | buf = NULL; | ||
| 687 | } | ||
| 688 | |||
| 689 | return buf; | ||
| 690 | } | ||
| 691 | |||
| 675 | /* allocates the memory where the IOMMU will log its events to */ | 692 | /* allocates the memory where the IOMMU will log its events to */ |
| 676 | static int __init alloc_event_buffer(struct amd_iommu *iommu) | 693 | static int __init alloc_event_buffer(struct amd_iommu *iommu) |
| 677 | { | 694 | { |
| 678 | iommu->evt_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | 695 | iommu->evt_buf = iommu_alloc_4k_pages(iommu, GFP_KERNEL | __GFP_ZERO, |
| 679 | get_order(EVT_BUFFER_SIZE)); | 696 | EVT_BUFFER_SIZE); |
| 680 | 697 | ||
| 681 | return iommu->evt_buf ? 0 : -ENOMEM; | 698 | return iommu->evt_buf ? 0 : -ENOMEM; |
| 682 | } | 699 | } |
| @@ -715,8 +732,8 @@ static void __init free_event_buffer(struct amd_iommu *iommu) · 32 unmodified lines | |||
| 715 | /* allocates the memory where the IOMMU will log its events to */ | 732 | /* allocates the memory where the IOMMU will log its events to */ |
| 716 | static int __init alloc_ppr_log(struct amd_iommu *iommu) | 733 | static int __init alloc_ppr_log(struct amd_iommu *iommu) |
| 717 | { | 734 | { |
| 718 | iommu->ppr_log = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | 735 | iommu->ppr_log = iommu_alloc_4k_pages(iommu, GFP_KERNEL | __GFP_ZERO, |
| 719 | get_order(PPR_LOG_SIZE)); | 736 | PPR_LOG_SIZE); |
| 720 | 737 | ||
| 721 | return iommu->ppr_log ? 0 : -ENOMEM; | 738 | return iommu->ppr_log ? 0 : -ENOMEM; |
| 722 | } | 739 | } |
| @@ -838,7 +855,7 @@ static int iommu_init_ga(struct amd_iommu *iommu) · 115 unmodified lines | |||
| 838 | 855 | ||
| 839 | static int __init alloc_cwwb_sem(struct amd_iommu *iommu) | 856 | static int __init alloc_cwwb_sem(struct amd_iommu *iommu) |
| 840 | { | 857 | { |
| 841 | iommu->cmd_sem = (void *)get_zeroed_page(GFP_KERNEL); | 858 | iommu->cmd_sem = iommu_alloc_4k_pages(iommu, GFP_KERNEL | __GFP_ZERO, 1); |
| 842 | 859 | ||
| 843 | return iommu->cmd_sem ? 0 : -ENOMEM; | 860 | return iommu->cmd_sem ? 0 : -ENOMEM; |
| 844 | } | 861 | } |
| @@ -69,6 +69,10 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu) · 68 unmodified lines | |||
| 69 | { | 69 | { |
| 70 | struct qcom_smmu *qsmmu; | 70 | struct qcom_smmu *qsmmu; |
| 71 | 71 | ||
| 72 | /* Check to make sure qcom_scm has finished probing */ | ||
| 73 | if (!qcom_scm_is_available()) | ||
| 74 | return ERR_PTR(-EPROBE_DEFER); | ||
| 75 | |||
| 72 | qsmmu = devm_kzalloc(smmu->dev, sizeof(*qsmmu), GFP_KERNEL); | 76 | qsmmu = devm_kzalloc(smmu->dev, sizeof(*qsmmu), GFP_KERNEL); |
| 73 | if (!qsmmu) | 77 | if (!qsmmu) |
| 74 | return ERR_PTR(-ENOMEM); | 78 | return ERR_PTR(-ENOMEM); |
| @@ -335,7 +335,9 @@ static void dmar_pci_bus_del_dev(struct dmar_pci_notify_info *info) · 334 unmodified lines | |||
| 335 | 335 | ||
| 336 | static inline void vf_inherit_msi_domain(struct pci_dev *pdev) | 336 | static inline void vf_inherit_msi_domain(struct pci_dev *pdev) |
| 337 | { | 337 | { |
| 338 | dev_set_msi_domain(&pdev->dev, dev_get_msi_domain(&pdev->physfn->dev)); | 338 | struct pci_dev *physfn = pci_physfn(pdev); |
| 339 | |||
| 340 | dev_set_msi_domain(&pdev->dev, dev_get_msi_domain(&physfn->dev)); | ||
| 339 | } | 341 | } |
| 340 | 342 | ||
| 341 | static int dmar_pci_bus_notifier(struct notifier_block *nb, | 343 | static int dmar_pci_bus_notifier(struct notifier_block *nb, |
| @@ -984,7 +986,8 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) · 642 unmodified lines | |||
| 984 | warn_invalid_dmar(phys_addr, " returns all ones"); | 986 | warn_invalid_dmar(phys_addr, " returns all ones"); |
| 985 | goto unmap; | 987 | goto unmap; |
| 986 | } | 988 | } |
| 987 | iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG); | 989 | if (ecap_vcs(iommu->ecap)) |
| 990 | iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG); | ||
| 988 | 991 | ||
| 989 | /* the registers might be more than one page */ | 992 | /* the registers might be more than one page */ |
| 990 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), | 993 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), |
| @@ -179,7 +179,7 @@ static int rwbf_quirk; · 178 unmodified lines | |||
| 179 | * (used when kernel is launched w/ TXT) | 179 | * (used when kernel is launched w/ TXT) |
| 180 | */ | 180 | */ |
| 181 | static int force_on = 0; | 181 | static int force_on = 0; |
| 182 | int intel_iommu_tboot_noforce; | 182 | static int intel_iommu_tboot_noforce; |
| 183 | static int no_platform_optin; | 183 | static int no_platform_optin; |
| 184 | 184 | ||
| 185 | #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) | 185 | #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) |
| @@ -1833,7 +1833,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu) · 1647 unmodified lines | |||
| 1833 | if (ecap_prs(iommu->ecap)) | 1833 | if (ecap_prs(iommu->ecap)) |
| 1834 | intel_svm_finish_prq(iommu); | 1834 | intel_svm_finish_prq(iommu); |
| 1835 | } | 1835 | } |
| 1836 | if (ecap_vcs(iommu->ecap) && vccap_pasid(iommu->vccap)) | 1836 | if (vccap_pasid(iommu->vccap)) |
| 1837 | ioasid_unregister_allocator(&iommu->pasid_allocator); | 1837 | ioasid_unregister_allocator(&iommu->pasid_allocator); |
| 1838 | 1838 | ||
| 1839 | #endif | 1839 | #endif |
| @@ -3212,7 +3212,7 @@ static void register_pasid_allocator(struct intel_iommu *iommu) · 1372 unmodified lines | |||
| 3212 | * is active. All vIOMMU allocators will eventually be calling the same | 3212 | * is active. All vIOMMU allocators will eventually be calling the same |
| 3213 | * host allocator. | 3213 | * host allocator. |
| 3214 | */ | 3214 | */ |
| 3215 | if (!ecap_vcs(iommu->ecap) || !vccap_pasid(iommu->vccap)) | 3215 | if (!vccap_pasid(iommu->vccap)) |
| 3216 | return; | 3216 | return; |
| 3217 | 3217 | ||
| 3218 | pr_info("Register custom PASID allocator\n"); | 3218 | pr_info("Register custom PASID allocator\n"); |
| @@ -4884,7 +4884,8 @@ int __init intel_iommu_init(void) · 1665 unmodified lines | |||
| 4884 | * Intel IOMMU is required for a TXT/tboot launch or platform | 4884 | * Intel IOMMU is required for a TXT/tboot launch or platform |
| 4885 | * opt in, so enforce that. | 4885 | * opt in, so enforce that. |
| 4886 | */ | 4886 | */ |
| 4887 | force_on = tboot_force_iommu() || platform_optin_force_iommu(); | 4887 | force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) || |
| 4888 | platform_optin_force_iommu(); | ||
| 4888 | 4889 | ||
| 4889 | if (iommu_init_mempool()) { | 4890 | if (iommu_init_mempool()) { |
| 4890 | if (force_on) | 4891 | if (force_on) |
| @@ -264,16 +264,18 @@ int iommu_probe_device(struct device *dev) · 263 unmodified lines | |||
| 264 | */ | 264 | */ |
| 265 | iommu_alloc_default_domain(group, dev); | 265 | iommu_alloc_default_domain(group, dev); |
| 266 | 266 | ||
| 267 | if (group->default_domain) | 267 | if (group->default_domain) { |
| 268 | ret = __iommu_attach_device(group->default_domain, dev); | 268 | ret = __iommu_attach_device(group->default_domain, dev); |
| 269 | if (ret) { | ||
| 270 | iommu_group_put(group); | ||
| 271 | goto err_release; | ||
| 272 | } | ||
| 273 | } | ||
| 269 | 274 | ||
| 270 | iommu_create_device_direct_mappings(group, dev); | 275 | iommu_create_device_direct_mappings(group, dev); |
| 271 | 276 | ||
| 272 | iommu_group_put(group); | 277 | iommu_group_put(group); |
| 273 | 278 | ||
| 274 | if (ret) | ||
| 275 | goto err_release; | ||
| 276 | |||
| 277 | if (ops->probe_finalize) | 279 | if (ops->probe_finalize) |
| 278 | ops->probe_finalize(dev); | 280 | ops->probe_finalize(dev); |
| 279 | 281 | ||
| @@ -253,17 +253,31 @@ config VIDEO_MEDIATEK_VCODEC · 252 unmodified lines | |||
| 253 | depends on MTK_IOMMU || COMPILE_TEST | 253 | depends on MTK_IOMMU || COMPILE_TEST |
| 254 | depends on VIDEO_DEV && VIDEO_V4L2 | 254 | depends on VIDEO_DEV && VIDEO_V4L2 |
| 255 | depends on ARCH_MEDIATEK || COMPILE_TEST | 255 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 256 | depends on VIDEO_MEDIATEK_VPU || MTK_SCP | ||
| 257 | # The two following lines ensure we have the same state ("m" or "y") as | ||
| 258 | # our dependencies, to avoid missing symbols during link. | ||
| 259 | depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU | ||
| 260 | depends on MTK_SCP || !MTK_SCP | ||
| 256 | select VIDEOBUF2_DMA_CONTIG | 261 | select VIDEOBUF2_DMA_CONTIG |
| 257 | select V4L2_MEM2MEM_DEV | 262 | select V4L2_MEM2MEM_DEV |
| 258 | select VIDEO_MEDIATEK_VPU | 263 | select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU |
| 259 | select MTK_SCP | 264 | select VIDEO_MEDIATEK_VCODEC_SCP if MTK_SCP |
| 260 | help | 265 | help |
| 261 | Mediatek video codec driver provides HW capability to | 266 | Mediatek video codec driver provides HW capability to |
| 262 | encode and decode in a range of video formats | 267 | encode and decode in a range of video formats on MT8173 |
| 263 | This driver rely on VPU driver to communicate with VPU. | 268 | and MT8183. |
| 269 | |||
| 270 | Note that support for MT8173 requires VIDEO_MEDIATEK_VPU to | ||
| 271 | also be selected. Support for MT8183 depends on MTK_SCP. | ||
| 272 | |||
| 273 | To compile this driver as modules, choose M here: the | ||
| 274 | modules will be called mtk-vcodec-dec and mtk-vcodec-enc. | ||
| 275 | |||
| 276 | config VIDEO_MEDIATEK_VCODEC_VPU | ||
| 277 | bool | ||
| 264 | 278 | ||
| 265 | To compile this driver as modules, choose M here: the | 279 | config VIDEO_MEDIATEK_VCODEC_SCP |
| 266 | modules will be called mtk-vcodec-dec and mtk-vcodec-enc. | 280 | bool |
| 267 | 281 | ||
| 268 | config VIDEO_MEM2MEM_DEINTERLACE | 282 | config VIDEO_MEM2MEM_DEINTERLACE |
| 269 | tristate "Deinterlace support" | 283 | tristate "Deinterlace support" |
| @@ -307,6 +307,7 @@ static int mmpcam_platform_remove(struct platform_device *pdev) · 306 unmodified lines | |||
| 307 | * Suspend/resume support. | 307 | * Suspend/resume support. |
| 308 | */ | 308 | */ |
| 309 | 309 | ||
| 310 | #ifdef CONFIG_PM | ||
| 310 | static int mmpcam_runtime_resume(struct device *dev) | 311 | static int mmpcam_runtime_resume(struct device *dev) |
| 311 | { | 312 | { |
| 312 | struct mmp_camera *cam = dev_get_drvdata(dev); | 313 | struct mmp_camera *cam = dev_get_drvdata(dev); |
| @@ -352,6 +353,7 @@ static int __maybe_unused mmpcam_resume(struct device *dev) · 39 unmodified lines | |||
| 352 | return mccic_resume(&cam->mcam); | 353 | return mccic_resume(&cam->mcam); |
| 353 | return 0; | 354 | return 0; |
| 354 | } | 355 | } |
| 356 | #endif | ||
| 355 | 357 | ||
| 356 | static const struct dev_pm_ops mmpcam_pm_ops = { | 358 | static const struct dev_pm_ops mmpcam_pm_ops = { |
| 357 | SET_RUNTIME_PM_OPS(mmpcam_runtime_suspend, mmpcam_runtime_resume, NULL) | 359 | SET_RUNTIME_PM_OPS(mmpcam_runtime_suspend, mmpcam_runtime_resume, NULL) |
| @@ -24,4 +24,12 @@ mtk-vcodec-enc-y := venc/venc_vp8_if.o \ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | mtk-vcodec-common-y := mtk_vcodec_intr.o \ | 25 | mtk-vcodec-common-y := mtk_vcodec_intr.o \ |
| 26 | mtk_vcodec_util.o \ | 26 | mtk_vcodec_util.o \ |
| 27 | mtk_vcodec_fw.o | 27 | mtk_vcodec_fw.o \ |
| 28 | |||
| 29 | ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU),) | ||
| 30 | mtk-vcodec-common-y += mtk_vcodec_fw_vpu.o | ||
| 31 | endif | ||
| 32 | |||
| 33 | ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP),) | ||
| 34 | mtk-vcodec-common-y += mtk_vcodec_fw_scp.o | ||
| 35 | endif | ||
| @@ -241,7 +241,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) · 240 unmodified lines | |||
| 241 | } | 241 | } |
| 242 | dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); | 242 | dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); |
| 243 | 243 | ||
| 244 | dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, VPU_RST_DEC); | 244 | dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER); |
| 245 | if (IS_ERR(dev->fw_handler)) | 245 | if (IS_ERR(dev->fw_handler)) |
| 246 | return PTR_ERR(dev->fw_handler); | 246 | return PTR_ERR(dev->fw_handler); |
| 247 | 247 | ||
| @@ -293,7 +293,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) · 292 unmodified lines | |||
| 293 | } | 293 | } |
| 294 | dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); | 294 | dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); |
| 295 | 295 | ||
| 296 | dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, VPU_RST_ENC); | 296 | dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, ENCODER); |
| 297 | if (IS_ERR(dev->fw_handler)) | 297 | if (IS_ERR(dev->fw_handler)) |
| 298 | return PTR_ERR(dev->fw_handler); | 298 | return PTR_ERR(dev->fw_handler); |
| 299 | 299 | ||
| @@ -1,193 +1,29 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | ||
| 3 | #include "mtk_vcodec_fw.h" | 3 | #include "mtk_vcodec_fw.h" |
| 4 | #include "mtk_vcodec_fw_priv.h" | ||
| 4 | #include "mtk_vcodec_util.h" | 5 | #include "mtk_vcodec_util.h" |
| 5 | #include "mtk_vcodec_drv.h" | 6 | #include "mtk_vcodec_drv.h" |
| 6 | 7 | ||
| 7 | struct mtk_vcodec_fw_ops { | ||
| 8 | int (*load_firmware)(struct mtk_vcodec_fw *fw); | ||
| 9 | unsigned int (*get_vdec_capa)(struct mtk_vcodec_fw *fw); | ||
| 10 | unsigned int (*get_venc_capa)(struct mtk_vcodec_fw *fw); | ||
| 11 | void * (*map_dm_addr)(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr); | ||
| 12 | int (*ipi_register)(struct mtk_vcodec_fw *fw, int id, | ||
| 13 | mtk_vcodec_ipi_handler handler, const char *name, void *priv); | ||
| 14 | int (*ipi_send)(struct mtk_vcodec_fw *fw, int id, void *buf, | ||
| 15 | unsigned int len, unsigned int wait); | ||
| 16 | }; | ||
| 17 | |||
| 18 | struct mtk_vcodec_fw { | ||
| 19 | enum mtk_vcodec_fw_type type; | ||
| 20 | const struct mtk_vcodec_fw_ops *ops; | ||
| 21 | struct platform_device *pdev; | ||
| 22 | struct mtk_scp *scp; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static int mtk_vcodec_vpu_load_firmware(struct mtk_vcodec_fw *fw) | ||
| 26 | { | ||
| 27 | return vpu_load_firmware(fw->pdev); | ||
| 28 | } | ||
| 29 | |||
| 30 | static unsigned int mtk_vcodec_vpu_get_vdec_capa(struct mtk_vcodec_fw *fw) | ||
| 31 | { | ||
| 32 | return vpu_get_vdec_hw_capa(fw->pdev); | ||
| 33 | } | ||
| 34 | |||
| 35 | static unsigned int mtk_vcodec_vpu_get_venc_capa(struct mtk_vcodec_fw *fw) | ||
| 36 | { | ||
| 37 | return vpu_get_venc_hw_capa(fw->pdev); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void *mtk_vcodec_vpu_map_dm_addr(struct mtk_vcodec_fw *fw, | ||
| 41 | u32 dtcm_dmem_addr) | ||
| 42 | { | ||
| 43 | return vpu_mapping_dm_addr(fw->pdev, dtcm_dmem_addr); | ||
| 44 | } | ||
| 45 | |||
| 46 | static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id, | ||
| 47 | mtk_vcodec_ipi_handler handler, | ||
| 48 | const char *name, void *priv) | ||
| 49 | { | ||
| 50 | /* | ||
| 51 | * The handler we receive takes a void * as its first argument. We | ||
| 52 | * cannot change this because it needs to be passed down to the rproc | ||
| 53 | * subsystem when SCP is used. VPU takes a const argument, which is | ||
| 54 | * more constrained, so the conversion below is safe. | ||
| 55 | */ | ||
| 56 | ipi_handler_t handler_const = (ipi_handler_t)handler; | ||
| 57 | |||
| 58 | return vpu_ipi_register(fw->pdev, id, handler_const, name, priv); | ||
| 59 | } | ||
| 60 | |||
| 61 | static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf, | ||
| 62 | unsigned int len, unsigned int wait) | ||
| 63 | { | ||
| 64 | return vpu_ipi_send(fw->pdev, id, buf, len); | ||
| 65 | } | ||
| 66 | |||
| 67 | static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = { | ||
| 68 | .load_firmware = mtk_vcodec_vpu_load_firmware, | ||
| 69 | .get_vdec_capa = mtk_vcodec_vpu_get_vdec_capa, | ||
| 70 | .get_venc_capa = mtk_vcodec_vpu_get_venc_capa, | ||
| 71 | .map_dm_addr = mtk_vcodec_vpu_map_dm_addr, | ||
| 72 | .ipi_register = mtk_vcodec_vpu_set_ipi_register, | ||
| 73 | .ipi_send = mtk_vcodec_vpu_ipi_send, | ||
| 74 | }; | ||
| 75 | |||
| 76 | static int mtk_vcodec_scp_load_firmware(struct mtk_vcodec_fw *fw) | ||
| 77 | { | ||
| 78 | return rproc_boot(scp_get_rproc(fw->scp)); | ||
| 79 | } | ||
| 80 | |||
| 81 | static unsigned int mtk_vcodec_scp_get_vdec_capa(struct mtk_vcodec_fw *fw) | ||
| 82 | { | ||
| 83 | return scp_get_vdec_hw_capa(fw->scp); | ||
| 84 | } | ||
| 85 | |||
| 86 | static unsigned int mtk_vcodec_scp_get_venc_capa(struct mtk_vcodec_fw *fw) | ||
| 87 | { | ||
| 88 | return scp_get_venc_hw_capa(fw->scp); | ||
| 89 | } | ||
| 90 | |||
| 91 | static void *mtk_vcodec_vpu_scp_dm_addr(struct mtk_vcodec_fw *fw, | ||
| 92 | u32 dtcm_dmem_addr) | ||
| 93 | { | ||
| 94 | return scp_mapping_dm_addr(fw->scp, dtcm_dmem_addr); | ||
| 95 | } | ||
| 96 | |||
| 97 | static int mtk_vcodec_scp_set_ipi_register(struct mtk_vcodec_fw *fw, int id, | ||
| 98 | mtk_vcodec_ipi_handler handler, | ||
| 99 | const char *name, void *priv) | ||
| 100 | { | ||
| 101 | return scp_ipi_register(fw->scp, id, handler, priv); | ||
| 102 | } | ||
| 103 | |||
| 104 | static int mtk_vcodec_scp_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf, | ||
| 105 | unsigned int len, unsigned int wait) | ||
| 106 | { | ||
| 107 | return scp_ipi_send(fw->scp, id, buf, len, wait); | ||
| 108 | } | ||
| 109 | |||
| 110 | static const struct mtk_vcodec_fw_ops mtk_vcodec_rproc_msg = { | ||
| 111 | .load_firmware = mtk_vcodec_scp_load_firmware, | ||
| 112 | .get_vdec_capa = mtk_vcodec_scp_get_vdec_capa, | ||
| 113 | .get_venc_capa = mtk_vcodec_scp_get_venc_capa, | ||
| 114 | .map_dm_addr = mtk_vcodec_vpu_scp_dm_addr, | ||
| 115 | .ipi_register = mtk_vcodec_scp_set_ipi_register, | ||
| 116 | .ipi_send = mtk_vcodec_scp_ipi_send, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static void mtk_vcodec_reset_handler(void *priv) | ||
| 120 | { | ||
| 121 | struct mtk_vcodec_dev *dev = priv; | ||
| 122 | struct mtk_vcodec_ctx *ctx; | ||
| 123 | |||
| 124 | mtk_v4l2_err("Watchdog timeout!!"); | ||
| 125 | |||
| 126 | mutex_lock(&dev->dev_mutex); | ||
| 127 | list_for_each_entry(ctx, &dev->ctx_list, list) { | ||
| 128 | ctx->state = MTK_STATE_ABORT; | ||
| 129 | mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ABORT", | ||
| 130 | ctx->id); | ||
| 131 | } | ||
| 132 | mutex_unlock(&dev->dev_mutex); | ||
| 133 | } | ||
| 134 | |||
| 135 | struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev, | 8 | struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev, |
| 136 | enum mtk_vcodec_fw_type type, | 9 | enum mtk_vcodec_fw_type type, |
| 137 | enum rst_id rst_id) | 10 | enum mtk_vcodec_fw_use fw_use) |
| 138 | { | 11 | { |
| 139 | const struct mtk_vcodec_fw_ops *ops; | ||
| 140 | struct mtk_vcodec_fw *fw; | ||
| 141 | struct platform_device *fw_pdev = NULL; | ||
| 142 | struct mtk_scp *scp = NULL; | ||
| 143 | |||
| 144 | switch (type) { | 12 | switch (type) { |
| 145 | case VPU: | 13 | case VPU: |
| 146 | ops = &mtk_vcodec_vpu_msg; | 14 | return mtk_vcodec_fw_vpu_init(dev, fw_use); |
| 147 | fw_pdev = vpu_get_plat_device(dev->plat_dev); | ||
| 148 | if (!fw_pdev) { | ||
| 149 | mtk_v4l2_err("firmware device is not ready"); | ||
| 150 | return ERR_PTR(-EINVAL); | ||
| 151 | } | ||
| 152 | vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_reset_handler, | ||
| 153 | dev, rst_id); | ||
| 154 | break; | ||
| 155 | case SCP: | 15 | case SCP: |
| 156 | ops = &mtk_vcodec_rproc_msg; | 16 | return mtk_vcodec_fw_scp_init(dev); |
| 157 | scp = scp_get(dev->plat_dev); | ||
| 158 | if (!scp) { | ||
| 159 | mtk_v4l2_err("could not get vdec scp handle"); | ||
| 160 | return ERR_PTR(-EPROBE_DEFER); | ||
| 161 | } | ||
| 162 | break; | ||
| 163 | default: | 17 | default: |
| 164 | mtk_v4l2_err("invalid vcodec fw type"); | 18 | mtk_v4l2_err("invalid vcodec fw type"); |
| 165 | return ERR_PTR(-EINVAL); | 19 | return ERR_PTR(-EINVAL); |
| 166 | } | 20 | } |
| 167 | |||
| 168 | fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL); | ||
| 169 | if (!fw) | ||
| 170 | return ERR_PTR(-EINVAL); | ||
| 171 | |||
| 172 | fw->type = type; | ||
| 173 | fw->ops = ops; | ||
| 174 | fw->pdev = fw_pdev; | ||
| 175 | fw->scp = scp; | ||
| 176 | |||
| 177 | return fw; | ||
| 178 | } | 21 | } |
| 179 | EXPORT_SYMBOL_GPL(mtk_vcodec_fw_select); | 22 | EXPORT_SYMBOL_GPL(mtk_vcodec_fw_select); |
| 180 | 23 | ||
| 181 | void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw) | 24 | void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw) |
| 182 | { | 25 | { |
| 183 | switch (fw->type) { | 26 | fw->ops->release(fw); |
| 184 | case VPU: | ||
| 185 | put_device(&fw->pdev->dev); | ||
| 186 | break; | ||
| 187 | case SCP: | ||
| 188 | scp_put(fw->scp); | ||
| 189 | break; | ||
| 190 | } | ||
| 191 | } | 27 | } |
| 192 | EXPORT_SYMBOL_GPL(mtk_vcodec_fw_release); | 28 | EXPORT_SYMBOL_GPL(mtk_vcodec_fw_release); |
| 193 | 29 | ||
| @@ -15,6 +15,11 @@ enum mtk_vcodec_fw_type { · 14 unmodified lines | |||
| 15 | SCP, | 15 | SCP, |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | enum mtk_vcodec_fw_use { | ||
| 19 | DECODER, | ||
| 20 | ENCODER, | ||
| 21 | }; | ||
| 22 | |||
| 18 | struct mtk_vcodec_fw; | 23 | struct mtk_vcodec_fw; |
| 19 | 24 | ||
| 20 | typedef void (*mtk_vcodec_ipi_handler) (void *data, | 25 | typedef void (*mtk_vcodec_ipi_handler) (void *data, |
| @@ -22,7 +27,7 @@ typedef void (*mtk_vcodec_ipi_handler) (void *data, · 1 unmodified line | |||
| 22 | 27 | ||
| 23 | struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev, | 28 | struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev, |
| 24 | enum mtk_vcodec_fw_type type, | 29 | enum mtk_vcodec_fw_type type, |
| 25 | enum rst_id rst_id); | 30 | enum mtk_vcodec_fw_use fw_use); |
| 26 | void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw); | 31 | void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw); |
| 27 | 32 | ||
| 28 | int mtk_vcodec_fw_load_firmware(struct mtk_vcodec_fw *fw); | 33 | int mtk_vcodec_fw_load_firmware(struct mtk_vcodec_fw *fw); |
| @@ -0,0 +1,52 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | |||
| 3 | #ifndef _MTK_VCODEC_FW_PRIV_H_ | ||
| 4 | #define _MTK_VCODEC_FW_PRIV_H_ | ||
| 5 | |||
| 6 | #include "mtk_vcodec_fw.h" | ||
| 7 | |||
| 8 | struct mtk_vcodec_dev; | ||
| 9 | |||
| 10 | struct mtk_vcodec_fw { | ||
| 11 | enum mtk_vcodec_fw_type type; | ||
| 12 | const struct mtk_vcodec_fw_ops *ops; | ||
| 13 | struct platform_device *pdev; | ||
| 14 | struct mtk_scp *scp; | ||
| 15 | }; | ||
| 16 | |||
| 17 | struct mtk_vcodec_fw_ops { | ||
| 18 | int (*load_firmware)(struct mtk_vcodec_fw *fw); | ||
| 19 | unsigned int (*get_vdec_capa)(struct mtk_vcodec_fw *fw); | ||
| 20 | unsigned int (*get_venc_capa)(struct mtk_vcodec_fw *fw); | ||
| 21 | void *(*map_dm_addr)(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr); | ||
| 22 | int (*ipi_register)(struct mtk_vcodec_fw *fw, int id, | ||
| 23 | mtk_vcodec_ipi_handler handler, const char *name, | ||
| 24 | void *priv); | ||
| 25 | int (*ipi_send)(struct mtk_vcodec_fw *fw, int id, void *buf, | ||
| 26 | unsigned int len, unsigned int wait); | ||
| 27 | void (*release)(struct mtk_vcodec_fw *fw); | ||
| 28 | }; | ||
| 29 | |||
| 30 | #if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU) | ||
| 31 | struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev, | ||
| 32 | enum mtk_vcodec_fw_use fw_use); | ||
| 33 | #else | ||
| 34 | static inline struct mtk_vcodec_fw * | ||
| 35 | mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev, | ||
| 36 | enum mtk_vcodec_fw_use fw_use) | ||
| 37 | { | ||
| 38 | return ERR_PTR(-ENODEV); | ||
| 39 | } | ||
| 40 | #endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_VPU */ | ||
| 41 | |||
| 42 | #if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP) | ||
| 43 | struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev); | ||
| 44 | #else | ||
| 45 | static inline struct mtk_vcodec_fw * | ||
| 46 | mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev) | ||
| 47 | { | ||
| 48 | return ERR_PTR(-ENODEV); | ||
| 49 | } | ||
| 50 | #endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_SCP */ | ||
| 51 | |||
| 52 | #endif /* _MTK_VCODEC_FW_PRIV_H_ */ | ||
| @@ -0,0 +1,73 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | #include "mtk_vcodec_fw_priv.h" | ||
| 4 | #include "mtk_vcodec_util.h" | ||
| 5 | #include "mtk_vcodec_drv.h" | ||
| 6 | |||
| 7 | static int mtk_vcodec_scp_load_firmware(struct mtk_vcodec_fw *fw) | ||
| 8 | { | ||
| 9 | return rproc_boot(scp_get_rproc(fw->scp)); | ||
| 10 | } | ||
| 11 | |||
| 12 | static unsigned int mtk_vcodec_scp_get_vdec_capa(struct mtk_vcodec_fw *fw) | ||
| 13 | { | ||
| 14 | return scp_get_vdec_hw_capa(fw->scp); | ||
| 15 | } | ||
| 16 | |||
| 17 | static unsigned int mtk_vcodec_scp_get_venc_capa(struct mtk_vcodec_fw *fw) | ||
| 18 | { | ||
| 19 | return scp_get_venc_hw_capa(fw->scp); | ||
| 20 | } | ||
| 21 | |||
| 22 | static void *mtk_vcodec_vpu_scp_dm_addr(struct mtk_vcodec_fw *fw, | ||
| 23 | u32 dtcm_dmem_addr) | ||
| 24 | { | ||
| 25 | return scp_mapping_dm_addr(fw->scp, dtcm_dmem_addr); | ||
| 26 | } | ||
| 27 | |||
| 28 | static int mtk_vcodec_scp_set_ipi_register(struct mtk_vcodec_fw *fw, int id, | ||
| 29 | mtk_vcodec_ipi_handler handler, | ||
| 30 | const char *name, void *priv) | ||
| 31 | { | ||
| 32 | return scp_ipi_register(fw->scp, id, handler, priv); | ||
| 33 | } | ||
| 34 | |||
| 35 | static int mtk_vcodec_scp_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf, | ||
| 36 | unsigned int len, unsigned int wait) | ||
| 37 | { | ||
| 38 | return scp_ipi_send(fw->scp, id, buf, len, wait); | ||
| 39 | } | ||
| 40 | |||
| 41 | static void mtk_vcodec_scp_release(struct mtk_vcodec_fw *fw) | ||
| 42 | { | ||
| 43 | scp_put(fw->scp); | ||
| 44 | } | ||
| 45 | |||
| 46 | static const struct mtk_vcodec_fw_ops mtk_vcodec_rproc_msg = { | ||
| 47 | .load_firmware = mtk_vcodec_scp_load_firmware, | ||
| 48 | .get_vdec_capa = mtk_vcodec_scp_get_vdec_capa, | ||
| 49 | .get_venc_capa = mtk_vcodec_scp_get_venc_capa, | ||
| 50 | .map_dm_addr = mtk_vcodec_vpu_scp_dm_addr, | ||
| 51 | .ipi_register = mtk_vcodec_scp_set_ipi_register, | ||
| 52 | .ipi_send = mtk_vcodec_scp_ipi_send, | ||
| 53 | .release = mtk_vcodec_scp_release, | ||
| 54 | }; | ||
| 55 | |||
| 56 | struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev) | ||
| 57 | { | ||
| 58 | struct mtk_vcodec_fw *fw; | ||
| 59 | struct mtk_scp *scp; | ||
| 60 | |||
| 61 | scp = scp_get(dev->plat_dev); | ||
| 62 | if (!scp) { | ||
| 63 | mtk_v4l2_err("could not get vdec scp handle"); | ||
| 64 | return ERR_PTR(-EPROBE_DEFER); | ||
| 65 | } | ||
| 66 | |||
| 67 | fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL); | ||
| 68 | fw->type = SCP; | ||
| 69 | fw->ops = &mtk_vcodec_rproc_msg; | ||
| 70 | fw->scp = scp; | ||
| 71 | |||
| 72 | return fw; | ||
| 73 | } | ||
| @@ -0,0 +1,110 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | #include "mtk_vcodec_fw_priv.h" | ||
| 4 | #include "mtk_vcodec_util.h" | ||
| 5 | #include "mtk_vcodec_drv.h" | ||
| 6 | |||
| 7 | static int mtk_vcodec_vpu_load_firmware(struct mtk_vcodec_fw *fw) | ||
| 8 | { | ||
| 9 | return vpu_load_firmware(fw->pdev); | ||
| 10 | } | ||
| 11 | |||
| 12 | static unsigned int mtk_vcodec_vpu_get_vdec_capa(struct mtk_vcodec_fw *fw) | ||
| 13 | { | ||
| 14 | return vpu_get_vdec_hw_capa(fw->pdev); | ||
| 15 | } | ||
| 16 | |||
| 17 | static unsigned int mtk_vcodec_vpu_get_venc_capa(struct mtk_vcodec_fw *fw) | ||
| 18 | { | ||
| 19 | return vpu_get_venc_hw_capa(fw->pdev); | ||
| 20 | } | ||
| 21 | |||
| 22 | static void *mtk_vcodec_vpu_map_dm_addr(struct mtk_vcodec_fw *fw, | ||
| 23 | u32 dtcm_dmem_addr) | ||
| 24 | { | ||
| 25 | return vpu_mapping_dm_addr(fw->pdev, dtcm_dmem_addr); | ||
| 26 | } | ||
| 27 | |||
| 28 | static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id, | ||
| 29 | mtk_vcodec_ipi_handler handler, | ||
| 30 | const char *name, void *priv) | ||
| 31 | { | ||
| 32 | /* | ||
| 33 | * The handler we receive takes a void * as its first argument. We | ||
| 34 | * cannot change this because it needs to be passed down to the rproc | ||
| 35 | * subsystem when SCP is used. VPU takes a const argument, which is | ||
| 36 | * more constrained, so the conversion below is safe. | ||
| 37 | */ | ||
| 38 | ipi_handler_t handler_const = (ipi_handler_t)handler; | ||
| 39 | |||
| 40 | return vpu_ipi_register(fw->pdev, id, handler_const, name, priv); | ||
| 41 | } | ||
| 42 | |||
| 43 | static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf, | ||
| 44 | unsigned int len, unsigned int wait) | ||
| 45 | { | ||
| 46 | return vpu_ipi_send(fw->pdev, id, buf, len); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void mtk_vcodec_vpu_release(struct mtk_vcodec_fw *fw) | ||
| 50 | { | ||
| 51 | put_device(&fw->pdev->dev); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void mtk_vcodec_vpu_reset_handler(void *priv) | ||
| 55 | { | ||
| 56 | struct mtk_vcodec_dev *dev = priv; | ||
| 57 | struct mtk_vcodec_ctx *ctx; | ||
| 58 | |||
| 59 | mtk_v4l2_err("Watchdog timeout!!"); | ||
| 60 | |||
| 61 | mutex_lock(&dev->dev_mutex); | ||
| 62 | list_for_each_entry(ctx, &dev->ctx_list, list) { | ||
| 63 | ctx->state = MTK_STATE_ABORT; | ||
| 64 | mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ABORT", | ||
| 65 | ctx->id); | ||
| 66 | } | ||
| 67 | mutex_unlock(&dev->dev_mutex); | ||
| 68 | } | ||
| 69 | |||
| 70 | static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = { | ||
| 71 | .load_firmware = mtk_vcodec_vpu_load_firmware, | ||
| 72 | .get_vdec_capa = mtk_vcodec_vpu_get_vdec_capa, | ||
| 73 | .get_venc_capa = mtk_vcodec_vpu_get_venc_capa, | ||
| 74 | .map_dm_addr = mtk_vcodec_vpu_map_dm_addr, | ||
| 75 | .ipi_register = mtk_vcodec_vpu_set_ipi_register, | ||
| 76 | .ipi_send = mtk_vcodec_vpu_ipi_send, | ||
| 77 | .release = mtk_vcodec_vpu_release, | ||
| 78 | }; | ||
| 79 | |||
| 80 | struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev, | ||
| 81 | enum mtk_vcodec_fw_use fw_use) | ||
| 82 | { | ||
| 83 | struct platform_device *fw_pdev; | ||
| 84 | struct mtk_vcodec_fw *fw; | ||
| 85 | enum rst_id rst_id; | ||
| 86 | |||
| 87 | switch (fw_use) { | ||
| 88 | case ENCODER: | ||
| 89 | rst_id = VPU_RST_ENC; | ||
| 90 | break; | ||
| 91 | case DECODER: | ||
| 92 | default: | ||
| 93 | rst_id = VPU_RST_DEC; | ||
| 94 | break; | ||
| 95 | } | ||
| 96 | |||
| 97 | fw_pdev = vpu_get_plat_device(dev->plat_dev); | ||
| 98 | if (!fw_pdev) { | ||
| 99 | mtk_v4l2_err("firmware device is not ready"); | ||
| 100 | return ERR_PTR(-EINVAL); | ||
| 101 | } | ||
| 102 | vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id); | ||
| 103 | |||
| 104 | fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL); | ||
| 105 | fw->type = VPU; | ||
| 106 | fw->ops = &mtk_vcodec_vpu_msg; | ||
| 107 | fw->pdev = fw_pdev; | ||
| 108 | |||
| 109 | return fw; | ||
| 110 | } | ||
| @@ -243,8 +243,19 @@ struct venc_controls { · 242 unmodified lines | |||
| 243 | 243 | ||
| 244 | u32 header_mode; | 244 | u32 header_mode; |
| 245 | 245 | ||
| 246 | u32 profile; | 246 | struct { |
| 247 | u32 level; | 247 | u32 h264; |
| 248 | u32 mpeg4; | ||
| 249 | u32 hevc; | ||
| 250 | u32 vp8; | ||
| 251 | u32 vp9; | ||
| 252 | } profile; | ||
| 253 | struct { | ||
| 254 | u32 h264; | ||
| 255 | u32 mpeg4; | ||
| 256 | u32 hevc; | ||
| 257 | u32 vp9; | ||
| 258 | } level; | ||
| 248 | }; | 259 | }; |
| 249 | 260 | ||
| 250 | struct venus_buffer { | 261 | struct venus_buffer { |
| @@ -794,7 +794,7 @@ skip_pmdomains: · 793 unmodified lines | |||
| 794 | return 0; | 794 | return 0; |
| 795 | 795 | ||
| 796 | opp_dl_add_err: | 796 | opp_dl_add_err: |
| 797 | dev_pm_domain_detach(core->opp_pmdomain, true); | 797 | dev_pm_opp_detach_genpd(core->opp_table); |
| 798 | opp_attach_err: | 798 | opp_attach_err: |
| 799 | if (core->pd_dl_venus) { | 799 | if (core->pd_dl_venus) { |
| 800 | device_link_del(core->pd_dl_venus); | 800 | device_link_del(core->pd_dl_venus); |
| @@ -832,7 +832,7 @@ skip_pmdomains: · 31 unmodified lines | |||
| 832 | if (core->opp_dl_venus) | 832 | if (core->opp_dl_venus) |
| 833 | device_link_del(core->opp_dl_venus); | 833 | device_link_del(core->opp_dl_venus); |
| 834 | 834 | ||
| 835 | dev_pm_domain_detach(core->opp_pmdomain, true); | 835 | dev_pm_opp_detach_genpd(core->opp_table); |
| 836 | } | 836 | } |
| 837 | 837 | ||
| 838 | static int core_get_v4(struct device *dev) | 838 | static int core_get_v4(struct device *dev) |
| @@ -537,6 +537,7 @@ static int venc_set_properties(struct venus_inst *inst) · 536 unmodified lines | |||
| 537 | struct hfi_quantization quant; | 537 | struct hfi_quantization quant; |
| 538 | struct hfi_quantization_range quant_range; | 538 | struct hfi_quantization_range quant_range; |
| 539 | u32 ptype, rate_control, bitrate; | 539 | u32 ptype, rate_control, bitrate; |
| 540 | u32 profile, level; | ||
| 540 | int ret; | 541 | int ret; |
| 541 | 542 | ||
| 542 | ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); | 543 | ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); |
| @@ -684,7 +685,35 @@ static int venc_set_properties(struct venus_inst *inst) · 141 unmodified lines | |||
| 684 | if (ret) | 685 | if (ret) |
| 685 | return ret; | 686 | return ret; |
| 686 | 687 | ||
| 687 | ret = venus_helper_set_profile_level(inst, ctr->profile, ctr->level); | 688 | switch (inst->hfi_codec) { |
| 689 | case HFI_VIDEO_CODEC_H264: | ||
| 690 | profile = ctr->profile.h264; | ||
| 691 | level = ctr->level.h264; | ||
| 692 | break; | ||
| 693 | case HFI_VIDEO_CODEC_MPEG4: | ||
| 694 | profile = ctr->profile.mpeg4; | ||
| 695 | level = ctr->level.mpeg4; | ||
| 696 | break; | ||
| 697 | case HFI_VIDEO_CODEC_VP8: | ||
| 698 | profile = ctr->profile.vp8; | ||
| 699 | level = 0; | ||
| 700 | break; | ||
| 701 | case HFI_VIDEO_CODEC_VP9: | ||
| 702 | profile = ctr->profile.vp9; | ||
| 703 | level = ctr->level.vp9; | ||
| 704 | break; | ||
| 705 | case HFI_VIDEO_CODEC_HEVC: | ||
| 706 | profile = ctr->profile.hevc; | ||
| 707 | level = ctr->level.hevc; | ||
| 708 | break; | ||
| 709 | case HFI_VIDEO_CODEC_MPEG2: | ||
| 710 | default: | ||
| 711 | profile = 0; | ||
| 712 | level = 0; | ||
| 713 | break; | ||
| 714 | } | ||
| 715 | |||
| 716 | ret = venus_helper_set_profile_level(inst, profile, level); | ||
| 688 | if (ret) | 717 | if (ret) |
| 689 | return ret; | 718 | return ret; |
| 690 | 719 | ||
| @@ -103,15 +103,25 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) · 102 unmodified lines | |||
| 103 | ctr->h264_entropy_mode = ctrl->val; | 103 | ctr->h264_entropy_mode = ctrl->val; |
| 104 | break; | 104 | break; |
| 105 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: | 105 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: |
| 106 | ctr->profile.mpeg4 = ctrl->val; | ||
| 107 | break; | ||
| 106 | case V4L2_CID_MPEG_VIDEO_H264_PROFILE: | 108 | case V4L2_CID_MPEG_VIDEO_H264_PROFILE: |
| 109 | ctr->profile.h264 = ctrl->val; | ||
| 110 | break; | ||
| 107 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: | 111 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: |
| 112 | ctr->profile.hevc = ctrl->val; | ||
| 113 | break; | ||
| 108 | case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: | 114 | case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: |
| 109 | ctr->profile = ctrl->val; | 115 | ctr->profile.vp8 = ctrl->val; |
| 110 | break; | 116 | break; |
| 111 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: | 117 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: |
| 118 | ctr->level.mpeg4 = ctrl->val; | ||
| 119 | break; | ||
| 112 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: | 120 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: |
| 121 | ctr->level.h264 = ctrl->val; | ||
| 122 | break; | ||
| 113 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: | 123 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: |
| 114 | ctr->level = ctrl->val; | 124 | ctr->level.hevc = ctrl->val; |
| 115 | break; | 125 | break; |
| 116 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: | 126 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: |
| 117 | ctr->h264_i_qp = ctrl->val; | 127 | ctr->h264_i_qp = ctrl->val; |
| @@ -4,36 +4,43 @@ · 3 unmodified lines | |||
| 4 | * validate the existing APIs in the media subsystem. It can also aid | 4 | * validate the existing APIs in the media subsystem. It can also aid |
| 5 | * developers working on userspace applications. | 5 | * developers working on userspace applications. |
| 6 | * | 6 | * |
| 7 | * When this module is loaded, it will attempt to modprobe 'dvb_vidtv_tuner' and 'dvb_vidtv_demod'. | 7 | * When this module is loaded, it will attempt to modprobe 'dvb_vidtv_tuner' |
| 8 | * and 'dvb_vidtv_demod'. | ||
| 8 | * | 9 | * |
| 9 | * Copyright (C) 2020 Daniel W. S. Almeida | 10 | * Copyright (C) 2020 Daniel W. S. Almeida |
| 10 | */ | 11 | */ |
| 11 | 12 | ||
| 13 | #include <linux/dev_printk.h> | ||
| 12 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
| 13 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
| 14 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 15 | #include <linux/dev_printk.h> | ||
| 16 | #include <linux/time.h> | 17 | #include <linux/time.h> |
| 17 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 18 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
| 19 | 20 | ||
| 20 | #include "vidtv_bridge.h" | 21 | #include "vidtv_bridge.h" |
| 22 | #include "vidtv_common.h" | ||
| 21 | #include "vidtv_demod.h" | 23 | #include "vidtv_demod.h" |
| 22 | #include "vidtv_tuner.h" | ||
| 23 | #include "vidtv_ts.h" | ||
| 24 | #include "vidtv_mux.h" | 24 | #include "vidtv_mux.h" |
| 25 | #include "vidtv_common.h" | 25 | #include "vidtv_ts.h" |
| 26 | #include "vidtv_tuner.h" | ||
| 26 | 27 | ||
| 27 | //#define MUX_BUF_MAX_SZ | 28 | #define MUX_BUF_MIN_SZ 90164 |
| 28 | //#define MUX_BUF_MIN_SZ | 29 | #define MUX_BUF_MAX_SZ (MUX_BUF_MIN_SZ * 10) |
| 29 | #define TUNER_DEFAULT_ADDR 0x68 | 30 | #define TUNER_DEFAULT_ADDR 0x68 |
| 30 | #define DEMOD_DEFAULT_ADDR 0x60 | 31 | #define DEMOD_DEFAULT_ADDR 0x60 |
| 32 | #define VIDTV_DEFAULT_NETWORK_ID 0xff44 | ||
| 33 | #define VIDTV_DEFAULT_NETWORK_NAME "LinuxTV.org" | ||
| 34 | #define VIDTV_DEFAULT_TS_ID 0x4081 | ||
| 31 | 35 | ||
| 32 | /* LNBf fake parameters: ranges used by an Universal (extended) European LNBf */ | 36 | /* |
| 33 | #define LNB_CUT_FREQUENCY 11700000 | 37 | * The LNBf fake parameters here are the ranges used by an |
| 34 | #define LNB_LOW_FREQ 9750000 | 38 | * Universal (extended) European LNBf, which is likely the most common LNBf |
| 35 | #define LNB_HIGH_FREQ 10600000 | 39 | * found on Satellite digital TV system nowadays. |
| 36 | 40 | */ | |
| 41 | #define LNB_CUT_FREQUENCY 11700000 /* high IF frequency */ | ||
| 42 | #define LNB_LOW_FREQ 9750000 /* low IF frequency */ | ||
| 43 | #define LNB_HIGH_FREQ 10600000 /* transition frequency */ | ||
| 37 | 44 | ||
| 38 | static unsigned int drop_tslock_prob_on_low_snr; | 45 | static unsigned int drop_tslock_prob_on_low_snr; |
| 39 | module_param(drop_tslock_prob_on_low_snr, uint, 0); | 46 | module_param(drop_tslock_prob_on_low_snr, uint, 0); |
| @@ -92,7 +99,8 @@ MODULE_PARM_DESC(si_period_msec, "How often to send SI packets. Default: 40ms"); · 52 unmodified lines | |||
| 92 | 99 | ||
| 93 | static unsigned int pcr_period_msec = 40; | 100 | static unsigned int pcr_period_msec = 40; |
| 94 | module_param(pcr_period_msec, uint, 0); | 101 | module_param(pcr_period_msec, uint, 0); |
| 95 | MODULE_PARM_DESC(pcr_period_msec, "How often to send PCR packets. Default: 40ms"); | 102 | MODULE_PARM_DESC(pcr_period_msec, |
| 103 | "How often to send PCR packets. Default: 40ms"); | ||
| 96 | 104 | ||
| 97 | static unsigned int mux_rate_kbytes_sec = 4096; | 105 | static unsigned int mux_rate_kbytes_sec = 4096; |
| 98 | module_param(mux_rate_kbytes_sec, uint, 0); | 106 | module_param(mux_rate_kbytes_sec, uint, 0); |
| @@ -104,16 +112,14 @@ MODULE_PARM_DESC(pcr_pid, "PCR PID for all channels: defaults to 0x200"); · 5 unmodified lines | |||
| 104 | 112 | ||
| 105 | static unsigned int mux_buf_sz_pkts; | 113 | static unsigned int mux_buf_sz_pkts; |
| 106 | module_param(mux_buf_sz_pkts, uint, 0); | 114 | module_param(mux_buf_sz_pkts, uint, 0); |
| 107 | MODULE_PARM_DESC(mux_buf_sz_pkts, "Size for the internal mux buffer in multiples of 188 bytes"); | 115 | MODULE_PARM_DESC(mux_buf_sz_pkts, |
| 108 | 116 | "Size for the internal mux buffer in multiples of 188 bytes"); | |
| 109 | #define MUX_BUF_MIN_SZ 90164 | ||
| 110 | #define MUX_BUF_MAX_SZ (MUX_BUF_MIN_SZ * 10) | ||
| 111 | 117 | ||
| 112 | static u32 vidtv_bridge_mux_buf_sz_for_mux_rate(void) | 118 | static u32 vidtv_bridge_mux_buf_sz_for_mux_rate(void) |
| 113 | { | 119 | { |
| 114 | u32 max_elapsed_time_msecs = VIDTV_MAX_SLEEP_USECS / USEC_PER_MSEC; | 120 | u32 max_elapsed_time_msecs = VIDTV_MAX_SLEEP_USECS / USEC_PER_MSEC; |
| 115 | u32 nbytes_expected; | ||
| 116 | u32 mux_buf_sz = mux_buf_sz_pkts * TS_PACKET_LEN; | 121 | u32 mux_buf_sz = mux_buf_sz_pkts * TS_PACKET_LEN; |
| 122 | u32 nbytes_expected; | ||
| 117 | 123 | ||
| 118 | nbytes_expected = mux_rate_kbytes_sec; | 124 | nbytes_expected = mux_rate_kbytes_sec; |
| 119 | nbytes_expected *= max_elapsed_time_msecs; | 125 | nbytes_expected *= max_elapsed_time_msecs; |
| @@ -143,14 +149,12 @@ static bool vidtv_bridge_check_demod_lock(struct vidtv_dvb *dvb, u32 n) · 23 unmodified lines | |||
| 143 | FE_HAS_LOCK); | 149 | FE_HAS_LOCK); |
| 144 | } | 150 | } |
| 145 | 151 | ||
| 146 | static void | 152 | /* |
| 147 | vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts) | 153 | * called on a separate thread by the mux when new packets become available |
| 154 | */ | ||
| 155 | static void vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts) | ||
| 148 | { | 156 | { |
| 149 | /* | 157 | struct vidtv_dvb *dvb = priv; |
| 150 | * called on a separate thread by the mux when new packets become | ||
| 151 | * available | ||
| 152 | */ | ||
| 153 | struct vidtv_dvb *dvb = (struct vidtv_dvb *)priv; | ||
| 154 | 158 | ||
| 155 | /* drop packets if we lose the lock */ | 159 | /* drop packets if we lose the lock */ |
| 156 | if (vidtv_bridge_check_demod_lock(dvb, 0)) | 160 | if (vidtv_bridge_check_demod_lock(dvb, 0)) |
| @@ -159,7 +163,17 @@ vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts) · 2 unmodified lines | |||
| 159 | 163 | ||
| 160 | static int vidtv_start_streaming(struct vidtv_dvb *dvb) | 164 | static int vidtv_start_streaming(struct vidtv_dvb *dvb) |
| 161 | { | 165 | { |
| 162 | struct vidtv_mux_init_args mux_args = {0}; | 166 | struct vidtv_mux_init_args mux_args = { |
| 167 | .mux_rate_kbytes_sec = mux_rate_kbytes_sec, | ||
| 168 | .on_new_packets_available_cb = vidtv_bridge_on_new_pkts_avail, | ||
| 169 | .pcr_period_usecs = pcr_period_msec * USEC_PER_MSEC, | ||
| 170 | .si_period_usecs = si_period_msec * USEC_PER_MSEC, | ||
| 171 | .pcr_pid = pcr_pid, | ||
| 172 | .transport_stream_id = VIDTV_DEFAULT_TS_ID, | ||
| 173 | .network_id = VIDTV_DEFAULT_NETWORK_ID, | ||
| 174 | .network_name = VIDTV_DEFAULT_NETWORK_NAME, | ||
| 175 | .priv = dvb, | ||
| 176 | }; | ||
| 163 | struct device *dev = &dvb->pdev->dev; | 177 | struct device *dev = &dvb->pdev->dev; |
| 164 | u32 mux_buf_sz; | 178 | u32 mux_buf_sz; |
| 165 | 179 | ||
| @@ -168,19 +182,17 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) · 2 unmodified lines | |||
| 168 | return 0; | 182 | return 0; |
| 169 | } | 183 | } |
| 170 | 184 | ||
| 171 | mux_buf_sz = (mux_buf_sz_pkts) ? mux_buf_sz_pkts : vidtv_bridge_mux_buf_sz_for_mux_rate(); | 185 | if (mux_buf_sz_pkts) |
| 186 | mux_buf_sz = mux_buf_sz_pkts; | ||
| 187 | else | ||
| 188 | mux_buf_sz = vidtv_bridge_mux_buf_sz_for_mux_rate(); | ||
| 172 | 189 | ||
| 173 | mux_args.mux_rate_kbytes_sec = mux_rate_kbytes_sec; | 190 | mux_args.mux_buf_sz = mux_buf_sz; |
| 174 | mux_args.on_new_packets_available_cb = vidtv_bridge_on_new_pkts_avail; | ||
| 175 | mux_args.mux_buf_sz = mux_buf_sz; | ||
| 176 | mux_args.pcr_period_usecs = pcr_period_msec * 1000; | ||
| 177 | mux_args.si_period_usecs = si_period_msec * 1000; | ||
| 178 | mux_args.pcr_pid = pcr_pid; | ||
| 179 | mux_args.transport_stream_id = VIDTV_DEFAULT_TS_ID; | ||
| 180 | mux_args.priv = dvb; | ||
| 181 | 191 | ||
| 182 | dvb->streaming = true; | 192 | dvb->streaming = true; |
| 183 | dvb->mux = vidtv_mux_init(dvb->fe[0], dev, mux_args); | 193 | dvb->mux = vidtv_mux_init(dvb->fe[0], dev, &mux_args); |
| 194 | if (!dvb->mux) | ||
| 195 | return -ENOMEM; | ||
| 184 | vidtv_mux_start_thread(dvb->mux); | 196 | vidtv_mux_start_thread(dvb->mux); |
| 185 | 197 | ||
| 186 | dev_dbg_ratelimited(dev, "Started streaming\n"); | 198 | dev_dbg_ratelimited(dev, "Started streaming\n"); |
| @@ -204,8 +216,8 @@ static int vidtv_start_feed(struct dvb_demux_feed *feed) · 17 unmodified lines | |||
| 204 | { | 216 | { |
| 205 | struct dvb_demux *demux = feed->demux; | 217 | struct dvb_demux *demux = feed->demux; |
| 206 | struct vidtv_dvb *dvb = demux->priv; | 218 | struct vidtv_dvb *dvb = demux->priv; |
| 207 | int rc; | ||
| 208 | int ret; | 219 | int ret; |
| 220 | int rc; | ||
| 209 | 221 | ||
| 210 | if (!demux->dmx.frontend) | 222 | if (!demux->dmx.frontend) |
| 211 | return -EINVAL; | 223 | return -EINVAL; |
| @@ -243,9 +255,9 @@ static int vidtv_stop_feed(struct dvb_demux_feed *feed) · 31 unmodified lines | |||
| 243 | 255 | ||
| 244 | static struct dvb_frontend *vidtv_get_frontend_ptr(struct i2c_client *c) | 256 | static struct dvb_frontend *vidtv_get_frontend_ptr(struct i2c_client *c) |
| 245 | { | 257 | { |
| 246 | /* the demod will set this when its probe function runs */ | ||
| 247 | struct vidtv_demod_state *state = i2c_get_clientdata(c); | 258 | struct vidtv_demod_state *state = i2c_get_clientdata(c); |
| 248 | 259 | ||
| 260 | /* the demod will set this when its probe function runs */ | ||
| 249 | return &state->frontend; | 261 | return &state->frontend; |
| 250 | } | 262 | } |
| 251 | 263 | ||
| @@ -253,6 +265,11 @@ static int vidtv_master_xfer(struct i2c_adapter *i2c_adap, · 1 unmodified line | |||
| 253 | struct i2c_msg msgs[], | 265 | struct i2c_msg msgs[], |
| 254 | int num) | 266 | int num) |
| 255 | { | 267 | { |
| 268 | /* | ||
| 269 | * Right now, this virtual driver doesn't really send or receive | ||
| 270 | * messages from I2C. A real driver will require an implementation | ||
| 271 | * here. | ||
| 272 | */ | ||
| 256 | return 0; | 273 | return 0; |
| 257 | } | 274 | } |
| 258 | 275 | ||
| @@ -320,11 +337,10 @@ static int vidtv_bridge_dmxdev_init(struct vidtv_dvb *dvb) · 61 unmodified lines | |||
| 320 | 337 | ||
| 321 | static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, u32 n) | 338 | static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, u32 n) |
| 322 | { | 339 | { |
| 323 | struct vidtv_demod_config cfg = {}; | 340 | struct vidtv_demod_config cfg = { |
| 324 | 341 | .drop_tslock_prob_on_low_snr = drop_tslock_prob_on_low_snr, | |
| 325 | cfg.drop_tslock_prob_on_low_snr = drop_tslock_prob_on_low_snr; | 342 | .recover_tslock_prob_on_good_snr = recover_tslock_prob_on_good_snr, |
| 326 | cfg.recover_tslock_prob_on_good_snr = recover_tslock_prob_on_good_snr; | 343 | }; |
| 327 | |||
| 328 | dvb->i2c_client_demod[n] = dvb_module_probe("dvb_vidtv_demod", | 344 | dvb->i2c_client_demod[n] = dvb_module_probe("dvb_vidtv_demod", |
| 329 | NULL, | 345 | NULL, |
| 330 | &dvb->i2c_adapter, | 346 | &dvb->i2c_adapter, |
| @@ -343,14 +359,14 @@ static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, u32 n) · 12 unmodified lines | |||
| 343 | 359 | ||
| 344 | static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n) | 360 | static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n) |
| 345 | { | 361 | { |
| 346 | struct vidtv_tuner_config cfg = {}; | 362 | struct vidtv_tuner_config cfg = { |
| 363 | .fe = dvb->fe[n], | ||
| 364 | .mock_power_up_delay_msec = mock_power_up_delay_msec, | ||
| 365 | .mock_tune_delay_msec = mock_tune_delay_msec, | ||
| 366 | }; | ||
| 347 | u32 freq; | 367 | u32 freq; |
| 348 | int i; | 368 | int i; |
| 349 | 369 | ||
| 350 | cfg.fe = dvb->fe[n]; | ||
| 351 | cfg.mock_power_up_delay_msec = mock_power_up_delay_msec; | ||
| 352 | cfg.mock_tune_delay_msec = mock_tune_delay_msec; | ||
| 353 | |||
| 354 | /* TODO: check if the frequencies are at a valid range */ | 370 | /* TODO: check if the frequencies are at a valid range */ |
| 355 | 371 | ||
| 356 | memcpy(cfg.vidtv_valid_dvb_t_freqs, | 372 | memcpy(cfg.vidtv_valid_dvb_t_freqs, |
| @@ -389,9 +405,7 @@ static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n) · 32 unmodified lines | |||
| 389 | 405 | ||
| 390 | static int vidtv_bridge_dvb_init(struct vidtv_dvb *dvb) | 406 | static int vidtv_bridge_dvb_init(struct vidtv_dvb *dvb) |
| 391 | { | 407 | { |
| 392 | int ret; | 408 | int ret, i, j; |
| 393 | int i; | ||
| 394 | int j; | ||
| 395 | 409 | ||
| 396 | ret = vidtv_bridge_i2c_register_adap(dvb); | 410 | ret = vidtv_bridge_i2c_register_adap(dvb); |
| 397 | if (ret < 0) | 411 | if (ret < 0) |
| @@ -20,9 +20,11 @@ · 19 unmodified lines | |||
| 20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
| 23 | |||
| 23 | #include <media/dmxdev.h> | 24 | #include <media/dmxdev.h> |
| 24 | #include <media/dvb_demux.h> | 25 | #include <media/dvb_demux.h> |
| 25 | #include <media/dvb_frontend.h> | 26 | #include <media/dvb_frontend.h> |
| 27 | |||
| 26 | #include "vidtv_mux.h" | 28 | #include "vidtv_mux.h" |
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| @@ -32,7 +34,7 @@ · 3 unmodified lines | |||
| 32 | * @adapter: Represents a DTV adapter. See 'dvb_register_adapter'. | 34 | * @adapter: Represents a DTV adapter. See 'dvb_register_adapter'. |
| 33 | * @demux: The demux used by the dvb_dmx_swfilter_packets() call. | 35 | * @demux: The demux used by the dvb_dmx_swfilter_packets() call. |
| 34 | * @dmx_dev: Represents a demux device. | 36 | * @dmx_dev: Represents a demux device. |
| 35 | * @dmx_frontend: The frontends associated with the demux. | 37 | * @dmx_fe: The frontends associated with the demux. |
| 36 | * @i2c_adapter: The i2c_adapter associated with the bridge driver. | 38 | * @i2c_adapter: The i2c_adapter associated with the bridge driver. |
| 37 | * @i2c_client_demod: The i2c_clients associated with the demodulator modules. | 39 | * @i2c_client_demod: The i2c_clients associated with the demodulator modules. |
| 38 | * @i2c_client_tuner: The i2c_clients associated with the tuner modules. | 40 | * @i2c_client_tuner: The i2c_clients associated with the tuner modules. |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | * When vidtv boots, it will create some hardcoded channels. | 9 | * When vidtv boots, it will create some hardcoded channels. |
| 10 | * Their services will be concatenated to populate the SDT. | 10 | * Their services will be concatenated to populate the SDT. |
| 11 | * Their programs will be concatenated to populate the PAT | 11 | * Their programs will be concatenated to populate the PAT |
| 12 | * Their events will be concatenated to populate the EIT | ||
| 12 | * For each program in the PAT, a PMT section will be created | 13 | * For each program in the PAT, a PMT section will be created |
| 13 | * The PMT section for a channel will be assigned its streams. | 14 | * The PMT section for a channel will be assigned its streams. |
| 14 | * Every stream will have its corresponding encoder polled to produce TS packets | 15 | * Every stream will have its corresponding encoder polled to produce TS packets |
| @@ -18,22 +19,22 @@ · 3 unmodified lines | |||
| 18 | * Copyright (C) 2020 Daniel W. S. Almeida | 19 | * Copyright (C) 2020 Daniel W. S. Almeida |
| 19 | */ | 20 | */ |
| 20 | 21 | ||
| 21 | #include <linux/types.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/dev_printk.h> | 22 | #include <linux/dev_printk.h> |
| 24 | #include <linux/ratelimit.h> | 23 | #include <linux/ratelimit.h> |
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/types.h> | ||
| 25 | 26 | ||
| 26 | #include "vidtv_channel.h" | 27 | #include "vidtv_channel.h" |
| 27 | #include "vidtv_psi.h" | 28 | #include "vidtv_common.h" |
| 28 | #include "vidtv_encoder.h" | 29 | #include "vidtv_encoder.h" |
| 29 | #include "vidtv_mux.h" | 30 | #include "vidtv_mux.h" |
| 30 | #include "vidtv_common.h" | 31 | #include "vidtv_psi.h" |
| 31 | #include "vidtv_s302m.h" | 32 | #include "vidtv_s302m.h" |
| 32 | 33 | ||
| 33 | static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) | 34 | static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) |
| 34 | { | 35 | { |
| 35 | struct vidtv_encoder *curr = e; | ||
| 36 | struct vidtv_encoder *tmp = NULL; | 36 | struct vidtv_encoder *tmp = NULL; |
| 37 | struct vidtv_encoder *curr = e; | ||
| 37 | 38 | ||
| 38 | while (curr) { | 39 | while (curr) { |
| 39 | /* forward the call to the derived type */ | 40 | /* forward the call to the derived type */ |
| @@ -44,55 +45,88 @@ static void vidtv_channel_encoder_destroy(struct vidtv_encoder *e) · 4 unmodified lines | |||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | #define ENCODING_ISO8859_15 "\x0b" | 47 | #define ENCODING_ISO8859_15 "\x0b" |
| 48 | #define TS_NIT_PID 0x10 | ||
| 47 | 49 | ||
| 50 | /* | ||
| 51 | * init an audio only channel with a s302m encoder | ||
| 52 | */ | ||
| 48 | struct vidtv_channel | 53 | struct vidtv_channel |
| 49 | *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id) | 54 | *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id) |
| 50 | { | 55 | { |
| 51 | /* | ||
| 52 | * init an audio only channel with a s302m encoder | ||
| 53 | */ | ||
| 54 | const u16 s302m_service_id = 0x880; | ||
| 55 | const u16 s302m_program_num = 0x880; | ||
| 56 | const u16 s302m_program_pid = 0x101; /* packet id for PMT*/ | ||
| 57 | const u16 s302m_es_pid = 0x111; /* packet id for the ES */ | ||
| 58 | const __be32 s302m_fid = cpu_to_be32(VIDTV_S302M_FORMAT_IDENTIFIER); | 56 | const __be32 s302m_fid = cpu_to_be32(VIDTV_S302M_FORMAT_IDENTIFIER); |
| 59 | 57 | char *event_text = ENCODING_ISO8859_15 "Bagatelle No. 25 in A minor for solo piano, also known as F\xfcr Elise, composed by Ludwig van Beethoven"; | |
| 60 | char *name = ENCODING_ISO8859_15 "Beethoven"; | 58 | char *event_name = ENCODING_ISO8859_15 "Ludwig van Beethoven: F\xfcr Elise"; |
| 59 | struct vidtv_s302m_encoder_init_args encoder_args = {}; | ||
| 60 | char *iso_language_code = ENCODING_ISO8859_15 "eng"; | ||
| 61 | char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; | 61 | char *provider = ENCODING_ISO8859_15 "LinuxTV.org"; |
| 62 | char *name = ENCODING_ISO8859_15 "Beethoven"; | ||
| 63 | const u16 s302m_es_pid = 0x111; /* packet id for the ES */ | ||
| 64 | const u16 s302m_program_pid = 0x101; /* packet id for PMT*/ | ||
| 65 | const u16 s302m_service_id = 0x880; | ||
| 66 | const u16 s302m_program_num = 0x880; | ||
| 67 | const u16 s302m_beethoven_event_id = 1; | ||
| 68 | struct vidtv_channel *s302m; | ||
| 62 | 69 | ||
| 63 | struct vidtv_channel *s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); | 70 | s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); |
| 64 | struct vidtv_s302m_encoder_init_args encoder_args = {}; | 71 | if (!s302m) |
| 72 | return NULL; | ||
| 65 | 73 | ||
| 66 | s302m->name = kstrdup(name, GFP_KERNEL); | 74 | s302m->name = kstrdup(name, GFP_KERNEL); |
| 75 | if (!s302m->name) | ||
| 76 | goto free_s302m; | ||
| 67 | 77 | ||
| 68 | s302m->service = vidtv_psi_sdt_service_init(NULL, s302m_service_id); | 78 | s302m->service = vidtv_psi_sdt_service_init(NULL, s302m_service_id, false, true); |
| 79 | if (!s302m->service) | ||
| 80 | goto free_name; | ||
| 69 | 81 | ||
| 70 | s302m->service->descriptor = (struct vidtv_psi_desc *) | 82 | s302m->service->descriptor = (struct vidtv_psi_desc *) |
| 71 | vidtv_psi_service_desc_init(NULL, | 83 | vidtv_psi_service_desc_init(NULL, |
| 72 | DIGITAL_TELEVISION_SERVICE, | 84 | DIGITAL_RADIO_SOUND_SERVICE, |
| 73 | name, | 85 | name, |
| 74 | provider); | 86 | provider); |
| 87 | if (!s302m->service->descriptor) | ||
| 88 | goto free_service; | ||
| 75 | 89 | ||
| 76 | s302m->transport_stream_id = transport_stream_id; | 90 | s302m->transport_stream_id = transport_stream_id; |
| 77 | 91 | ||
| 78 | s302m->program = vidtv_psi_pat_program_init(NULL, | 92 | s302m->program = vidtv_psi_pat_program_init(NULL, |
| 79 | s302m_service_id, | 93 | s302m_service_id, |
| 80 | s302m_program_pid); | 94 | s302m_program_pid); |
| 95 | if (!s302m->program) | ||
| 96 | goto free_service; | ||
| 81 | 97 | ||
| 82 | s302m->program_num = s302m_program_num; | 98 | s302m->program_num = s302m_program_num; |
| 83 | 99 | ||
| 84 | s302m->streams = vidtv_psi_pmt_stream_init(NULL, | 100 | s302m->streams = vidtv_psi_pmt_stream_init(NULL, |
| 85 | STREAM_PRIVATE_DATA, | 101 | STREAM_PRIVATE_DATA, |
| 86 | s302m_es_pid); | 102 | s302m_es_pid); |
| 103 | if (!s302m->streams) | ||
| 104 | goto free_program; | ||
| 87 | 105 | ||
| 88 | s302m->streams->descriptor = (struct vidtv_psi_desc *) | 106 | s302m->streams->descriptor = (struct vidtv_psi_desc *) |
| 89 | vidtv_psi_registration_desc_init(NULL, | 107 | vidtv_psi_registration_desc_init(NULL, |
| 90 | s302m_fid, | 108 | s302m_fid, |
| 91 | NULL, | 109 | NULL, |
| 92 | 0); | 110 | 0); |
| 111 | if (!s302m->streams->descriptor) | ||
| 112 | goto free_streams; | ||
| 113 | |||
| 93 | encoder_args.es_pid = s302m_es_pid; | 114 | encoder_args.es_pid = s302m_es_pid; |
| 94 | 115 | ||
| 95 | s302m->encoders = vidtv_s302m_encoder_init(encoder_args); | 116 | s302m->encoders = vidtv_s302m_encoder_init(encoder_args); |
| 117 | if (!s302m->encoders) | ||
| 118 | goto free_streams; | ||
| 119 | |||
| 120 | s302m->events = vidtv_psi_eit_event_init(NULL, s302m_beethoven_event_id); | ||
| 121 | if (!s302m->events) | ||
| 122 | goto free_encoders; | ||
| 123 | s302m->events->descriptor = (struct vidtv_psi_desc *) | ||
| 124 | vidtv_psi_short_event_desc_init(NULL, | ||
| 125 | iso_language_code, | ||
| 126 | event_name, | ||
| 127 | event_text); | ||
| 128 | if (!s302m->events->descriptor) | ||
| 129 | goto free_events; | ||
| 96 | 130 | ||
| 97 | if (head) { | 131 | if (head) { |
| 98 | while (head->next) | 132 | while (head->next) |
| @@ -102,6 +136,68 @@ struct vidtv_channel · 3 unmodified lines | |||
| 102 | } | 136 | } |
| 103 | 137 | ||
| 104 | return s302m; | 138 | return s302m; |
| 139 | |||
| 140 | free_events: | ||
| 141 | vidtv_psi_eit_event_destroy(s302m->events); | ||
| 142 | free_encoders: | ||
| 143 | vidtv_s302m_encoder_destroy(s302m->encoders); | ||
| 144 | free_streams: | ||
| 145 | vidtv_psi_pmt_stream_destroy(s302m->streams); | ||
| 146 | free_program: | ||
| 147 | vidtv_psi_pat_program_destroy(s302m->program); | ||
| 148 | free_service: | ||
| 149 | vidtv_psi_sdt_service_destroy(s302m->service); | ||
| 150 | free_name: | ||
| 151 | kfree(s302m->name); | ||
| 152 | free_s302m: | ||
| 153 | kfree(s302m); | ||
| 154 | |||
| 155 | return NULL; | ||
| 156 | } | ||
| 157 | |||
| 158 | static struct vidtv_psi_table_eit_event | ||
| 159 | *vidtv_channel_eit_event_cat_into_new(struct vidtv_mux *m) | ||
| 160 | { | ||
| 161 | /* Concatenate the events */ | ||
| 162 | const struct vidtv_channel *cur_chnl = m->channels; | ||
| 163 | struct vidtv_psi_table_eit_event *curr = NULL; | ||
| 164 | struct vidtv_psi_table_eit_event *head = NULL; | ||
| 165 | struct vidtv_psi_table_eit_event *tail = NULL; | ||
| 166 | struct vidtv_psi_desc *desc = NULL; | ||
| 167 | u16 event_id; | ||
| 168 | |||
| 169 | if (!cur_chnl) | ||
| 170 | return NULL; | ||
| 171 | |||
| 172 | while (cur_chnl) { | ||
| 173 | curr = cur_chnl->events; | ||
| 174 | |||
| 175 | if (!curr) | ||
| 176 | dev_warn_ratelimited(m->dev, | ||
| 177 | "No events found for channel %s\n", | ||
| 178 | cur_chnl->name); | ||
| 179 | |||
| 180 | while (curr) { | ||
| 181 | event_id = be16_to_cpu(curr->event_id); | ||
| 182 | tail = vidtv_psi_eit_event_init(tail, event_id); | ||
| 183 | if (!tail) { | ||
| 184 | vidtv_psi_eit_event_destroy(head); | ||
| 185 | return NULL; | ||
| 186 | } | ||
| 187 | |||
| 188 | desc = vidtv_psi_desc_clone(curr->descriptor); | ||
| 189 | vidtv_psi_desc_assign(&tail->descriptor, desc); | ||
| 190 | |||
| 191 | if (!head) | ||
| 192 | head = tail; | ||
| 193 | |||
| 194 | curr = curr->next; | ||
| 195 | } | ||
| 196 | |||
| 197 | cur_chnl = cur_chnl->next; | ||
| 198 | } | ||
| 199 | |||
| 200 | return head; | ||
| 105 | } | 201 | } |
| 106 | 202 | ||
| 107 | static struct vidtv_psi_table_sdt_service | 203 | static struct vidtv_psi_table_sdt_service |
| @@ -125,13 +221,21 @@ static struct vidtv_psi_table_sdt_service · 17 unmodified lines | |||
| 125 | 221 | ||
| 126 | if (!curr) | 222 | if (!curr) |
| 127 | dev_warn_ratelimited(m->dev, | 223 | dev_warn_ratelimited(m->dev, |
| 128 | "No services found for channel %s\n", cur_chnl->name); | 224 | "No services found for channel %s\n", |
| 225 | cur_chnl->name); | ||
| 129 | 226 | ||
| 130 | while (curr) { | 227 | while (curr) { |
| 131 | service_id = be16_to_cpu(curr->service_id); | 228 | service_id = be16_to_cpu(curr->service_id); |
| 132 | tail = vidtv_psi_sdt_service_init(tail, service_id); | 229 | tail = vidtv_psi_sdt_service_init(tail, |
| 230 | service_id, | ||
| 231 | curr->EIT_schedule, | ||
| 232 | curr->EIT_present_following); | ||
| 233 | if (!tail) | ||
| 234 | goto free; | ||
| 133 | 235 | ||
| 134 | desc = vidtv_psi_desc_clone(curr->descriptor); | 236 | desc = vidtv_psi_desc_clone(curr->descriptor); |
| 237 | if (!desc) | ||
| 238 | goto free_tail; | ||
| 135 | vidtv_psi_desc_assign(&tail->descriptor, desc); | 239 | vidtv_psi_desc_assign(&tail->descriptor, desc); |
| 136 | 240 | ||
| 137 | if (!head) | 241 | if (!head) |
| @@ -144,6 +248,12 @@ static struct vidtv_psi_table_sdt_service · 6 unmodified lines | |||
| 144 | } | 248 | } |
| 145 | 249 | ||
| 146 | return head; | 250 | return head; |
| 251 | |||
| 252 | free_tail: | ||
| 253 | vidtv_psi_sdt_service_destroy(tail); | ||
| 254 | free: | ||
| 255 | vidtv_psi_sdt_service_destroy(head); | ||
| 256 | return NULL; | ||
| 147 | } | 257 | } |
| 148 | 258 | ||
| 149 | static struct vidtv_psi_table_pat_program* | 259 | static struct vidtv_psi_table_pat_program* |
| @@ -174,6 +284,10 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m) · 24 unmodified lines | |||
| 174 | tail = vidtv_psi_pat_program_init(tail, | 284 | tail = vidtv_psi_pat_program_init(tail, |
| 175 | serv_id, | 285 | serv_id, |
| 176 | pid); | 286 | pid); |
| 287 | if (!tail) { | ||
| 288 | vidtv_psi_pat_program_destroy(head); | ||
| 289 | return NULL; | ||
| 290 | } | ||
| 177 | 291 | ||
| 178 | if (!head) | 292 | if (!head) |
| 179 | head = tail; | 293 | head = tail; |
| @@ -183,30 +297,30 @@ vidtv_channel_pat_prog_cat_into_new(struct vidtv_mux *m) · 3 unmodified lines | |||
| 183 | 297 | ||
| 184 | cur_chnl = cur_chnl->next; | 298 | cur_chnl = cur_chnl->next; |
| 185 | } | 299 | } |
| 300 | /* Add the NIT table */ | ||
| 301 | vidtv_psi_pat_program_init(tail, 0, TS_NIT_PID); | ||
| 186 | 302 | ||
| 187 | return head; | 303 | return head; |
| 188 | } | 304 | } |
| 189 | 305 | ||
| 306 | /* | ||
| 307 | * Match channels to their respective PMT sections, then assign the | ||
| 308 | * streams | ||
| 309 | */ | ||
| 190 | static void | 310 | static void |
| 191 | vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, | 311 | vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, |
| 192 | struct vidtv_psi_table_pmt **sections, | 312 | struct vidtv_psi_table_pmt **sections, |
| 193 | u32 nsections) | 313 | u32 nsections) |
| 194 | { | 314 | { |
| 195 | /* | ||
| 196 | * Match channels to their respective PMT sections, then assign the | ||
| 197 | * streams | ||
| 198 | */ | ||
| 199 | struct vidtv_psi_table_pmt *curr_section = NULL; | 315 | struct vidtv_psi_table_pmt *curr_section = NULL; |
| 200 | struct vidtv_channel *cur_chnl = channels; | ||
| 201 | |||
| 202 | struct vidtv_psi_table_pmt_stream *s = NULL; | ||
| 203 | struct vidtv_psi_table_pmt_stream *head = NULL; | 316 | struct vidtv_psi_table_pmt_stream *head = NULL; |
| 204 | struct vidtv_psi_table_pmt_stream *tail = NULL; | 317 | struct vidtv_psi_table_pmt_stream *tail = NULL; |
| 205 | 318 | struct vidtv_psi_table_pmt_stream *s = NULL; | |
| 319 | struct vidtv_channel *cur_chnl = channels; | ||
| 206 | struct vidtv_psi_desc *desc = NULL; | 320 | struct vidtv_psi_desc *desc = NULL; |
| 207 | u32 j; | ||
| 208 | u16 curr_id; | ||
| 209 | u16 e_pid; /* elementary stream pid */ | 321 | u16 e_pid; /* elementary stream pid */ |
| 322 | u16 curr_id; | ||
| 323 | u32 j; | ||
| 210 | 324 | ||
| 211 | while (cur_chnl) { | 325 | while (cur_chnl) { |
| 212 | for (j = 0; j < nsections; ++j) { | 326 | for (j = 0; j < nsections; ++j) { |
| @@ -232,7 +346,8 @@ vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, · 19 unmodified lines | |||
| 232 | head = tail; | 346 | head = tail; |
| 233 | 347 | ||
| 234 | desc = vidtv_psi_desc_clone(s->descriptor); | 348 | desc = vidtv_psi_desc_clone(s->descriptor); |
| 235 | vidtv_psi_desc_assign(&tail->descriptor, desc); | 349 | vidtv_psi_desc_assign(&tail->descriptor, |
| 350 | desc); | ||
| 236 | 351 | ||
| 237 | s = s->next; | 352 | s = s->next; |
| 238 | } | 353 | } |
| @@ -246,17 +361,103 @@ vidtv_channel_pmt_match_sections(struct vidtv_channel *channels, · 7 unmodified lines | |||
| 246 | } | 361 | } |
| 247 | } | 362 | } |
| 248 | 363 | ||
| 249 | void vidtv_channel_si_init(struct vidtv_mux *m) | 364 | static void |
| 365 | vidtv_channel_destroy_service_list(struct vidtv_psi_desc_service_list_entry *e) | ||
| 366 | { | ||
| 367 | struct vidtv_psi_desc_service_list_entry *tmp; | ||
| 368 | |||
| 369 | while (e) { | ||
| 370 | tmp = e; | ||
| 371 | e = e->next; | ||
| 372 | kfree(tmp); | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | static struct vidtv_psi_desc_service_list_entry | ||
| 377 | *vidtv_channel_build_service_list(struct vidtv_psi_table_sdt_service *s) | ||
| 378 | { | ||
| 379 | struct vidtv_psi_desc_service_list_entry *curr_e = NULL; | ||
| 380 | struct vidtv_psi_desc_service_list_entry *head_e = NULL; | ||
| 381 | struct vidtv_psi_desc_service_list_entry *prev_e = NULL; | ||
| 382 | struct vidtv_psi_desc *desc = s->descriptor; | ||
| 383 | struct vidtv_psi_desc_service *s_desc; | ||
| 384 | |||
| 385 | while (s) { | ||
| 386 | while (desc) { | ||
| 387 | if (s->descriptor->type != SERVICE_DESCRIPTOR) | ||
| 388 | goto next_desc; | ||
| 389 | |||
| 390 | s_desc = (struct vidtv_psi_desc_service *)desc; | ||
| 391 | |||
| 392 | curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); | ||
| 393 | if (!curr_e) { | ||
| 394 | vidtv_channel_destroy_service_list(head_e); | ||
| 395 | return NULL; | ||
| 396 | } | ||
| 397 | |||
| 398 | curr_e->service_id = s->service_id; | ||
| 399 | curr_e->service_type = s_desc->service_type; | ||
| 400 | |||
| 401 | if (!head_e) | ||
| 402 | head_e = curr_e; | ||
| 403 | if (prev_e) | ||
| 404 | prev_e->next = curr_e; | ||
| 405 | |||
| 406 | prev_e = curr_e; | ||
| 407 | |||
| 408 | next_desc: | ||
| 409 | desc = desc->next; | ||
| 410 | } | ||
| 411 | s = s->next; | ||
| 412 | } | ||
| 413 | return head_e; | ||
| 414 | } | ||
| 415 | |||
| 416 | int vidtv_channel_si_init(struct vidtv_mux *m) | ||
| 250 | { | 417 | { |
| 418 | struct vidtv_psi_desc_service_list_entry *service_list = NULL; | ||
| 251 | struct vidtv_psi_table_pat_program *programs = NULL; | 419 | struct vidtv_psi_table_pat_program *programs = NULL; |
| 252 | struct vidtv_psi_table_sdt_service *services = NULL; | 420 | struct vidtv_psi_table_sdt_service *services = NULL; |
| 421 | struct vidtv_psi_table_eit_event *events = NULL; | ||
| 253 | 422 | ||
| 254 | m->si.pat = vidtv_psi_pat_table_init(m->transport_stream_id); | 423 | m->si.pat = vidtv_psi_pat_table_init(m->transport_stream_id); |
| 424 | if (!m->si.pat) | ||
| 425 | return -ENOMEM; | ||
| 255 | 426 | ||
| 256 | m->si.sdt = vidtv_psi_sdt_table_init(m->transport_stream_id); | 427 | m->si.sdt = vidtv_psi_sdt_table_init(m->network_id, |
| 428 | m->transport_stream_id); | ||
| 429 | if (!m->si.sdt) | ||
| 430 | goto free_pat; | ||
| 257 | 431 | ||
| 258 | programs = vidtv_channel_pat_prog_cat_into_new(m); | 432 | programs = vidtv_channel_pat_prog_cat_into_new(m); |
| 433 | if (!programs) | ||
| 434 | goto free_sdt; | ||
| 259 | services = vidtv_channel_sdt_serv_cat_into_new(m); | 435 | services = vidtv_channel_sdt_serv_cat_into_new(m); |
| 436 | if (!services) | ||
| 437 | goto free_programs; | ||
| 438 | |||
| 439 | events = vidtv_channel_eit_event_cat_into_new(m); | ||
| 440 | if (!events) | ||
| 441 | goto free_services; | ||
| 442 | |||
| 443 | /* look for a service descriptor for every service */ | ||
| 444 | service_list = vidtv_channel_build_service_list(services); | ||
| 445 | if (!service_list) | ||
| 446 | goto free_events; | ||
| 447 | |||
| 448 | /* use these descriptors to build the NIT */ | ||
| 449 | m->si.nit = vidtv_psi_nit_table_init(m->network_id, | ||
| 450 | m->transport_stream_id, | ||
| 451 | m->network_name, | ||
| 452 | service_list); | ||
| 453 | if (!m->si.nit) | ||
| 454 | goto free_service_list; | ||
| 455 | |||
| 456 | m->si.eit = vidtv_psi_eit_table_init(m->network_id, | ||
| 457 | m->transport_stream_id, | ||
| 458 | programs->service_id); | ||
| 459 | if (!m->si.eit) | ||
| 460 | goto free_nit; | ||
| 260 | 461 | ||
| 261 | /* assemble all programs and assign to PAT */ | 462 | /* assemble all programs and assign to PAT */ |
| 262 | vidtv_psi_pat_program_assign(m->si.pat, programs); | 463 | vidtv_psi_pat_program_assign(m->si.pat, programs); |
| @@ -264,31 +465,65 @@ void vidtv_channel_si_init(struct vidtv_mux *m) · 1 unmodified line | |||
| 264 | /* assemble all services and assign to SDT */ | 465 | /* assemble all services and assign to SDT */ |
| 265 | vidtv_psi_sdt_service_assign(m->si.sdt, services); | 466 | vidtv_psi_sdt_service_assign(m->si.sdt, services); |
| 266 | 467 | ||
| 267 | m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, m->pcr_pid); | 468 | /* assemble all events and assign to EIT */ |
| 469 | vidtv_psi_eit_event_assign(m->si.eit, events); | ||
| 470 | |||
| 471 | m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, | ||
| 472 | m->pcr_pid); | ||
| 473 | if (!m->si.pmt_secs) | ||
| 474 | goto free_eit; | ||
| 268 | 475 | ||
| 269 | vidtv_channel_pmt_match_sections(m->channels, | 476 | vidtv_channel_pmt_match_sections(m->channels, |
| 270 | m->si.pmt_secs, | 477 | m->si.pmt_secs, |
| 271 | m->si.pat->programs); | 478 | m->si.pat->num_pmt); |
| 479 | |||
| 480 | vidtv_channel_destroy_service_list(service_list); | ||
| 481 | |||
| 482 | return 0; | ||
| 483 | |||
| 484 | free_eit: | ||
| 485 | vidtv_psi_eit_table_destroy(m->si.eit); | ||
| 486 | free_nit: | ||
| 487 | vidtv_psi_nit_table_destroy(m->si.nit); | ||
| 488 | free_service_list: | ||
| 489 | vidtv_channel_destroy_service_list(service_list); | ||
| 490 | free_events: | ||
| 491 | vidtv_psi_eit_event_destroy(events); | ||
| 492 | free_services: | ||
| 493 | vidtv_psi_sdt_service_destroy(services); | ||
| 494 | free_programs: | ||
| 495 | vidtv_psi_pat_program_destroy(programs); | ||
| 496 | free_sdt: | ||
| 497 | vidtv_psi_sdt_table_destroy(m->si.sdt); | ||
| 498 | free_pat: | ||
| 499 | vidtv_psi_pat_table_destroy(m->si.pat); | ||
| 500 | return 0; | ||
| 272 | } | 501 | } |
| 273 | 502 | ||
| 274 | void vidtv_channel_si_destroy(struct vidtv_mux *m) | 503 | void vidtv_channel_si_destroy(struct vidtv_mux *m) |
| 275 | { | 504 | { |
| 276 | u32 i; | 505 | u32 i; |
| 277 | u16 num_programs = m->si.pat->programs; | ||
| 278 | 506 | ||
| 279 | vidtv_psi_pat_table_destroy(m->si.pat); | 507 | vidtv_psi_pat_table_destroy(m->si.pat); |
| 280 | 508 | ||
| 281 | for (i = 0; i < num_programs; ++i) | 509 | for (i = 0; i < m->si.pat->num_pmt; ++i) |
| 282 | vidtv_psi_pmt_table_destroy(m->si.pmt_secs[i]); | 510 | vidtv_psi_pmt_table_destroy(m->si.pmt_secs[i]); |
| 283 | 511 | ||
| 284 | kfree(m->si.pmt_secs); | 512 | kfree(m->si.pmt_secs); |
| 285 | vidtv_psi_sdt_table_destroy(m->si.sdt); | 513 | vidtv_psi_sdt_table_destroy(m->si.sdt); |
| 514 | vidtv_psi_nit_table_destroy(m->si.nit); | ||
| 515 | vidtv_psi_eit_table_destroy(m->si.eit); | ||
| 286 | } | 516 | } |
| 287 | 517 | ||
| 288 | void vidtv_channels_init(struct vidtv_mux *m) | 518 | int vidtv_channels_init(struct vidtv_mux *m) |
| 289 | { | 519 | { |
| 290 | /* this is the place to add new 'channels' for vidtv */ | 520 | /* this is the place to add new 'channels' for vidtv */ |
| 291 | m->channels = vidtv_channel_s302m_init(NULL, m->transport_stream_id); | 521 | m->channels = vidtv_channel_s302m_init(NULL, m->transport_stream_id); |
| 522 | |||
| 523 | if (!m->channels) | ||
| 524 | return -ENOMEM; | ||
| 525 | |||
| 526 | return 0; | ||
| 292 | } | 527 | } |
| 293 | 528 | ||
| 294 | void vidtv_channels_destroy(struct vidtv_mux *m) | 529 | void vidtv_channels_destroy(struct vidtv_mux *m) |
| @@ -302,6 +537,7 @@ void vidtv_channels_destroy(struct vidtv_mux *m) · 7 unmodified lines | |||
| 302 | vidtv_psi_pat_program_destroy(curr->program); | 537 | vidtv_psi_pat_program_destroy(curr->program); |
| 303 | vidtv_psi_pmt_stream_destroy(curr->streams); | 538 | vidtv_psi_pmt_stream_destroy(curr->streams); |
| 304 | vidtv_channel_encoder_destroy(curr->encoders); | 539 | vidtv_channel_encoder_destroy(curr->encoders); |
| 540 | vidtv_psi_eit_event_destroy(curr->events); | ||
| 305 | 541 | ||
| 306 | tmp = curr; | 542 | tmp = curr; |
| 307 | curr = curr->next; | 543 | curr = curr->next; |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | * When vidtv boots, it will create some hardcoded channels. | 9 | * When vidtv boots, it will create some hardcoded channels. |
| 10 | * Their services will be concatenated to populate the SDT. | 10 | * Their services will be concatenated to populate the SDT. |
| 11 | * Their programs will be concatenated to populate the PAT | 11 | * Their programs will be concatenated to populate the PAT |
| 12 | * Their events will be concatenated to populate the EIT | ||
| 12 | * For each program in the PAT, a PMT section will be created | 13 | * For each program in the PAT, a PMT section will be created |
| 13 | * The PMT section for a channel will be assigned its streams. | 14 | * The PMT section for a channel will be assigned its streams. |
| 14 | * Every stream will have its corresponding encoder polled to produce TS packets | 15 | * Every stream will have its corresponding encoder polled to produce TS packets |
| @@ -22,9 +23,10 @@ · 7 unmodified lines | |||
| 22 | #define VIDTV_CHANNEL_H | 23 | #define VIDTV_CHANNEL_H |
| 23 | 24 | ||
| 24 | #include <linux/types.h> | 25 | #include <linux/types.h> |
| 25 | #include "vidtv_psi.h" | 26 | |
| 26 | #include "vidtv_encoder.h" | 27 | #include "vidtv_encoder.h" |
| 27 | #include "vidtv_mux.h" | 28 | #include "vidtv_mux.h" |
| 29 | #include "vidtv_psi.h" | ||
| 28 | 30 | ||
| 29 | /** | 31 | /** |
| 30 | * struct vidtv_channel - A 'channel' abstraction | 32 | * struct vidtv_channel - A 'channel' abstraction |
| @@ -37,6 +39,7 @@ · 6 unmodified lines | |||
| 37 | * Every stream will have its corresponding encoder polled to produce TS packets | 39 | * Every stream will have its corresponding encoder polled to produce TS packets |
| 38 | * These packets may be interleaved by the mux and then delivered to the bridge | 40 | * These packets may be interleaved by the mux and then delivered to the bridge |
| 39 | * | 41 | * |
| 42 | * @name: name of the channel | ||
| 40 | * @transport_stream_id: a number to identify the TS, chosen at will. | 43 | * @transport_stream_id: a number to identify the TS, chosen at will. |
| 41 | * @service: A _single_ service. Will be concatenated into the SDT. | 44 | * @service: A _single_ service. Will be concatenated into the SDT. |
| 42 | * @program_num: The link between PAT, PMT and SDT. | 45 | * @program_num: The link between PAT, PMT and SDT. |
| @@ -44,6 +47,7 @@ · 1 unmodified line | |||
| 44 | * Will be concatenated into the PAT. | 47 | * Will be concatenated into the PAT. |
| 45 | * @streams: A stream loop used to populate the PMT section for 'program' | 48 | * @streams: A stream loop used to populate the PMT section for 'program' |
| 46 | * @encoders: A encoder loop. There must be one encoder for each stream. | 49 | * @encoders: A encoder loop. There must be one encoder for each stream. |
| 50 | * @events: Optional event information. This will feed into the EIT. | ||
| 47 | * @next: Optionally chain this channel. | 51 | * @next: Optionally chain this channel. |
| 48 | */ | 52 | */ |
| 49 | struct vidtv_channel { | 53 | struct vidtv_channel { |
| @@ -54,6 +58,7 @@ struct vidtv_channel { · 4 unmodified lines | |||
| 54 | struct vidtv_psi_table_pat_program *program; | 58 | struct vidtv_psi_table_pat_program *program; |
| 55 | struct vidtv_psi_table_pmt_stream *streams; | 59 | struct vidtv_psi_table_pmt_stream *streams; |
| 56 | struct vidtv_encoder *encoders; | 60 | struct vidtv_encoder *encoders; |
| 61 | struct vidtv_psi_table_eit_event *events; | ||
| 57 | struct vidtv_channel *next; | 62 | struct vidtv_channel *next; |
| 58 | }; | 63 | }; |
| 59 | 64 | ||
| @@ -61,14 +66,14 @@ struct vidtv_channel { · 1 unmodified line | |||
| 61 | * vidtv_channel_si_init - Init the PSI tables from the channels in the mux | 66 | * vidtv_channel_si_init - Init the PSI tables from the channels in the mux |
| 62 | * @m: The mux containing the channels. | 67 | * @m: The mux containing the channels. |
| 63 | */ | 68 | */ |
| 64 | void vidtv_channel_si_init(struct vidtv_mux *m); | 69 | int vidtv_channel_si_init(struct vidtv_mux *m); |
| 65 | void vidtv_channel_si_destroy(struct vidtv_mux *m); | 70 | void vidtv_channel_si_destroy(struct vidtv_mux *m); |
| 66 | 71 | ||
| 67 | /** | 72 | /** |
| 68 | * vidtv_channels_init - Init hardcoded, fake 'channels'. | 73 | * vidtv_channels_init - Init hardcoded, fake 'channels'. |
| 69 | * @m: The mux to store the channels into. | 74 | * @m: The mux to store the channels into. |
| 70 | */ | 75 | */ |
| 71 | void vidtv_channels_init(struct vidtv_mux *m); | 76 | int vidtv_channels_init(struct vidtv_mux *m); |
| 72 | struct vidtv_channel | 77 | struct vidtv_channel |
| 73 | *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id); | 78 | *vidtv_channel_s302m_init(struct vidtv_channel *head, u16 transport_stream_id); |
| 74 | void vidtv_channels_destroy(struct vidtv_mux *m); | 79 | void vidtv_channels_destroy(struct vidtv_mux *m); |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | |||
| 16 | #define CLOCK_UNIT_27MHZ 27000000 | 16 | #define CLOCK_UNIT_27MHZ 27000000 |
| 17 | #define VIDTV_SLEEP_USECS 10000 | 17 | #define VIDTV_SLEEP_USECS 10000 |
| 18 | #define VIDTV_MAX_SLEEP_USECS (2 * VIDTV_SLEEP_USECS) | 18 | #define VIDTV_MAX_SLEEP_USECS (2 * VIDTV_SLEEP_USECS) |
| 19 | #define VIDTV_DEFAULT_TS_ID 0x744 | ||
| 20 | 19 | ||
| 21 | u32 vidtv_memcpy(void *to, | 20 | u32 vidtv_memcpy(void *to, |
| 22 | size_t to_offset, | 21 | size_t to_offset, |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
| 21 | #include <linux/workqueue.h> | 21 | #include <linux/workqueue.h> |
| 22 | |||
| 22 | #include <media/dvb_frontend.h> | 23 | #include <media/dvb_frontend.h> |
| 23 | 24 | ||
| 24 | #include "vidtv_demod.h" | 25 | #include "vidtv_demod.h" |
| @@ -192,7 +193,6 @@ static void vidtv_demod_update_stats(struct dvb_frontend *fe) · 167 unmodified lines | |||
| 192 | 193 | ||
| 193 | c->cnr.stat[0].svalue = state->tuner_cnr; | 194 | c->cnr.stat[0].svalue = state->tuner_cnr; |
| 194 | c->cnr.stat[0].svalue -= prandom_u32_max(state->tuner_cnr / 50); | 195 | c->cnr.stat[0].svalue -= prandom_u32_max(state->tuner_cnr / 50); |
| 195 | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | static int vidtv_demod_read_status(struct dvb_frontend *fe, | 198 | static int vidtv_demod_read_status(struct dvb_frontend *fe, |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #define VIDTV_DEMOD_H | 12 | #define VIDTV_DEMOD_H |
| 13 | 13 | ||
| 14 | #include <linux/dvb/frontend.h> | 14 | #include <linux/dvb/frontend.h> |
| 15 | |||
| 15 | #include <media/dvb_frontend.h> | 16 | #include <media/dvb_frontend.h> |
| 16 | 17 | ||
| 17 | /** | 18 | /** |
| @@ -19,6 +20,9 @@ · 1 unmodified line | |||
| 19 | * modulation and fec_inner | 20 | * modulation and fec_inner |
| 20 | * @modulation: see enum fe_modulation | 21 | * @modulation: see enum fe_modulation |
| 21 | * @fec: see enum fe_fec_rate | 22 | * @fec: see enum fe_fec_rate |
| 23 | * @cnr_ok: S/N threshold to consider the signal as OK. Below that, there's | ||
| 24 | * a chance of losing sync. | ||
| 25 | * @cnr_good: S/N threshold to consider the signal strong. | ||
| 22 | * | 26 | * |
| 23 | * This struct matches values for 'good' and 'ok' CNRs given the combination | 27 | * This struct matches values for 'good' and 'ok' CNRs given the combination |
| 24 | * of modulation and fec_inner in use. We might simulate some noise if the | 28 | * of modulation and fec_inner in use. We might simulate some noise if the |
| @@ -52,13 +56,8 @@ struct vidtv_demod_config { · 27 unmodified lines | |||
| 52 | * struct vidtv_demod_state - The demodulator state | 56 | * struct vidtv_demod_state - The demodulator state |
| 53 | * @frontend: The frontend structure allocated by the demod. | 57 | * @frontend: The frontend structure allocated by the demod. |
| 54 | * @config: The config used to init the demod. | 58 | * @config: The config used to init the demod. |
| 55 | * @poll_snr: The task responsible for periodically checking the simulated | ||
| 56 | * signal quality, eventually dropping or reacquiring the TS lock. | ||
| 57 | * @status: the demod status. | 59 | * @status: the demod status. |
| 58 | * @cold_start: Whether the demod has not been init yet. | 60 | * @tuner_cnr: current S/N ratio for the signal carrier |
| 59 | * @poll_snr_thread_running: Whether the task responsible for periodically | ||
| 60 | * checking the simulated signal quality is running. | ||
| 61 | * @poll_snr_thread_restart: Whether we should restart the poll_snr task. | ||
| 62 | */ | 61 | */ |
| 63 | struct vidtv_demod_state { | 62 | struct vidtv_demod_state { |
| 64 | struct dvb_frontend frontend; | 63 | struct dvb_frontend frontend; |
| @@ -28,7 +28,7 @@ struct vidtv_access_unit { · 27 unmodified lines | |||
| 28 | struct vidtv_access_unit *next; | 28 | struct vidtv_access_unit *next; |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | /* Some musical notes, used by a tone generator */ | 31 | /* Some musical notes, used by a tone generator. Values are in Hz */ |
| 32 | enum musical_notes { | 32 | enum musical_notes { |
| 33 | NOTE_SILENT = 0, | 33 | NOTE_SILENT = 0, |
| 34 | 34 | ||
| @@ -103,14 +103,16 @@ enum musical_notes { · 68 unmodified lines | |||
| 103 | * @encoder_buf_sz: The encoder buffer size, in bytes | 103 | * @encoder_buf_sz: The encoder buffer size, in bytes |
| 104 | * @encoder_buf_offset: Our byte position in the encoder buffer. | 104 | * @encoder_buf_offset: Our byte position in the encoder buffer. |
| 105 | * @sample_count: How many samples we have encoded in total. | 105 | * @sample_count: How many samples we have encoded in total. |
| 106 | * @access_units: encoder payload units, used for clock references | ||
| 106 | * @src_buf: The source of raw data to be encoded, encoder might set a | 107 | * @src_buf: The source of raw data to be encoded, encoder might set a |
| 107 | * default if null. | 108 | * default if null. |
| 109 | * @src_buf_sz: size of @src_buf. | ||
| 108 | * @src_buf_offset: Our position in the source buffer. | 110 | * @src_buf_offset: Our position in the source buffer. |
| 109 | * @is_video_encoder: Whether this a video encoder (as opposed to audio) | 111 | * @is_video_encoder: Whether this a video encoder (as opposed to audio) |
| 110 | * @ctx: Encoder-specific state. | 112 | * @ctx: Encoder-specific state. |
| 111 | * @stream_id: Examples: Audio streams (0xc0-0xdf), Video streams | 113 | * @stream_id: Examples: Audio streams (0xc0-0xdf), Video streams |
| 112 | * (0xe0-0xef). | 114 | * (0xe0-0xef). |
| 113 | * @es_id: The TS PID to use for the elementary stream in this encoder. | 115 | * @es_pid: The TS PID to use for the elementary stream in this encoder. |
| 114 | * @encode: Prepare enough AUs for the given amount of time. | 116 | * @encode: Prepare enough AUs for the given amount of time. |
| 115 | * @clear: Clear the encoder output. | 117 | * @clear: Clear the encoder output. |
| 116 | * @sync: Attempt to synchronize with this encoder. | 118 | * @sync: Attempt to synchronize with this encoder. |
| @@ -131,9 +133,6 @@ struct vidtv_encoder { · 14 unmodified lines | |||
| 131 | u32 encoder_buf_offset; | 133 | u32 encoder_buf_offset; |
| 132 | 134 | ||
| 133 | u64 sample_count; | 135 | u64 sample_count; |
| 134 | int last_duration; | ||
| 135 | int note_offset; | ||
| 136 | enum musical_notes last_tone; | ||
| 137 | 136 | ||
| 138 | struct vidtv_access_unit *access_units; | 137 | struct vidtv_access_unit *access_units; |
| 139 | 138 | ||
| @@ -12,23 +12,23 @@ · 11 unmodified lines | |||
| 12 | * Copyright (C) 2020 Daniel W. S. Almeida | 12 | * Copyright (C) 2020 Daniel W. S. Almeida |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/dev_printk.h> |
| 17 | #include <linux/jiffies.h> | 17 | #include <linux/jiffies.h> |
| 18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 19 | #include <linux/dev_printk.h> | 19 | #include <linux/math64.h> |
| 20 | #include <linux/ratelimit.h> | 20 | #include <linux/ratelimit.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/types.h> | ||
| 22 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
| 23 | #include <linux/math64.h> | ||
| 24 | 24 | ||
| 25 | #include "vidtv_mux.h" | ||
| 26 | #include "vidtv_ts.h" | ||
| 27 | #include "vidtv_pes.h" | ||
| 28 | #include "vidtv_encoder.h" | ||
| 29 | #include "vidtv_channel.h" | 25 | #include "vidtv_channel.h" |
| 30 | #include "vidtv_common.h" | 26 | #include "vidtv_common.h" |
| 27 | #include "vidtv_encoder.h" | ||
| 28 | #include "vidtv_mux.h" | ||
| 29 | #include "vidtv_pes.h" | ||
| 31 | #include "vidtv_psi.h" | 30 | #include "vidtv_psi.h" |
| 31 | #include "vidtv_ts.h" | ||
| 32 | 32 | ||
| 33 | static struct vidtv_mux_pid_ctx | 33 | static struct vidtv_mux_pid_ctx |
| 34 | *vidtv_mux_get_pid_ctx(struct vidtv_mux *m, u16 pid) | 34 | *vidtv_mux_get_pid_ctx(struct vidtv_mux *m, u16 pid) |
| @@ -47,33 +47,56 @@ static struct vidtv_mux_pid_ctx · 12 unmodified lines | |||
| 47 | struct vidtv_mux_pid_ctx *ctx; | 47 | struct vidtv_mux_pid_ctx *ctx; |
| 48 | 48 | ||
| 49 | ctx = vidtv_mux_get_pid_ctx(m, pid); | 49 | ctx = vidtv_mux_get_pid_ctx(m, pid); |
| 50 | |||
| 51 | if (ctx) | 50 | if (ctx) |
| 52 | goto end; | 51 | return ctx; |
| 52 | |||
| 53 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
| 54 | if (!ctx) | ||
| 55 | return NULL; | ||
| 53 | 56 | ||
| 54 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
| 55 | ctx->pid = pid; | 57 | ctx->pid = pid; |
| 56 | ctx->cc = 0; | 58 | ctx->cc = 0; |
| 57 | hash_add(m->pid_ctx, &ctx->h, pid); | 59 | hash_add(m->pid_ctx, &ctx->h, pid); |
| 58 | 60 | ||
| 59 | end: | ||
| 60 | return ctx; | 61 | return ctx; |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 63 | static void vidtv_mux_pid_ctx_init(struct vidtv_mux *m) | 64 | static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m) |
| 65 | { | ||
| 66 | struct vidtv_mux_pid_ctx *ctx; | ||
| 67 | struct hlist_node *tmp; | ||
| 68 | int bkt; | ||
| 69 | |||
| 70 | hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) { | ||
| 71 | hash_del(&ctx->h); | ||
| 72 | kfree(ctx); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | static int vidtv_mux_pid_ctx_init(struct vidtv_mux *m) | ||
| 64 | { | 77 | { |
| 65 | struct vidtv_psi_table_pat_program *p = m->si.pat->program; | 78 | struct vidtv_psi_table_pat_program *p = m->si.pat->program; |
| 66 | u16 pid; | 79 | u16 pid; |
| 67 | 80 | ||
| 68 | hash_init(m->pid_ctx); | 81 | hash_init(m->pid_ctx); |
| 69 | /* push the pcr pid ctx */ | 82 | /* push the pcr pid ctx */ |
| 70 | vidtv_mux_create_pid_ctx_once(m, m->pcr_pid); | 83 | if (!vidtv_mux_create_pid_ctx_once(m, m->pcr_pid)) |
| 71 | /* push the null packet pid ctx */ | 84 | return -ENOMEM; |
| 72 | vidtv_mux_create_pid_ctx_once(m, TS_NULL_PACKET_PID); | 85 | /* push the NULL packet pid ctx */ |
| 86 | if (!vidtv_mux_create_pid_ctx_once(m, TS_NULL_PACKET_PID)) | ||
| 87 | goto free; | ||
| 73 | /* push the PAT pid ctx */ | 88 | /* push the PAT pid ctx */ |
| 74 | vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID); | 89 | if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_PAT_PID)) |
| 90 | goto free; | ||
| 75 | /* push the SDT pid ctx */ | 91 | /* push the SDT pid ctx */ |
| 76 | vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID); | 92 | if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_SDT_PID)) |
| 93 | goto free; | ||
| 94 | /* push the NIT pid ctx */ | ||
| 95 | if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_NIT_PID)) | ||
| 96 | goto free; | ||
| 97 | /* push the EIT pid ctx */ | ||
| 98 | if (!vidtv_mux_create_pid_ctx_once(m, VIDTV_EIT_PID)) | ||
| 99 | goto free; | ||
| 77 | 100 | ||
| 78 | /* add a ctx for all PMT sections */ | 101 | /* add a ctx for all PMT sections */ |
| 79 | while (p) { | 102 | while (p) { |
| @@ -81,18 +104,12 @@ static void vidtv_mux_pid_ctx_init(struct vidtv_mux *m) · 1 unmodified line | |||
| 81 | vidtv_mux_create_pid_ctx_once(m, pid); | 104 | vidtv_mux_create_pid_ctx_once(m, pid); |
| 82 | p = p->next; | 105 | p = p->next; |
| 83 | } | 106 | } |
| 84 | } | ||
| 85 | 107 | ||
| 86 | static void vidtv_mux_pid_ctx_destroy(struct vidtv_mux *m) | 108 | return 0; |
| 87 | { | ||
| 88 | int bkt; | ||
| 89 | struct vidtv_mux_pid_ctx *ctx; | ||
| 90 | struct hlist_node *tmp; | ||
| 91 | 109 | ||
| 92 | hash_for_each_safe(m->pid_ctx, bkt, tmp, ctx, h) { | 110 | free: |
| 93 | hash_del(&ctx->h); | 111 | vidtv_mux_pid_ctx_destroy(m); |
| 94 | kfree(ctx); | 112 | return -ENOMEM; |
| 95 | } | ||
| 96 | } | 113 | } |
| 97 | 114 | ||
| 98 | static void vidtv_mux_update_clk(struct vidtv_mux *m) | 115 | static void vidtv_mux_update_clk(struct vidtv_mux *m) |
| @@ -112,32 +129,53 @@ static void vidtv_mux_update_clk(struct vidtv_mux *m) · 13 unmodified lines | |||
| 112 | 129 | ||
| 113 | static u32 vidtv_mux_push_si(struct vidtv_mux *m) | 130 | static u32 vidtv_mux_push_si(struct vidtv_mux *m) |
| 114 | { | 131 | { |
| 132 | struct vidtv_psi_pat_write_args pat_args = { | ||
| 133 | .buf = m->mux_buf, | ||
| 134 | .buf_sz = m->mux_buf_sz, | ||
| 135 | .pat = m->si.pat, | ||
| 136 | }; | ||
| 137 | struct vidtv_psi_pmt_write_args pmt_args = { | ||
| 138 | .buf = m->mux_buf, | ||
| 139 | .buf_sz = m->mux_buf_sz, | ||
| 140 | .pcr_pid = m->pcr_pid, | ||
| 141 | }; | ||
| 142 | struct vidtv_psi_sdt_write_args sdt_args = { | ||
| 143 | .buf = m->mux_buf, | ||
| 144 | .buf_sz = m->mux_buf_sz, | ||
| 145 | .sdt = m->si.sdt, | ||
| 146 | }; | ||
| 147 | struct vidtv_psi_nit_write_args nit_args = { | ||
| 148 | .buf = m->mux_buf, | ||
| 149 | .buf_sz = m->mux_buf_sz, | ||
| 150 | .nit = m->si.nit, | ||
| 151 | |||
| 152 | }; | ||
| 153 | struct vidtv_psi_eit_write_args eit_args = { | ||
| 154 | .buf = m->mux_buf, | ||
| 155 | .buf_sz = m->mux_buf_sz, | ||
| 156 | .eit = m->si.eit, | ||
| 157 | }; | ||
| 115 | u32 initial_offset = m->mux_buf_offset; | 158 | u32 initial_offset = m->mux_buf_offset; |
| 116 | |||
| 117 | struct vidtv_mux_pid_ctx *pat_ctx; | 159 | struct vidtv_mux_pid_ctx *pat_ctx; |
| 118 | struct vidtv_mux_pid_ctx *pmt_ctx; | 160 | struct vidtv_mux_pid_ctx *pmt_ctx; |
| 119 | struct vidtv_mux_pid_ctx *sdt_ctx; | 161 | struct vidtv_mux_pid_ctx *sdt_ctx; |
| 120 | 162 | struct vidtv_mux_pid_ctx *nit_ctx; | |
| 121 | struct vidtv_psi_pat_write_args pat_args = {}; | 163 | struct vidtv_mux_pid_ctx *eit_ctx; |
| 122 | struct vidtv_psi_pmt_write_args pmt_args = {}; | 164 | u32 nbytes; |
| 123 | struct vidtv_psi_sdt_write_args sdt_args = {}; | ||
| 124 | |||
| 125 | u32 nbytes; /* the number of bytes written by this function */ | ||
| 126 | u16 pmt_pid; | 165 | u16 pmt_pid; |
| 127 | u32 i; | 166 | u32 i; |
| 128 | 167 | ||
| 129 | pat_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_PAT_PID); | 168 | pat_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_PAT_PID); |
| 130 | sdt_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_SDT_PID); | 169 | sdt_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_SDT_PID); |
| 170 | nit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_NIT_PID); | ||
| 171 | eit_ctx = vidtv_mux_get_pid_ctx(m, VIDTV_EIT_PID); | ||
| 131 | 172 | ||
| 132 | pat_args.buf = m->mux_buf; | ||
| 133 | pat_args.offset = m->mux_buf_offset; | 173 | pat_args.offset = m->mux_buf_offset; |
| 134 | pat_args.pat = m->si.pat; | ||
| 135 | pat_args.buf_sz = m->mux_buf_sz; | ||
| 136 | pat_args.continuity_counter = &pat_ctx->cc; | 174 | pat_args.continuity_counter = &pat_ctx->cc; |
| 137 | 175 | ||
| 138 | m->mux_buf_offset += vidtv_psi_pat_write_into(pat_args); | 176 | m->mux_buf_offset += vidtv_psi_pat_write_into(&pat_args); |
| 139 | 177 | ||
| 140 | for (i = 0; i < m->si.pat->programs; ++i) { | 178 | for (i = 0; i < m->si.pat->num_pmt; ++i) { |
| 141 | pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i], | 179 | pmt_pid = vidtv_psi_pmt_get_pid(m->si.pmt_secs[i], |
| 142 | m->si.pat); | 180 | m->si.pat); |
| 143 | 181 | ||
| @@ -149,25 +187,29 @@ static u32 vidtv_mux_push_si(struct vidtv_mux *m) · 5 unmodified lines | |||
| 149 | 187 | ||
| 150 | pmt_ctx = vidtv_mux_get_pid_ctx(m, pmt_pid); | 188 | pmt_ctx = vidtv_mux_get_pid_ctx(m, pmt_pid); |
| 151 | 189 | ||
| 152 | pmt_args.buf = m->mux_buf; | ||
| 153 | pmt_args.offset = m->mux_buf_offset; | 190 | pmt_args.offset = m->mux_buf_offset; |
| 154 | pmt_args.pmt = m->si.pmt_secs[i]; | 191 | pmt_args.pmt = m->si.pmt_secs[i]; |
| 155 | pmt_args.pid = pmt_pid; | 192 | pmt_args.pid = pmt_pid; |
| 156 | pmt_args.buf_sz = m->mux_buf_sz; | ||
| 157 | pmt_args.continuity_counter = &pmt_ctx->cc; | 193 | pmt_args.continuity_counter = &pmt_ctx->cc; |
| 158 | pmt_args.pcr_pid = m->pcr_pid; | ||
| 159 | 194 | ||
| 160 | /* write each section into buffer */ | 195 | /* write each section into buffer */ |
| 161 | m->mux_buf_offset += vidtv_psi_pmt_write_into(pmt_args); | 196 | m->mux_buf_offset += vidtv_psi_pmt_write_into(&pmt_args); |
| 162 | } | 197 | } |
| 163 | 198 | ||
| 164 | sdt_args.buf = m->mux_buf; | ||
| 165 | sdt_args.offset = m->mux_buf_offset; | 199 | sdt_args.offset = m->mux_buf_offset; |
| 166 | sdt_args.sdt = m->si.sdt; | ||
| 167 | sdt_args.buf_sz = m->mux_buf_sz; | ||
| 168 | sdt_args.continuity_counter = &sdt_ctx->cc; | 200 | sdt_args.continuity_counter = &sdt_ctx->cc; |
| 169 | 201 | ||
| 170 | m->mux_buf_offset += vidtv_psi_sdt_write_into(sdt_args); | 202 | m->mux_buf_offset += vidtv_psi_sdt_write_into(&sdt_args); |
| 203 | |||
| 204 | nit_args.offset = m->mux_buf_offset; | ||
| 205 | nit_args.continuity_counter = &nit_ctx->cc; | ||
| 206 | |||
| 207 | m->mux_buf_offset += vidtv_psi_nit_write_into(&nit_args); | ||
| 208 | |||
| 209 | eit_args.offset = m->mux_buf_offset; | ||
| 210 | eit_args.continuity_counter = &eit_ctx->cc; | ||
| 211 | |||
| 212 | m->mux_buf_offset += vidtv_psi_eit_write_into(&eit_args); | ||
| 171 | 213 | ||
| 172 | nbytes = m->mux_buf_offset - initial_offset; | 214 | nbytes = m->mux_buf_offset - initial_offset; |
| 173 | 215 | ||
| @@ -230,23 +272,29 @@ static bool vidtv_mux_should_push_si(struct vidtv_mux *m) · 56 unmodified lines | |||
| 230 | static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, | 272 | static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, |
| 231 | struct vidtv_encoder *e) | 273 | struct vidtv_encoder *e) |
| 232 | { | 274 | { |
| 233 | u32 nbytes = 0; | 275 | struct pes_write_args args = { |
| 234 | 276 | .dest_buf = m->mux_buf, | |
| 235 | struct pes_write_args args = {}; | 277 | .dest_buf_sz = m->mux_buf_sz, |
| 236 | u32 initial_offset = m->mux_buf_offset; | 278 | .pid = be16_to_cpu(e->es_pid), |
| 279 | .encoder_id = e->id, | ||
| 280 | .stream_id = be16_to_cpu(e->stream_id), | ||
| 281 | .send_pts = true, /* forbidden value '01'... */ | ||
| 282 | .send_dts = false, /* ...for PTS_DTS flags */ | ||
| 283 | }; | ||
| 237 | struct vidtv_access_unit *au = e->access_units; | 284 | struct vidtv_access_unit *au = e->access_units; |
| 238 | 285 | u32 initial_offset = m->mux_buf_offset; | |
| 286 | struct vidtv_mux_pid_ctx *pid_ctx; | ||
| 287 | u32 nbytes = 0; | ||
| 239 | u8 *buf = NULL; | 288 | u8 *buf = NULL; |
| 240 | struct vidtv_mux_pid_ctx *pid_ctx = vidtv_mux_create_pid_ctx_once(m, | ||
| 241 | be16_to_cpu(e->es_pid)); | ||
| 242 | 289 | ||
| 243 | args.dest_buf = m->mux_buf; | 290 | /* see SMPTE 302M clause 6.4 */ |
| 244 | args.dest_buf_sz = m->mux_buf_sz; | 291 | if (args.encoder_id == S302M) { |
| 245 | args.pid = be16_to_cpu(e->es_pid); | 292 | args.send_dts = false; |
| 246 | args.encoder_id = e->id; | 293 | args.send_pts = true; |
| 294 | } | ||
| 295 | |||
| 296 | pid_ctx = vidtv_mux_create_pid_ctx_once(m, be16_to_cpu(e->es_pid)); | ||
| 247 | args.continuity_counter = &pid_ctx->cc; | 297 | args.continuity_counter = &pid_ctx->cc; |
| 248 | args.stream_id = be16_to_cpu(e->stream_id); | ||
| 249 | args.send_pts = true; | ||
| 250 | 298 | ||
| 251 | while (au) { | 299 | while (au) { |
| 252 | buf = e->encoder_buf + au->offset; | 300 | buf = e->encoder_buf + au->offset; |
| @@ -256,7 +304,7 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, · 3 unmodified lines | |||
| 256 | args.pts = au->pts; | 304 | args.pts = au->pts; |
| 257 | args.pcr = m->timing.clk; | 305 | args.pcr = m->timing.clk; |
| 258 | 306 | ||
| 259 | m->mux_buf_offset += vidtv_pes_write_into(args); | 307 | m->mux_buf_offset += vidtv_pes_write_into(&args); |
| 260 | 308 | ||
| 261 | au = au->next; | 309 | au = au->next; |
| 262 | } | 310 | } |
| @@ -273,10 +321,10 @@ static u32 vidtv_mux_packetize_access_units(struct vidtv_mux *m, · 10 unmodified lines | |||
| 273 | 321 | ||
| 274 | static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m) | 322 | static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m) |
| 275 | { | 323 | { |
| 276 | u32 nbytes = 0; | ||
| 277 | u32 au_nbytes; | ||
| 278 | struct vidtv_channel *cur_chnl = m->channels; | 324 | struct vidtv_channel *cur_chnl = m->channels; |
| 279 | struct vidtv_encoder *e = NULL; | 325 | struct vidtv_encoder *e = NULL; |
| 326 | u32 nbytes = 0; | ||
| 327 | u32 au_nbytes; | ||
| 280 | 328 | ||
| 281 | while (cur_chnl) { | 329 | while (cur_chnl) { |
| 282 | e = cur_chnl->encoders; | 330 | e = cur_chnl->encoders; |
| @@ -300,18 +348,19 @@ static u32 vidtv_mux_poll_encoders(struct vidtv_mux *m) · 17 unmodified lines | |||
| 300 | 348 | ||
| 301 | static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts) | 349 | static u32 vidtv_mux_pad_with_nulls(struct vidtv_mux *m, u32 npkts) |
| 302 | { | 350 | { |
| 303 | struct null_packet_write_args args = {}; | 351 | struct null_packet_write_args args = { |
| 352 | .dest_buf = m->mux_buf, | ||
| 353 | .buf_sz = m->mux_buf_sz, | ||
| 354 | .dest_offset = m->mux_buf_offset, | ||
| 355 | }; | ||
| 304 | u32 initial_offset = m->mux_buf_offset; | 356 | u32 initial_offset = m->mux_buf_offset; |
| 305 | u32 nbytes; /* the number of bytes written by this function */ | ||
| 306 | u32 i; | ||
| 307 | struct vidtv_mux_pid_ctx *ctx; | 357 | struct vidtv_mux_pid_ctx *ctx; |
| 358 | u32 nbytes; | ||
| 359 | u32 i; | ||
| 308 | 360 | ||
| 309 | ctx = vidtv_mux_get_pid_ctx(m, TS_NULL_PACKET_PID); | 361 | ctx = vidtv_mux_get_pid_ctx(m, TS_NULL_PACKET_PID); |
| 310 | 362 | ||
| 311 | args.dest_buf = m->mux_buf; | ||
| 312 | args.buf_sz = m->mux_buf_sz; | ||
| 313 | args.continuity_counter = &ctx->cc; | 363 | args.continuity_counter = &ctx->cc; |
| 314 | args.dest_offset = m->mux_buf_offset; | ||
| 315 | 364 | ||
| 316 | for (i = 0; i < npkts; ++i) { | 365 | for (i = 0; i < npkts; ++i) { |
| 317 | m->mux_buf_offset += vidtv_ts_null_write_into(args); | 366 | m->mux_buf_offset += vidtv_ts_null_write_into(args); |
| @@ -343,9 +392,9 @@ static void vidtv_mux_tick(struct work_struct *work) · 25 unmodified lines | |||
| 343 | struct vidtv_mux, | 392 | struct vidtv_mux, |
| 344 | mpeg_thread); | 393 | mpeg_thread); |
| 345 | struct dtv_frontend_properties *c = &m->fe->dtv_property_cache; | 394 | struct dtv_frontend_properties *c = &m->fe->dtv_property_cache; |
| 395 | u32 tot_bits = 0; | ||
| 346 | u32 nbytes; | 396 | u32 nbytes; |
| 347 | u32 npkts; | 397 | u32 npkts; |
| 348 | u32 tot_bits = 0; | ||
| 349 | 398 | ||
| 350 | while (m->streaming) { | 399 | while (m->streaming) { |
| 351 | nbytes = 0; | 400 | nbytes = 0; |
| @@ -427,40 +476,62 @@ void vidtv_mux_stop_thread(struct vidtv_mux *m) · 75 unmodified lines | |||
| 427 | 476 | ||
| 428 | struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, | 477 | struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, |
| 429 | struct device *dev, | 478 | struct device *dev, |
| 430 | struct vidtv_mux_init_args args) | 479 | struct vidtv_mux_init_args *args) |
| 431 | { | 480 | { |
| 432 | struct vidtv_mux *m = kzalloc(sizeof(*m), GFP_KERNEL); | 481 | struct vidtv_mux *m; |
| 482 | |||
| 483 | m = kzalloc(sizeof(*m), GFP_KERNEL); | ||
| 484 | if (!m) | ||
| 485 | return NULL; | ||
| 433 | 486 | ||
| 434 | m->dev = dev; | 487 | m->dev = dev; |
| 435 | m->fe = fe; | 488 | m->fe = fe; |
| 436 | m->timing.pcr_period_usecs = args.pcr_period_usecs; | 489 | m->timing.pcr_period_usecs = args->pcr_period_usecs; |
| 437 | m->timing.si_period_usecs = args.si_period_usecs; | 490 | m->timing.si_period_usecs = args->si_period_usecs; |
| 491 | |||
| 492 | m->mux_rate_kbytes_sec = args->mux_rate_kbytes_sec; | ||
| 438 | 493 | ||
| 439 | m->mux_rate_kbytes_sec = args.mux_rate_kbytes_sec; | 494 | m->on_new_packets_available_cb = args->on_new_packets_available_cb; |
| 440 | 495 | ||
| 441 | m->on_new_packets_available_cb = args.on_new_packets_available_cb; | 496 | m->mux_buf = vzalloc(args->mux_buf_sz); |
| 497 | if (!m->mux_buf) | ||
| 498 | goto free_mux; | ||
| 442 | 499 | ||
| 443 | m->mux_buf = vzalloc(args.mux_buf_sz); | 500 | m->mux_buf_sz = args->mux_buf_sz; |
| 444 | m->mux_buf_sz = args.mux_buf_sz; | ||
| 445 | 501 | ||
| 446 | m->pcr_pid = args.pcr_pid; | 502 | m->pcr_pid = args->pcr_pid; |
| 447 | m->transport_stream_id = args.transport_stream_id; | 503 | m->transport_stream_id = args->transport_stream_id; |
| 448 | m->priv = args.priv; | 504 | m->priv = args->priv; |
| 505 | m->network_id = args->network_id; | ||
| 506 | m->network_name = kstrdup(args->network_name, GFP_KERNEL); | ||
| 449 | m->timing.current_jiffies = get_jiffies_64(); | 507 | m->timing.current_jiffies = get_jiffies_64(); |
| 450 | 508 | ||
| 451 | if (args.channels) | 509 | if (args->channels) |
| 452 | m->channels = args.channels; | 510 | m->channels = args->channels; |
| 453 | else | 511 | else |
| 454 | vidtv_channels_init(m); | 512 | if (vidtv_channels_init(m) < 0) |
| 513 | goto free_mux_buf; | ||
| 455 | 514 | ||
| 456 | /* will alloc data for pmt_sections after initializing pat */ | 515 | /* will alloc data for pmt_sections after initializing pat */ |
| 457 | vidtv_channel_si_init(m); | 516 | if (vidtv_channel_si_init(m) < 0) |
| 517 | goto free_channels; | ||
| 458 | 518 | ||
| 459 | INIT_WORK(&m->mpeg_thread, vidtv_mux_tick); | 519 | INIT_WORK(&m->mpeg_thread, vidtv_mux_tick); |
| 460 | 520 | ||
| 461 | vidtv_mux_pid_ctx_init(m); | 521 | if (vidtv_mux_pid_ctx_init(m) < 0) |
| 522 | goto free_channel_si; | ||
| 462 | 523 | ||
| 463 | return m; | 524 | return m; |
| 525 | |||
| 526 | free_channel_si: | ||
| 527 | vidtv_channel_si_destroy(m); | ||
| 528 | free_channels: | ||
| 529 | vidtv_channels_destroy(m); | ||
| 530 | free_mux_buf: | ||
| 531 | vfree(m->mux_buf); | ||
| 532 | free_mux: | ||
| 533 | kfree(m); | ||
| 534 | return NULL; | ||
| 464 | } | 535 | } |
| 465 | 536 | ||
| 466 | void vidtv_mux_destroy(struct vidtv_mux *m) | 537 | void vidtv_mux_destroy(struct vidtv_mux *m) |
| @@ -469,6 +540,7 @@ void vidtv_mux_destroy(struct vidtv_mux *m) · 2 unmodified lines | |||
| 469 | vidtv_mux_pid_ctx_destroy(m); | 540 | vidtv_mux_pid_ctx_destroy(m); |
| 470 | vidtv_channel_si_destroy(m); | 541 | vidtv_channel_si_destroy(m); |
| 471 | vidtv_channels_destroy(m); | 542 | vidtv_channels_destroy(m); |
| 543 | kfree(m->network_name); | ||
| 472 | vfree(m->mux_buf); | 544 | vfree(m->mux_buf); |
| 473 | kfree(m); | 545 | kfree(m); |
| 474 | } | 546 | } |
| @@ -15,9 +15,10 @@ · 14 unmodified lines | |||
| 15 | #ifndef VIDTV_MUX_H | 15 | #ifndef VIDTV_MUX_H |
| 16 | #define VIDTV_MUX_H | 16 | #define VIDTV_MUX_H |
| 17 | 17 | ||
| 18 | #include <linux/types.h> | ||
| 19 | #include <linux/hashtable.h> | 18 | #include <linux/hashtable.h> |
| 19 | #include <linux/types.h> | ||
| 20 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
| 21 | |||
| 21 | #include <media/dvb_frontend.h> | 22 | #include <media/dvb_frontend.h> |
| 22 | 23 | ||
| 23 | #include "vidtv_psi.h" | 24 | #include "vidtv_psi.h" |
| @@ -58,12 +59,16 @@ struct vidtv_mux_timing { · 34 unmodified lines | |||
| 58 | * @pat: The PAT in use by the muxer. | 59 | * @pat: The PAT in use by the muxer. |
| 59 | * @pmt_secs: The PMT sections in use by the muxer. One for each program in the PAT. | 60 | * @pmt_secs: The PMT sections in use by the muxer. One for each program in the PAT. |
| 60 | * @sdt: The SDT in use by the muxer. | 61 | * @sdt: The SDT in use by the muxer. |
| 62 | * @nit: The NIT in use by the muxer. | ||
| 63 | * @eit: the EIT in use by the muxer. | ||
| 61 | */ | 64 | */ |
| 62 | struct vidtv_mux_si { | 65 | struct vidtv_mux_si { |
| 63 | /* the SI tables */ | 66 | /* the SI tables */ |
| 64 | struct vidtv_psi_table_pat *pat; | 67 | struct vidtv_psi_table_pat *pat; |
| 65 | struct vidtv_psi_table_pmt **pmt_secs; /* the PMT sections */ | 68 | struct vidtv_psi_table_pmt **pmt_secs; /* the PMT sections */ |
| 66 | struct vidtv_psi_table_sdt *sdt; | 69 | struct vidtv_psi_table_sdt *sdt; |
| 70 | struct vidtv_psi_table_nit *nit; | ||
| 71 | struct vidtv_psi_table_eit *eit; | ||
| 67 | }; | 72 | }; |
| 68 | 73 | ||
| 69 | /** | 74 | /** |
| @@ -82,8 +87,10 @@ struct vidtv_mux_pid_ctx { · 12 unmodified lines | |||
| 82 | 87 | ||
| 83 | /** | 88 | /** |
| 84 | * struct vidtv_mux - A muxer abstraction loosely based in libavcodec/mpegtsenc.c | 89 | * struct vidtv_mux - A muxer abstraction loosely based in libavcodec/mpegtsenc.c |
| 85 | * @mux_rate_kbytes_sec: The bit rate for the TS, in kbytes. | 90 | * @fe: The frontend structure allocated by the muxer. |
| 91 | * @dev: pointer to struct device. | ||
| 86 | * @timing: Keeps track of timing related information. | 92 | * @timing: Keeps track of timing related information. |
| 93 | * @mux_rate_kbytes_sec: The bit rate for the TS, in kbytes. | ||
| 87 | * @pid_ctx: A hash table to keep track of per-PID metadata. | 94 | * @pid_ctx: A hash table to keep track of per-PID metadata. |
| 88 | * @on_new_packets_available_cb: A callback to inform of new TS packets ready. | 95 | * @on_new_packets_available_cb: A callback to inform of new TS packets ready. |
| 89 | * @mux_buf: A pointer to a buffer for this muxer. TS packets are stored there | 96 | * @mux_buf: A pointer to a buffer for this muxer. TS packets are stored there |
| @@ -99,6 +106,8 @@ struct vidtv_mux_pid_ctx { · 9 unmodified lines | |||
| 99 | * @pcr_pid: The TS PID used for the PSI packets. All channels will share the | 106 | * @pcr_pid: The TS PID used for the PSI packets. All channels will share the |
| 100 | * same PCR. | 107 | * same PCR. |
| 101 | * @transport_stream_id: The transport stream ID | 108 | * @transport_stream_id: The transport stream ID |
| 109 | * @network_id: The network ID | ||
| 110 | * @network_name: The network name | ||
| 102 | * @priv: Private data. | 111 | * @priv: Private data. |
| 103 | */ | 112 | */ |
| 104 | struct vidtv_mux { | 113 | struct vidtv_mux { |
| @@ -128,6 +137,8 @@ struct vidtv_mux { · 23 unmodified lines | |||
| 128 | 137 | ||
| 129 | u16 pcr_pid; | 138 | u16 pcr_pid; |
| 130 | u16 transport_stream_id; | 139 | u16 transport_stream_id; |
| 140 | u16 network_id; | ||
| 141 | char *network_name; | ||
| 131 | void *priv; | 142 | void *priv; |
| 132 | }; | 143 | }; |
| 133 | 144 | ||
| @@ -142,6 +153,8 @@ struct vidtv_mux { · 8 unmodified lines | |||
| 142 | * same PCR. | 153 | * same PCR. |
| 143 | * @transport_stream_id: The transport stream ID | 154 | * @transport_stream_id: The transport stream ID |
| 144 | * @channels: an optional list of channels to use | 155 | * @channels: an optional list of channels to use |
| 156 | * @network_id: The network ID | ||
| 157 | * @network_name: The network name | ||
| 145 | * @priv: Private data. | 158 | * @priv: Private data. |
| 146 | */ | 159 | */ |
| 147 | struct vidtv_mux_init_args { | 160 | struct vidtv_mux_init_args { |
| @@ -153,12 +166,14 @@ struct vidtv_mux_init_args { · 5 unmodified lines | |||
| 153 | u16 pcr_pid; | 166 | u16 pcr_pid; |
| 154 | u16 transport_stream_id; | 167 | u16 transport_stream_id; |
| 155 | struct vidtv_channel *channels; | 168 | struct vidtv_channel *channels; |
| 169 | u16 network_id; | ||
| 170 | char *network_name; | ||
| 156 | void *priv; | 171 | void *priv; |
| 157 | }; | 172 | }; |
| 158 | 173 | ||
| 159 | struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, | 174 | struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, |
| 160 | struct device *dev, | 175 | struct device *dev, |
| 161 | struct vidtv_mux_init_args args); | 176 | struct vidtv_mux_init_args *args); |
| 162 | void vidtv_mux_destroy(struct vidtv_mux *m); | 177 | void vidtv_mux_destroy(struct vidtv_mux *m); |
| 163 | 178 | ||
| 164 | void vidtv_mux_start_thread(struct vidtv_mux *m); | 179 | void vidtv_mux_start_thread(struct vidtv_mux *m); |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | |||
| 16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 17 | #include <linux/printk.h> | 17 | #include <linux/printk.h> |
| 18 | #include <linux/ratelimit.h> | 18 | #include <linux/ratelimit.h> |
| 19 | #include <asm/byteorder.h> | ||
| 20 | 19 | ||
| 21 | #include "vidtv_pes.h" | 20 | #include "vidtv_pes.h" |
| 22 | #include "vidtv_common.h" | 21 | #include "vidtv_common.h" |
| @@ -57,7 +56,7 @@ static u32 vidtv_pes_h_get_len(bool send_pts, bool send_dts) · 34 unmodified lines | |||
| 57 | return len; | 56 | return len; |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args args) | 59 | static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args *args) |
| 61 | { | 60 | { |
| 62 | /* | 61 | /* |
| 63 | * This is a fixed 8-bit value equal to '0xFF' that can be inserted | 62 | * This is a fixed 8-bit value equal to '0xFF' that can be inserted |
| @@ -65,20 +64,20 @@ static u32 vidtv_pes_write_header_stuffing(struct pes_header_write_args args) · 1 unmodified line | |||
| 65 | * It is discarded by the decoder. No more than 32 stuffing bytes shall | 64 | * It is discarded by the decoder. No more than 32 stuffing bytes shall |
| 66 | * be present in one PES packet header. | 65 | * be present in one PES packet header. |
| 67 | */ | 66 | */ |
| 68 | if (args.n_pes_h_s_bytes > PES_HEADER_MAX_STUFFING_BYTES) { | 67 | if (args->n_pes_h_s_bytes > PES_HEADER_MAX_STUFFING_BYTES) { |
| 69 | pr_warn_ratelimited("More than %d stuffing bytes in PES packet header\n", | 68 | pr_warn_ratelimited("More than %d stuffing bytes in PES packet header\n", |
| 70 | PES_HEADER_MAX_STUFFING_BYTES); | 69 | PES_HEADER_MAX_STUFFING_BYTES); |
| 71 | args.n_pes_h_s_bytes = PES_HEADER_MAX_STUFFING_BYTES; | 70 | args->n_pes_h_s_bytes = PES_HEADER_MAX_STUFFING_BYTES; |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | return vidtv_memset(args.dest_buf, | 73 | return vidtv_memset(args->dest_buf, |
| 75 | args.dest_offset, | 74 | args->dest_offset, |
| 76 | args.dest_buf_sz, | 75 | args->dest_buf_sz, |
| 77 | TS_FILL_BYTE, | 76 | TS_FILL_BYTE, |
| 78 | args.n_pes_h_s_bytes); | 77 | args->n_pes_h_s_bytes); |
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args) | 80 | static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args *args) |
| 82 | { | 81 | { |
| 83 | u32 nbytes = 0; /* the number of bytes written by this function */ | 82 | u32 nbytes = 0; /* the number of bytes written by this function */ |
| 84 | 83 | ||
| @@ -90,7 +89,7 @@ static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args) · 5 unmodified lines | |||
| 90 | u64 mask2; | 89 | u64 mask2; |
| 91 | u64 mask3; | 90 | u64 mask3; |
| 92 | 91 | ||
| 93 | if (!args.send_pts && args.send_dts) | 92 | if (!args->send_pts && args->send_dts) |
| 94 | return 0; | 93 | return 0; |
| 95 | 94 | ||
| 96 | mask1 = GENMASK_ULL(32, 30); | 95 | mask1 = GENMASK_ULL(32, 30); |
| @@ -98,80 +97,81 @@ static u32 vidtv_pes_write_pts_dts(struct pes_header_write_args args) · 1 unmodified line | |||
| 98 | mask3 = GENMASK_ULL(14, 0); | 97 | mask3 = GENMASK_ULL(14, 0); |
| 99 | 98 | ||
| 100 | /* see ISO/IEC 13818-1 : 2000 p. 32 */ | 99 | /* see ISO/IEC 13818-1 : 2000 p. 32 */ |
| 101 | if (args.send_pts && args.send_dts) { | 100 | if (args->send_pts && args->send_dts) { |
| 102 | pts_dts.pts1 = (0x3 << 4) | ((args.pts & mask1) >> 29) | 0x1; | 101 | pts_dts.pts1 = (0x3 << 4) | ((args->pts & mask1) >> 29) | 0x1; |
| 103 | pts_dts.pts2 = cpu_to_be16(((args.pts & mask2) >> 14) | 0x1); | 102 | pts_dts.pts2 = cpu_to_be16(((args->pts & mask2) >> 14) | 0x1); |
| 104 | pts_dts.pts3 = cpu_to_be16(((args.pts & mask3) << 1) | 0x1); | 103 | pts_dts.pts3 = cpu_to_be16(((args->pts & mask3) << 1) | 0x1); |
| 105 | 104 | ||
| 106 | pts_dts.dts1 = (0x1 << 4) | ((args.dts & mask1) >> 29) | 0x1; | 105 | pts_dts.dts1 = (0x1 << 4) | ((args->dts & mask1) >> 29) | 0x1; |
| 107 | pts_dts.dts2 = cpu_to_be16(((args.dts & mask2) >> 14) | 0x1); | 106 | pts_dts.dts2 = cpu_to_be16(((args->dts & mask2) >> 14) | 0x1); |
| 108 | pts_dts.dts3 = cpu_to_be16(((args.dts & mask3) << 1) | 0x1); | 107 | pts_dts.dts3 = cpu_to_be16(((args->dts & mask3) << 1) | 0x1); |
| 109 | 108 | ||
| 110 | op = &pts_dts; | 109 | op = &pts_dts; |
| 111 | op_sz = sizeof(pts_dts); | 110 | op_sz = sizeof(pts_dts); |
| 112 | 111 | ||
| 113 | } else if (args.send_pts) { | 112 | } else if (args->send_pts) { |
| 114 | pts.pts1 = (0x1 << 5) | ((args.pts & mask1) >> 29) | 0x1; | 113 | pts.pts1 = (0x1 << 5) | ((args->pts & mask1) >> 29) | 0x1; |
| 115 | pts.pts2 = cpu_to_be16(((args.pts & mask2) >> 14) | 0x1); | 114 | pts.pts2 = cpu_to_be16(((args->pts & mask2) >> 14) | 0x1); |
| 116 | pts.pts3 = cpu_to_be16(((args.pts & mask3) << 1) | 0x1); | 115 | pts.pts3 = cpu_to_be16(((args->pts & mask3) << 1) | 0x1); |
| 117 | 116 | ||
| 118 | op = &pts; | 117 | op = &pts; |
| 119 | op_sz = sizeof(pts); | 118 | op_sz = sizeof(pts); |
| 120 | } | 119 | } |
| 121 | 120 | ||
| 122 | /* copy PTS/DTS optional */ | 121 | /* copy PTS/DTS optional */ |
| 123 | nbytes += vidtv_memcpy(args.dest_buf, | 122 | nbytes += vidtv_memcpy(args->dest_buf, |
| 124 | args.dest_offset + nbytes, | 123 | args->dest_offset + nbytes, |
| 125 | args.dest_buf_sz, | 124 | args->dest_buf_sz, |
| 126 | op, | 125 | op, |
| 127 | op_sz); | 126 | op_sz); |
| 128 | 127 | ||
| 129 | return nbytes; | 128 | return nbytes; |
| 130 | } | 129 | } |
| 131 | 130 | ||
| 132 | static u32 vidtv_pes_write_h(struct pes_header_write_args args) | 131 | static u32 vidtv_pes_write_h(struct pes_header_write_args *args) |
| 133 | { | 132 | { |
| 134 | u32 nbytes = 0; /* the number of bytes written by this function */ | 133 | u32 nbytes = 0; /* the number of bytes written by this function */ |
| 135 | 134 | ||
| 136 | struct vidtv_mpeg_pes pes_header = {}; | 135 | struct vidtv_mpeg_pes pes_header = {}; |
| 137 | struct vidtv_pes_optional pes_optional = {}; | 136 | struct vidtv_pes_optional pes_optional = {}; |
| 138 | struct pes_header_write_args pts_dts_args = args; | 137 | struct pes_header_write_args pts_dts_args; |
| 139 | u32 stream_id = (args.encoder_id == S302M) ? PRIVATE_STREAM_1_ID : args.stream_id; | 138 | u32 stream_id = (args->encoder_id == S302M) ? PRIVATE_STREAM_1_ID : args->stream_id; |
| 140 | u16 pes_opt_bitfield = 0x01 << 15; | 139 | u16 pes_opt_bitfield = 0x01 << 15; |
| 141 | 140 | ||
| 142 | pes_header.bitfield = cpu_to_be32((PES_START_CODE_PREFIX << 8) | stream_id); | 141 | pes_header.bitfield = cpu_to_be32((PES_START_CODE_PREFIX << 8) | stream_id); |
| 143 | 142 | ||
| 144 | pes_header.length = cpu_to_be16(vidtv_pes_op_get_len(args.send_pts, | 143 | pes_header.length = cpu_to_be16(vidtv_pes_op_get_len(args->send_pts, |
| 145 | args.send_dts) + | 144 | args->send_dts) + |
| 146 | args.access_unit_len); | 145 | args->access_unit_len); |
| 147 | 146 | ||
| 148 | if (args.send_pts && args.send_dts) | 147 | if (args->send_pts && args->send_dts) |
| 149 | pes_opt_bitfield |= (0x3 << 6); | 148 | pes_opt_bitfield |= (0x3 << 6); |
| 150 | else if (args.send_pts) | 149 | else if (args->send_pts) |
| 151 | pes_opt_bitfield |= (0x1 << 7); | 150 | pes_opt_bitfield |= (0x1 << 7); |
| 152 | 151 | ||
| 153 | pes_optional.bitfield = cpu_to_be16(pes_opt_bitfield); | 152 | pes_optional.bitfield = cpu_to_be16(pes_opt_bitfield); |
| 154 | pes_optional.length = vidtv_pes_op_get_len(args.send_pts, args.send_dts) + | 153 | pes_optional.length = vidtv_pes_op_get_len(args->send_pts, args->send_dts) + |
| 155 | args.n_pes_h_s_bytes - | 154 | args->n_pes_h_s_bytes - |
| 156 | sizeof(struct vidtv_pes_optional); | 155 | sizeof(struct vidtv_pes_optional); |
| 157 | 156 | ||
| 158 | /* copy header */ | 157 | /* copy header */ |
| 159 | nbytes += vidtv_memcpy(args.dest_buf, | 158 | nbytes += vidtv_memcpy(args->dest_buf, |
| 160 | args.dest_offset + nbytes, | 159 | args->dest_offset + nbytes, |
| 161 | args.dest_buf_sz, | 160 | args->dest_buf_sz, |
| 162 | &pes_header, | 161 | &pes_header, |
| 163 | sizeof(pes_header)); | 162 | sizeof(pes_header)); |
| 164 | 163 | ||
| 165 | /* copy optional header bits */ | 164 | /* copy optional header bits */ |
| 166 | nbytes += vidtv_memcpy(args.dest_buf, | 165 | nbytes += vidtv_memcpy(args->dest_buf, |
| 167 | args.dest_offset + nbytes, | 166 | args->dest_offset + nbytes, |
| 168 | args.dest_buf_sz, | 167 | args->dest_buf_sz, |
| 169 | &pes_optional, | 168 | &pes_optional, |
| 170 | sizeof(pes_optional)); | 169 | sizeof(pes_optional)); |
| 171 | 170 | ||
| 172 | /* copy the timing information */ | 171 | /* copy the timing information */ |
| 173 | pts_dts_args.dest_offset = args.dest_offset + nbytes; | 172 | pts_dts_args = *args; |
| 174 | nbytes += vidtv_pes_write_pts_dts(pts_dts_args); | 173 | pts_dts_args.dest_offset = args->dest_offset + nbytes; |
| 174 | nbytes += vidtv_pes_write_pts_dts(&pts_dts_args); | ||
| 175 | 175 | ||
| 176 | /* write any PES header stuffing */ | 176 | /* write any PES header stuffing */ |
| 177 | nbytes += vidtv_pes_write_header_stuffing(args); | 177 | nbytes += vidtv_pes_write_header_stuffing(args); |
| @@ -300,14 +300,31 @@ static u32 vidtv_pes_write_ts_h(struct pes_ts_header_write_args args, · 122 unmodified lines | |||
| 300 | return nbytes; | 300 | return nbytes; |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | u32 vidtv_pes_write_into(struct pes_write_args args) | 303 | u32 vidtv_pes_write_into(struct pes_write_args *args) |
| 304 | { | 304 | { |
| 305 | u32 unaligned_bytes = (args.dest_offset % TS_PACKET_LEN); | 305 | u32 unaligned_bytes = (args->dest_offset % TS_PACKET_LEN); |
| 306 | struct pes_ts_header_write_args ts_header_args = {}; | 306 | struct pes_ts_header_write_args ts_header_args = { |
| 307 | struct pes_header_write_args pes_header_args = {}; | 307 | .dest_buf = args->dest_buf, |
| 308 | u32 remaining_len = args.access_unit_len; | 308 | .dest_buf_sz = args->dest_buf_sz, |
| 309 | .pid = args->pid, | ||
| 310 | .pcr = args->pcr, | ||
| 311 | .continuity_counter = args->continuity_counter, | ||
| 312 | }; | ||
| 313 | struct pes_header_write_args pes_header_args = { | ||
| 314 | .dest_buf = args->dest_buf, | ||
| 315 | .dest_buf_sz = args->dest_buf_sz, | ||
| 316 | .encoder_id = args->encoder_id, | ||
| 317 | .send_pts = args->send_pts, | ||
| 318 | .pts = args->pts, | ||
| 319 | .send_dts = args->send_dts, | ||
| 320 | .dts = args->dts, | ||
| 321 | .stream_id = args->stream_id, | ||
| 322 | .n_pes_h_s_bytes = args->n_pes_h_s_bytes, | ||
| 323 | .access_unit_len = args->access_unit_len, | ||
| 324 | }; | ||
| 325 | u32 remaining_len = args->access_unit_len; | ||
| 309 | bool wrote_pes_header = false; | 326 | bool wrote_pes_header = false; |
| 310 | u64 last_pcr = args.pcr; | 327 | u64 last_pcr = args->pcr; |
| 311 | bool need_pcr = true; | 328 | bool need_pcr = true; |
| 312 | u32 available_space; | 329 | u32 available_space; |
| 313 | u32 payload_size; | 330 | u32 payload_size; |
| @@ -318,25 +335,13 @@ u32 vidtv_pes_write_into(struct pes_write_args args) · 4 unmodified lines | |||
| 318 | pr_warn_ratelimited("buffer is misaligned, while starting PES\n"); | 335 | pr_warn_ratelimited("buffer is misaligned, while starting PES\n"); |
| 319 | 336 | ||
| 320 | /* forcibly align and hope for the best */ | 337 | /* forcibly align and hope for the best */ |
| 321 | nbytes += vidtv_memset(args.dest_buf, | 338 | nbytes += vidtv_memset(args->dest_buf, |
| 322 | args.dest_offset + nbytes, | 339 | args->dest_offset + nbytes, |
| 323 | args.dest_buf_sz, | 340 | args->dest_buf_sz, |
| 324 | TS_FILL_BYTE, | 341 | TS_FILL_BYTE, |
| 325 | TS_PACKET_LEN - unaligned_bytes); | 342 | TS_PACKET_LEN - unaligned_bytes); |
| 326 | } | 343 | } |
| 327 | 344 | ||
| 328 | if (args.send_dts && !args.send_pts) { | ||
| 329 | pr_warn_ratelimited("forbidden value '01' for PTS_DTS flags\n"); | ||
| 330 | args.send_pts = true; | ||
| 331 | args.pts = args.dts; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* see SMPTE 302M clause 6.4 */ | ||
| 335 | if (args.encoder_id == S302M) { | ||
| 336 | args.send_dts = false; | ||
| 337 | args.send_pts = true; | ||
| 338 | } | ||
| 339 | |||
| 340 | while (remaining_len) { | 345 | while (remaining_len) { |
| 341 | available_space = TS_PAYLOAD_LEN; | 346 | available_space = TS_PAYLOAD_LEN; |
| 342 | /* | 347 | /* |
| @@ -345,14 +350,14 @@ u32 vidtv_pes_write_into(struct pes_write_args args) · 2 unmodified lines | |||
| 345 | * the space needed for the TS header _and_ for the PES header | 350 | * the space needed for the TS header _and_ for the PES header |
| 346 | */ | 351 | */ |
| 347 | if (!wrote_pes_header) | 352 | if (!wrote_pes_header) |
| 348 | available_space -= vidtv_pes_h_get_len(args.send_pts, | 353 | available_space -= vidtv_pes_h_get_len(args->send_pts, |
| 349 | args.send_dts); | 354 | args->send_dts); |
| 350 | 355 | ||
| 351 | /* | 356 | /* |
| 352 | * if the encoder has inserted stuffing bytes in the PES | 357 | * if the encoder has inserted stuffing bytes in the PES |
| 353 | * header, account for them. | 358 | * header, account for them. |
| 354 | */ | 359 | */ |
| 355 | available_space -= args.n_pes_h_s_bytes; | 360 | available_space -= args->n_pes_h_s_bytes; |
| 356 | 361 | ||
| 357 | /* Take the extra adaptation into account if need to send PCR */ | 362 | /* Take the extra adaptation into account if need to send PCR */ |
| 358 | if (need_pcr) { | 363 | if (need_pcr) { |
| @@ -387,14 +392,9 @@ u32 vidtv_pes_write_into(struct pes_write_args args) · 28 unmodified lines | |||
| 387 | } | 392 | } |
| 388 | 393 | ||
| 389 | /* write ts header */ | 394 | /* write ts header */ |
| 390 | ts_header_args.dest_buf = args.dest_buf; | 395 | ts_header_args.dest_offset = args->dest_offset + nbytes; |
| 391 | ts_header_args.dest_offset = args.dest_offset + nbytes; | 396 | ts_header_args.wrote_pes_header = wrote_pes_header; |
| 392 | ts_header_args.dest_buf_sz = args.dest_buf_sz; | 397 | ts_header_args.n_stuffing_bytes = stuff_bytes; |
| 393 | ts_header_args.pid = args.pid; | ||
| 394 | ts_header_args.pcr = args.pcr; | ||
| 395 | ts_header_args.continuity_counter = args.continuity_counter; | ||
| 396 | ts_header_args.wrote_pes_header = wrote_pes_header; | ||
| 397 | ts_header_args.n_stuffing_bytes = stuff_bytes; | ||
| 398 | 398 | ||
| 399 | nbytes += vidtv_pes_write_ts_h(ts_header_args, need_pcr, | 399 | nbytes += vidtv_pes_write_ts_h(ts_header_args, need_pcr, |
| 400 | &last_pcr); | 400 | &last_pcr); |
| @@ -403,33 +403,20 @@ u32 vidtv_pes_write_into(struct pes_write_args args) · 2 unmodified lines | |||
| 403 | 403 | ||
| 404 | if (!wrote_pes_header) { | 404 | if (!wrote_pes_header) { |
| 405 | /* write the PES header only once */ | 405 | /* write the PES header only once */ |
| 406 | pes_header_args.dest_buf = args.dest_buf; | 406 | pes_header_args.dest_offset = args->dest_offset + |
| 407 | 407 | nbytes; | |
| 408 | pes_header_args.dest_offset = args.dest_offset + | 408 | nbytes += vidtv_pes_write_h(&pes_header_args); |
| 409 | nbytes; | 409 | wrote_pes_header = true; |
| 410 | |||
| 411 | pes_header_args.dest_buf_sz = args.dest_buf_sz; | ||
| 412 | pes_header_args.encoder_id = args.encoder_id; | ||
| 413 | pes_header_args.send_pts = args.send_pts; | ||
| 414 | pes_header_args.pts = args.pts; | ||
| 415 | pes_header_args.send_dts = args.send_dts; | ||
| 416 | pes_header_args.dts = args.dts; | ||
| 417 | pes_header_args.stream_id = args.stream_id; | ||
| 418 | pes_header_args.n_pes_h_s_bytes = args.n_pes_h_s_bytes; | ||
| 419 | pes_header_args.access_unit_len = args.access_unit_len; | ||
| 420 | |||
| 421 | nbytes += vidtv_pes_write_h(pes_header_args); | ||
| 422 | wrote_pes_header = true; | ||
| 423 | } | 410 | } |
| 424 | 411 | ||
| 425 | /* write as much of the payload as we possibly can */ | 412 | /* write as much of the payload as we possibly can */ |
| 426 | nbytes += vidtv_memcpy(args.dest_buf, | 413 | nbytes += vidtv_memcpy(args->dest_buf, |
| 427 | args.dest_offset + nbytes, | 414 | args->dest_offset + nbytes, |
| 428 | args.dest_buf_sz, | 415 | args->dest_buf_sz, |
| 429 | args.from, | 416 | args->from, |
| 430 | payload_size); | 417 | payload_size); |
| 431 | 418 | ||
| 432 | args.from += payload_size; | 419 | args->from += payload_size; |
| 433 | 420 | ||
| 434 | remaining_len -= payload_size; | 421 | remaining_len -= payload_size; |
| 435 | } | 422 | } |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | |||
| 14 | #ifndef VIDTV_PES_H | 14 | #ifndef VIDTV_PES_H |
| 15 | #define VIDTV_PES_H | 15 | #define VIDTV_PES_H |
| 16 | 16 | ||
| 17 | #include <asm/byteorder.h> | ||
| 18 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 19 | 18 | ||
| 20 | #include "vidtv_common.h" | 19 | #include "vidtv_common.h" |
| @@ -114,8 +113,10 @@ struct pes_header_write_args { · 93 unmodified lines | |||
| 114 | * @dest_buf_sz: The size of the dest_buffer | 113 | * @dest_buf_sz: The size of the dest_buffer |
| 115 | * @pid: The PID to use for the TS packets. | 114 | * @pid: The PID to use for the TS packets. |
| 116 | * @continuity_counter: Incremented on every new TS packet. | 115 | * @continuity_counter: Incremented on every new TS packet. |
| 117 | * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets | 116 | * @wrote_pes_header: Flag to indicate that the PES header was written |
| 117 | * @n_stuffing_bytes: Padding bytes. Might be used by an encoder if needed, gets | ||
| 118 | * discarded by the decoder. | 118 | * discarded by the decoder. |
| 119 | * @pcr: counter driven by a 27Mhz clock. | ||
| 119 | */ | 120 | */ |
| 120 | struct pes_ts_header_write_args { | 121 | struct pes_ts_header_write_args { |
| 121 | void *dest_buf; | 122 | void *dest_buf; |
| @@ -146,6 +147,7 @@ struct pes_ts_header_write_args { · 24 unmodified lines | |||
| 146 | * @dts: DTS value to send. | 147 | * @dts: DTS value to send. |
| 147 | * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets | 148 | * @n_pes_h_s_bytes: Padding bytes. Might be used by an encoder if needed, gets |
| 148 | * discarded by the decoder. | 149 | * discarded by the decoder. |
| 150 | * @pcr: counter driven by a 27Mhz clock. | ||
| 149 | */ | 151 | */ |
| 150 | struct pes_write_args { | 152 | struct pes_write_args { |
| 151 | void *dest_buf; | 153 | void *dest_buf; |
| @@ -186,6 +188,6 @@ struct pes_write_args { · 34 unmodified lines | |||
| 186 | * equal to the size of the access unit, since we need space for PES headers, TS headers | 188 | * equal to the size of the access unit, since we need space for PES headers, TS headers |
| 187 | * and padding bytes, if any. | 189 | * and padding bytes, if any. |
| 188 | */ | 190 | */ |
| 189 | u32 vidtv_pes_write_into(struct pes_write_args args); | 191 | u32 vidtv_pes_write_into(struct pes_write_args *args); |
| 190 | 192 | ||
| 191 | #endif // VIDTV_PES_H | 193 | #endif // VIDTV_PES_H |
| @@ -6,31 +6,31 @@ · 5 unmodified lines | |||
| 6 | * technically be broken into one or more sections, we do not do this here, | 6 | * technically be broken into one or more sections, we do not do this here, |
| 7 | * hence 'table' and 'section' are interchangeable for vidtv. | 7 | * hence 'table' and 'section' are interchangeable for vidtv. |
| 8 | * | 8 | * |
| 9 | * This code currently supports three tables: PAT, PMT and SDT. These are the | ||
| 10 | * bare minimum to get userspace to recognize our MPEG transport stream. It can | ||
| 11 | * be extended to support more PSI tables in the future. | ||
| 12 | * | ||
| 13 | * Copyright (C) 2020 Daniel W. S. Almeida | 9 | * Copyright (C) 2020 Daniel W. S. Almeida |
| 14 | */ | 10 | */ |
| 15 | 11 | ||
| 16 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ |
| 17 | 13 | ||
| 18 | #include <linux/kernel.h> | 14 | #include <linux/bcd.h> |
| 19 | #include <linux/types.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
| 22 | #include <linux/string.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/ktime.h> | ||
| 23 | #include <linux/printk.h> | 18 | #include <linux/printk.h> |
| 24 | #include <linux/ratelimit.h> | 19 | #include <linux/ratelimit.h> |
| 20 | #include <linux/slab.h> | ||
| 25 | #include <linux/string.h> | 21 | #include <linux/string.h> |
| 26 | #include <asm/byteorder.h> | 22 | #include <linux/string.h> |
| 23 | #include <linux/time.h> | ||
| 24 | #include <linux/types.h> | ||
| 27 | 25 | ||
| 28 | #include "vidtv_psi.h" | ||
| 29 | #include "vidtv_common.h" | 26 | #include "vidtv_common.h" |
| 27 | #include "vidtv_psi.h" | ||
| 30 | #include "vidtv_ts.h" | 28 | #include "vidtv_ts.h" |
| 31 | 29 | ||
| 32 | #define CRC_SIZE_IN_BYTES 4 | 30 | #define CRC_SIZE_IN_BYTES 4 |
| 33 | #define MAX_VERSION_NUM 32 | 31 | #define MAX_VERSION_NUM 32 |
| 32 | #define INITIAL_CRC 0xffffffff | ||
| 33 | #define ISO_LANGUAGE_CODE_LEN 3 | ||
| 34 | 34 | ||
| 35 | static const u32 CRC_LUT[256] = { | 35 | static const u32 CRC_LUT[256] = { |
| 36 | /* from libdvbv5 */ | 36 | /* from libdvbv5 */ |
| @@ -79,7 +79,7 @@ static const u32 CRC_LUT[256] = { · 42 unmodified lines | |||
| 79 | 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 | 79 | 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | static inline u32 dvb_crc32(u32 crc, u8 *data, u32 len) | 82 | static u32 dvb_crc32(u32 crc, u8 *data, u32 len) |
| 83 | { | 83 | { |
| 84 | /* from libdvbv5 */ | 84 | /* from libdvbv5 */ |
| 85 | while (len--) | 85 | while (len--) |
| @@ -92,40 +92,7 @@ static void vidtv_psi_update_version_num(struct vidtv_psi_table_header *h) · 6 unmodified lines | |||
| 92 | h->version++; | 92 | h->version++; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static inline u16 vidtv_psi_sdt_serv_get_desc_loop_len(struct vidtv_psi_table_sdt_service *s) | 95 | static u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) |
| 96 | { | ||
| 97 | u16 mask; | ||
| 98 | u16 ret; | ||
| 99 | |||
| 100 | mask = GENMASK(11, 0); | ||
| 101 | |||
| 102 | ret = be16_to_cpu(s->bitfield) & mask; | ||
| 103 | return ret; | ||
| 104 | } | ||
| 105 | |||
| 106 | static inline u16 vidtv_psi_pmt_stream_get_desc_loop_len(struct vidtv_psi_table_pmt_stream *s) | ||
| 107 | { | ||
| 108 | u16 mask; | ||
| 109 | u16 ret; | ||
| 110 | |||
| 111 | mask = GENMASK(9, 0); | ||
| 112 | |||
| 113 | ret = be16_to_cpu(s->bitfield2) & mask; | ||
| 114 | return ret; | ||
| 115 | } | ||
| 116 | |||
| 117 | static inline u16 vidtv_psi_pmt_get_desc_loop_len(struct vidtv_psi_table_pmt *p) | ||
| 118 | { | ||
| 119 | u16 mask; | ||
| 120 | u16 ret; | ||
| 121 | |||
| 122 | mask = GENMASK(9, 0); | ||
| 123 | |||
| 124 | ret = be16_to_cpu(p->bitfield2) & mask; | ||
| 125 | return ret; | ||
| 126 | } | ||
| 127 | |||
| 128 | static inline u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) | ||
| 129 | { | 96 | { |
| 130 | u16 mask; | 97 | u16 mask; |
| 131 | u16 ret; | 98 | u16 ret; |
| @@ -136,7 +103,7 @@ static inline u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h) · 4 unmodified lines | |||
| 136 | return ret; | 103 | return ret; |
| 137 | } | 104 | } |
| 138 | 105 | ||
| 139 | inline u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p) | 106 | u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p) |
| 140 | { | 107 | { |
| 141 | u16 mask; | 108 | u16 mask; |
| 142 | u16 ret; | 109 | u16 ret; |
| @@ -147,7 +114,7 @@ inline u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p) · 4 unmodified lines | |||
| 147 | return ret; | 114 | return ret; |
| 148 | } | 115 | } |
| 149 | 116 | ||
| 150 | inline u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s) | 117 | u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s) |
| 151 | { | 118 | { |
| 152 | u16 mask; | 119 | u16 mask; |
| 153 | u16 ret; | 120 | u16 ret; |
| @@ -158,10 +125,11 @@ inline u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream * · 4 unmodified lines | |||
| 158 | return ret; | 125 | return ret; |
| 159 | } | 126 | } |
| 160 | 127 | ||
| 161 | static inline void vidtv_psi_set_desc_loop_len(__be16 *bitfield, u16 new_len, u8 desc_len_nbits) | 128 | static void vidtv_psi_set_desc_loop_len(__be16 *bitfield, u16 new_len, |
| 129 | u8 desc_len_nbits) | ||
| 162 | { | 130 | { |
| 163 | u16 mask; | ||
| 164 | __be16 new; | 131 | __be16 new; |
| 132 | u16 mask; | ||
| 165 | 133 | ||
| 166 | mask = GENMASK(15, desc_len_nbits); | 134 | mask = GENMASK(15, desc_len_nbits); |
| 167 | 135 | ||
| @@ -188,90 +156,81 @@ static void vidtv_psi_set_sec_len(struct vidtv_psi_table_header *h, u16 new_len) · 20 unmodified lines | |||
| 188 | h->bitfield = new; | 156 | h->bitfield = new; |
| 189 | } | 157 | } |
| 190 | 158 | ||
| 191 | static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args args) | 159 | /* |
| 160 | * Packetize PSI sections into TS packets: | ||
| 161 | * push a TS header (4bytes) every 184 bytes | ||
| 162 | * manage the continuity_counter | ||
| 163 | * add stuffing (i.e. padding bytes) after the CRC | ||
| 164 | */ | ||
| 165 | static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args *args) | ||
| 192 | { | 166 | { |
| 193 | /* | 167 | struct vidtv_mpeg_ts ts_header = { |
| 194 | * Packetize PSI sections into TS packets: | 168 | .sync_byte = TS_SYNC_BYTE, |
| 195 | * push a TS header (4bytes) every 184 bytes | 169 | .bitfield = cpu_to_be16((args->new_psi_section << 14) | args->pid), |
| 196 | * manage the continuity_counter | 170 | .scrambling = 0, |
| 197 | * add stuffing (i.e. padding bytes) after the CRC | 171 | .payload = 1, |
| 198 | */ | 172 | .adaptation_field = 0, /* no adaptation field */ |
| 199 | 173 | }; | |
| 200 | u32 nbytes_past_boundary = (args.dest_offset % TS_PACKET_LEN); | 174 | u32 nbytes_past_boundary = (args->dest_offset % TS_PACKET_LEN); |
| 201 | bool aligned = (nbytes_past_boundary == 0); | 175 | bool aligned = (nbytes_past_boundary == 0); |
| 202 | struct vidtv_mpeg_ts ts_header = {}; | 176 | u32 remaining_len = args->len; |
| 203 | |||
| 204 | /* number of bytes written by this function */ | ||
| 205 | u32 nbytes = 0; | ||
| 206 | /* how much there is left to write */ | ||
| 207 | u32 remaining_len = args.len; | ||
| 208 | /* how much we can be written in this packet */ | ||
| 209 | u32 payload_write_len = 0; | 177 | u32 payload_write_len = 0; |
| 210 | /* where we are in the source */ | ||
| 211 | u32 payload_offset = 0; | 178 | u32 payload_offset = 0; |
| 179 | u32 nbytes = 0; | ||
| 212 | 180 | ||
| 213 | const u16 PAYLOAD_START = args.new_psi_section; | 181 | if (!args->crc && !args->is_crc) |
| 214 | |||
| 215 | if (!args.crc && !args.is_crc) | ||
| 216 | pr_warn_ratelimited("Missing CRC for chunk\n"); | 182 | pr_warn_ratelimited("Missing CRC for chunk\n"); |
| 217 | 183 | ||
| 218 | if (args.crc) | 184 | if (args->crc) |
| 219 | *args.crc = dvb_crc32(*args.crc, args.from, args.len); | 185 | *args->crc = dvb_crc32(*args->crc, args->from, args->len); |
| 220 | 186 | ||
| 221 | if (args.new_psi_section && !aligned) { | 187 | if (args->new_psi_section && !aligned) { |
| 222 | pr_warn_ratelimited("Cannot write a new PSI section in a misaligned buffer\n"); | 188 | pr_warn_ratelimited("Cannot write a new PSI section in a misaligned buffer\n"); |
| 223 | 189 | ||
| 224 | /* forcibly align and hope for the best */ | 190 | /* forcibly align and hope for the best */ |
| 225 | nbytes += vidtv_memset(args.dest_buf, | 191 | nbytes += vidtv_memset(args->dest_buf, |
| 226 | args.dest_offset + nbytes, | 192 | args->dest_offset + nbytes, |
| 227 | args.dest_buf_sz, | 193 | args->dest_buf_sz, |
| 228 | TS_FILL_BYTE, | 194 | TS_FILL_BYTE, |
| 229 | TS_PACKET_LEN - nbytes_past_boundary); | 195 | TS_PACKET_LEN - nbytes_past_boundary); |
| 230 | } | 196 | } |
| 231 | 197 | ||
| 232 | while (remaining_len) { | 198 | while (remaining_len) { |
| 233 | nbytes_past_boundary = (args.dest_offset + nbytes) % TS_PACKET_LEN; | 199 | nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN; |
| 234 | aligned = (nbytes_past_boundary == 0); | 200 | aligned = (nbytes_past_boundary == 0); |
| 235 | 201 | ||
| 236 | if (aligned) { | 202 | if (aligned) { |
| 237 | /* if at a packet boundary, write a new TS header */ | 203 | /* if at a packet boundary, write a new TS header */ |
| 238 | ts_header.sync_byte = TS_SYNC_BYTE; | 204 | ts_header.continuity_counter = *args->continuity_counter; |
| 239 | ts_header.bitfield = cpu_to_be16((PAYLOAD_START << 14) | args.pid); | 205 | |
| 240 | ts_header.scrambling = 0; | 206 | nbytes += vidtv_memcpy(args->dest_buf, |
| 241 | ts_header.continuity_counter = *args.continuity_counter; | 207 | args->dest_offset + nbytes, |
| 242 | ts_header.payload = 1; | 208 | args->dest_buf_sz, |
| 243 | /* no adaptation field */ | ||
| 244 | ts_header.adaptation_field = 0; | ||
| 245 | |||
| 246 | /* copy the header */ | ||
| 247 | nbytes += vidtv_memcpy(args.dest_buf, | ||
| 248 | args.dest_offset + nbytes, | ||
| 249 | args.dest_buf_sz, | ||
| 250 | &ts_header, | 209 | &ts_header, |
| 251 | sizeof(ts_header)); | 210 | sizeof(ts_header)); |
| 252 | /* | 211 | /* |
| 253 | * This will trigger a discontinuity if the buffer is full, | 212 | * This will trigger a discontinuity if the buffer is full, |
| 254 | * effectively dropping the packet. | 213 | * effectively dropping the packet. |
| 255 | */ | 214 | */ |
| 256 | vidtv_ts_inc_cc(args.continuity_counter); | 215 | vidtv_ts_inc_cc(args->continuity_counter); |
| 257 | } | 216 | } |
| 258 | 217 | ||
| 259 | /* write the pointer_field in the first byte of the payload */ | 218 | /* write the pointer_field in the first byte of the payload */ |
| 260 | if (args.new_psi_section) | 219 | if (args->new_psi_section) |
| 261 | nbytes += vidtv_memset(args.dest_buf, | 220 | nbytes += vidtv_memset(args->dest_buf, |
| 262 | args.dest_offset + nbytes, | 221 | args->dest_offset + nbytes, |
| 263 | args.dest_buf_sz, | 222 | args->dest_buf_sz, |
| 264 | 0x0, | 223 | 0x0, |
| 265 | 1); | 224 | 1); |
| 266 | 225 | ||
| 267 | /* write as much of the payload as possible */ | 226 | /* write as much of the payload as possible */ |
| 268 | nbytes_past_boundary = (args.dest_offset + nbytes) % TS_PACKET_LEN; | 227 | nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN; |
| 269 | payload_write_len = min(TS_PACKET_LEN - nbytes_past_boundary, remaining_len); | 228 | payload_write_len = min(TS_PACKET_LEN - nbytes_past_boundary, remaining_len); |
| 270 | 229 | ||
| 271 | nbytes += vidtv_memcpy(args.dest_buf, | 230 | nbytes += vidtv_memcpy(args->dest_buf, |
| 272 | args.dest_offset + nbytes, | 231 | args->dest_offset + nbytes, |
| 273 | args.dest_buf_sz, | 232 | args->dest_buf_sz, |
| 274 | args.from + payload_offset, | 233 | args->from + payload_offset, |
| 275 | payload_write_len); | 234 | payload_write_len); |
| 276 | 235 | ||
| 277 | /* 'payload_write_len' written from a total of 'len' requested*/ | 236 | /* 'payload_write_len' written from a total of 'len' requested*/ |
| @@ -283,37 +242,45 @@ static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args args) · 5 unmodified lines | |||
| 283 | * fill the rest of the packet if there is any remaining space unused | 242 | * fill the rest of the packet if there is any remaining space unused |
| 284 | */ | 243 | */ |
| 285 | 244 | ||
| 286 | nbytes_past_boundary = (args.dest_offset + nbytes) % TS_PACKET_LEN; | 245 | nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN; |
| 287 | 246 | ||
| 288 | if (args.is_crc) | 247 | if (args->is_crc) |
| 289 | nbytes += vidtv_memset(args.dest_buf, | 248 | nbytes += vidtv_memset(args->dest_buf, |
| 290 | args.dest_offset + nbytes, | 249 | args->dest_offset + nbytes, |
| 291 | args.dest_buf_sz, | 250 | args->dest_buf_sz, |
| 292 | TS_FILL_BYTE, | 251 | TS_FILL_BYTE, |
| 293 | TS_PACKET_LEN - nbytes_past_boundary); | 252 | TS_PACKET_LEN - nbytes_past_boundary); |
| 294 | 253 | ||
| 295 | return nbytes; | 254 | return nbytes; |
| 296 | } | 255 | } |
| 297 | 256 | ||
| 298 | static u32 table_section_crc32_write_into(struct crc32_write_args args) | 257 | static u32 table_section_crc32_write_into(struct crc32_write_args *args) |
| 299 | { | 258 | { |
| 259 | struct psi_write_args psi_args = { | ||
| 260 | .dest_buf = args->dest_buf, | ||
| 261 | .from = &args->crc, | ||
| 262 | .len = CRC_SIZE_IN_BYTES, | ||
| 263 | .dest_offset = args->dest_offset, | ||
| 264 | .pid = args->pid, | ||
| 265 | .new_psi_section = false, | ||
| 266 | .continuity_counter = args->continuity_counter, | ||
| 267 | .is_crc = true, | ||
| 268 | .dest_buf_sz = args->dest_buf_sz, | ||
| 269 | }; | ||
| 270 | |||
| 300 | /* the CRC is the last entry in the section */ | 271 | /* the CRC is the last entry in the section */ |
| 301 | u32 nbytes = 0; | ||
| 302 | struct psi_write_args psi_args = {}; | ||
| 303 | 272 | ||
| 304 | psi_args.dest_buf = args.dest_buf; | 273 | return vidtv_psi_ts_psi_write_into(&psi_args); |
| 305 | psi_args.from = &args.crc; | 274 | } |
| 306 | psi_args.len = CRC_SIZE_IN_BYTES; | ||
| 307 | psi_args.dest_offset = args.dest_offset; | ||
| 308 | psi_args.pid = args.pid; | ||
| 309 | psi_args.new_psi_section = false; | ||
| 310 | psi_args.continuity_counter = args.continuity_counter; | ||
| 311 | psi_args.is_crc = true; | ||
| 312 | psi_args.dest_buf_sz = args.dest_buf_sz; | ||
| 313 | 275 | ||
| 314 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 276 | static void vidtv_psi_desc_chain(struct vidtv_psi_desc *head, struct vidtv_psi_desc *desc) |
| 277 | { | ||
| 278 | if (head) { | ||
| 279 | while (head->next) | ||
| 280 | head = head->next; | ||
| 315 | 281 | ||
| 316 | return nbytes; | 282 | head->next = desc; |
| 283 | } | ||
| 317 | } | 284 | } |
| 318 | 285 | ||
| 319 | struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc *head, | 286 | struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc *head, |
| @@ -326,6 +293,8 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc · 6 unmodified lines | |||
| 326 | u32 provider_name_len = provider_name ? strlen(provider_name) : 0; | 293 | u32 provider_name_len = provider_name ? strlen(provider_name) : 0; |
| 327 | 294 | ||
| 328 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); | 295 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); |
| 296 | if (!desc) | ||
| 297 | return NULL; | ||
| 329 | 298 | ||
| 330 | desc->type = SERVICE_DESCRIPTOR; | 299 | desc->type = SERVICE_DESCRIPTOR; |
| 331 | 300 | ||
| @@ -347,12 +316,7 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc · 15 unmodified lines | |||
| 347 | if (provider_name && provider_name_len) | 316 | if (provider_name && provider_name_len) |
| 348 | desc->provider_name = kstrdup(provider_name, GFP_KERNEL); | 317 | desc->provider_name = kstrdup(provider_name, GFP_KERNEL); |
| 349 | 318 | ||
| 350 | if (head) { | 319 | vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); |
| 351 | while (head->next) | ||
| 352 | head = head->next; | ||
| 353 | |||
| 354 | head->next = (struct vidtv_psi_desc *)desc; | ||
| 355 | } | ||
| 356 | return desc; | 320 | return desc; |
| 357 | } | 321 | } |
| 358 | 322 | ||
| @@ -365,6 +329,8 @@ struct vidtv_psi_desc_registration · 6 unmodified lines | |||
| 365 | struct vidtv_psi_desc_registration *desc; | 329 | struct vidtv_psi_desc_registration *desc; |
| 366 | 330 | ||
| 367 | desc = kzalloc(sizeof(*desc) + sizeof(format_id) + additional_info_len, GFP_KERNEL); | 331 | desc = kzalloc(sizeof(*desc) + sizeof(format_id) + additional_info_len, GFP_KERNEL); |
| 332 | if (!desc) | ||
| 333 | return NULL; | ||
| 368 | 334 | ||
| 369 | desc->type = REGISTRATION_DESCRIPTOR; | 335 | desc->type = REGISTRATION_DESCRIPTOR; |
| 370 | 336 | ||
| @@ -378,44 +344,178 @@ struct vidtv_psi_desc_registration · 7 unmodified lines | |||
| 378 | additional_ident_info, | 344 | additional_ident_info, |
| 379 | additional_info_len); | 345 | additional_info_len); |
| 380 | 346 | ||
| 381 | if (head) { | 347 | vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); |
| 382 | while (head->next) | 348 | return desc; |
| 383 | head = head->next; | 349 | } |
| 384 | 350 | ||
| 385 | head->next = (struct vidtv_psi_desc *)desc; | 351 | struct vidtv_psi_desc_network_name |
| 352 | *vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name) | ||
| 353 | { | ||
| 354 | u32 network_name_len = network_name ? strlen(network_name) : 0; | ||
| 355 | struct vidtv_psi_desc_network_name *desc; | ||
| 356 | |||
| 357 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); | ||
| 358 | if (!desc) | ||
| 359 | return NULL; | ||
| 360 | |||
| 361 | desc->type = NETWORK_NAME_DESCRIPTOR; | ||
| 362 | |||
| 363 | desc->length = network_name_len; | ||
| 364 | |||
| 365 | if (network_name && network_name_len) | ||
| 366 | desc->network_name = kstrdup(network_name, GFP_KERNEL); | ||
| 367 | |||
| 368 | vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); | ||
| 369 | return desc; | ||
| 370 | } | ||
| 371 | |||
| 372 | struct vidtv_psi_desc_service_list | ||
| 373 | *vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head, | ||
| 374 | struct vidtv_psi_desc_service_list_entry *entry) | ||
| 375 | { | ||
| 376 | struct vidtv_psi_desc_service_list_entry *curr_e = NULL; | ||
| 377 | struct vidtv_psi_desc_service_list_entry *head_e = NULL; | ||
| 378 | struct vidtv_psi_desc_service_list_entry *prev_e = NULL; | ||
| 379 | struct vidtv_psi_desc_service_list *desc; | ||
| 380 | u16 length = 0; | ||
| 381 | |||
| 382 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); | ||
| 383 | if (!desc) | ||
| 384 | return NULL; | ||
| 385 | |||
| 386 | desc->type = SERVICE_LIST_DESCRIPTOR; | ||
| 387 | |||
| 388 | while (entry) { | ||
| 389 | curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); | ||
| 390 | if (!curr_e) { | ||
| 391 | while (head_e) { | ||
| 392 | curr_e = head_e; | ||
| 393 | head_e = head_e->next; | ||
| 394 | kfree(curr_e); | ||
| 395 | } | ||
| 396 | kfree(desc); | ||
| 397 | return NULL; | ||
| 398 | } | ||
| 399 | |||
| 400 | curr_e->service_id = entry->service_id; | ||
| 401 | curr_e->service_type = entry->service_type; | ||
| 402 | |||
| 403 | length += sizeof(struct vidtv_psi_desc_service_list_entry) - | ||
| 404 | sizeof(struct vidtv_psi_desc_service_list_entry *); | ||
| 405 | |||
| 406 | if (!head_e) | ||
| 407 | head_e = curr_e; | ||
| 408 | if (prev_e) | ||
| 409 | prev_e->next = curr_e; | ||
| 410 | |||
| 411 | prev_e = curr_e; | ||
| 412 | entry = entry->next; | ||
| 386 | } | 413 | } |
| 387 | 414 | ||
| 415 | desc->length = length; | ||
| 416 | desc->service_list = head_e; | ||
| 417 | |||
| 418 | vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); | ||
| 419 | return desc; | ||
| 420 | } | ||
| 421 | |||
| 422 | struct vidtv_psi_desc_short_event | ||
| 423 | *vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head, | ||
| 424 | char *iso_language_code, | ||
| 425 | char *event_name, | ||
| 426 | char *text) | ||
| 427 | { | ||
| 428 | u32 iso_len = iso_language_code ? strlen(iso_language_code) : 0; | ||
| 429 | u32 event_name_len = event_name ? strlen(event_name) : 0; | ||
| 430 | struct vidtv_psi_desc_short_event *desc; | ||
| 431 | u32 text_len = text ? strlen(text) : 0; | ||
| 432 | |||
| 433 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); | ||
| 434 | if (!desc) | ||
| 435 | return NULL; | ||
| 436 | |||
| 437 | desc->type = SHORT_EVENT_DESCRIPTOR; | ||
| 438 | |||
| 439 | desc->length = ISO_LANGUAGE_CODE_LEN + | ||
| 440 | sizeof_field(struct vidtv_psi_desc_short_event, event_name_len) + | ||
| 441 | event_name_len + | ||
| 442 | sizeof_field(struct vidtv_psi_desc_short_event, text_len) + | ||
| 443 | text_len; | ||
| 444 | |||
| 445 | desc->event_name_len = event_name_len; | ||
| 446 | desc->text_len = text_len; | ||
| 447 | |||
| 448 | if (iso_len != ISO_LANGUAGE_CODE_LEN) | ||
| 449 | iso_language_code = "eng"; | ||
| 450 | |||
| 451 | desc->iso_language_code = kstrdup(iso_language_code, GFP_KERNEL); | ||
| 452 | |||
| 453 | if (event_name && event_name_len) | ||
| 454 | desc->event_name = kstrdup(event_name, GFP_KERNEL); | ||
| 455 | |||
| 456 | if (text && text_len) | ||
| 457 | desc->text = kstrdup(text, GFP_KERNEL); | ||
| 458 | |||
| 459 | vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); | ||
| 388 | return desc; | 460 | return desc; |
| 389 | } | 461 | } |
| 390 | 462 | ||
| 391 | struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) | 463 | struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) |
| 392 | { | 464 | { |
| 465 | struct vidtv_psi_desc_network_name *desc_network_name; | ||
| 466 | struct vidtv_psi_desc_service_list *desc_service_list; | ||
| 467 | struct vidtv_psi_desc_short_event *desc_short_event; | ||
| 468 | struct vidtv_psi_desc_service *service; | ||
| 393 | struct vidtv_psi_desc *head = NULL; | 469 | struct vidtv_psi_desc *head = NULL; |
| 394 | struct vidtv_psi_desc *prev = NULL; | 470 | struct vidtv_psi_desc *prev = NULL; |
| 395 | struct vidtv_psi_desc *curr = NULL; | 471 | struct vidtv_psi_desc *curr = NULL; |
| 396 | 472 | ||
| 397 | struct vidtv_psi_desc_service *service; | ||
| 398 | |||
| 399 | while (desc) { | 473 | while (desc) { |
| 400 | switch (desc->type) { | 474 | switch (desc->type) { |
| 401 | case SERVICE_DESCRIPTOR: | 475 | case SERVICE_DESCRIPTOR: |
| 402 | service = (struct vidtv_psi_desc_service *)desc; | 476 | service = (struct vidtv_psi_desc_service *)desc; |
| 403 | curr = (struct vidtv_psi_desc *) | 477 | curr = (struct vidtv_psi_desc *) |
| 404 | vidtv_psi_service_desc_init(head, | 478 | vidtv_psi_service_desc_init(head, |
| 405 | service->service_type, | 479 | service->service_type, |
| 406 | service->service_name, | 480 | service->service_name, |
| 407 | service->provider_name); | 481 | service->provider_name); |
| 482 | break; | ||
| 483 | |||
| 484 | case NETWORK_NAME_DESCRIPTOR: | ||
| 485 | desc_network_name = (struct vidtv_psi_desc_network_name *)desc; | ||
| 486 | curr = (struct vidtv_psi_desc *) | ||
| 487 | vidtv_psi_network_name_desc_init(head, | ||
| 488 | desc_network_name->network_name); | ||
| 489 | break; | ||
| 490 | |||
| 491 | case SERVICE_LIST_DESCRIPTOR: | ||
| 492 | desc_service_list = (struct vidtv_psi_desc_service_list *)desc; | ||
| 493 | curr = (struct vidtv_psi_desc *) | ||
| 494 | vidtv_psi_service_list_desc_init(head, | ||
| 495 | desc_service_list->service_list); | ||
| 496 | break; | ||
| 497 | |||
| 498 | case SHORT_EVENT_DESCRIPTOR: | ||
| 499 | desc_short_event = (struct vidtv_psi_desc_short_event *)desc; | ||
| 500 | curr = (struct vidtv_psi_desc *) | ||
| 501 | vidtv_psi_short_event_desc_init(head, | ||
| 502 | desc_short_event->iso_language_code, | ||
| 503 | desc_short_event->event_name, | ||
| 504 | desc_short_event->text); | ||
| 408 | break; | 505 | break; |
| 409 | 506 | ||
| 410 | case REGISTRATION_DESCRIPTOR: | 507 | case REGISTRATION_DESCRIPTOR: |
| 411 | default: | 508 | default: |
| 412 | curr = kzalloc(sizeof(*desc) + desc->length, GFP_KERNEL); | 509 | curr = kzalloc(sizeof(*desc) + desc->length, GFP_KERNEL); |
| 510 | if (!curr) | ||
| 511 | return NULL; | ||
| 413 | memcpy(curr, desc, sizeof(*desc) + desc->length); | 512 | memcpy(curr, desc, sizeof(*desc) + desc->length); |
| 414 | break; | 513 | } |
| 415 | } | ||
| 416 | 514 | ||
| 417 | if (curr) | 515 | if (!curr) |
| 418 | curr->next = NULL; | 516 | return NULL; |
| 517 | |||
| 518 | curr->next = NULL; | ||
| 419 | if (!head) | 519 | if (!head) |
| 420 | head = curr; | 520 | head = curr; |
| 421 | if (prev) | 521 | if (prev) |
| @@ -430,6 +530,8 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) · 8 unmodified lines | |||
| 430 | 530 | ||
| 431 | void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) | 531 | void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) |
| 432 | { | 532 | { |
| 533 | struct vidtv_psi_desc_service_list_entry *sl_entry_tmp = NULL; | ||
| 534 | struct vidtv_psi_desc_service_list_entry *sl_entry = NULL; | ||
| 433 | struct vidtv_psi_desc *curr = desc; | 535 | struct vidtv_psi_desc *curr = desc; |
| 434 | struct vidtv_psi_desc *tmp = NULL; | 536 | struct vidtv_psi_desc *tmp = NULL; |
| 435 | 537 | ||
| @@ -447,6 +549,25 @@ void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc) · 11 unmodified lines | |||
| 447 | /* nothing to do */ | 549 | /* nothing to do */ |
| 448 | break; | 550 | break; |
| 449 | 551 | ||
| 552 | case NETWORK_NAME_DESCRIPTOR: | ||
| 553 | kfree(((struct vidtv_psi_desc_network_name *)tmp)->network_name); | ||
| 554 | break; | ||
| 555 | |||
| 556 | case SERVICE_LIST_DESCRIPTOR: | ||
| 557 | sl_entry = ((struct vidtv_psi_desc_service_list *)tmp)->service_list; | ||
| 558 | while (sl_entry) { | ||
| 559 | sl_entry_tmp = sl_entry; | ||
| 560 | sl_entry = sl_entry->next; | ||
| 561 | kfree(sl_entry_tmp); | ||
| 562 | } | ||
| 563 | break; | ||
| 564 | |||
| 565 | case SHORT_EVENT_DESCRIPTOR: | ||
| 566 | kfree(((struct vidtv_psi_desc_short_event *)tmp)->iso_language_code); | ||
| 567 | kfree(((struct vidtv_psi_desc_short_event *)tmp)->event_name); | ||
| 568 | kfree(((struct vidtv_psi_desc_short_event *)tmp)->text); | ||
| 569 | break; | ||
| 570 | |||
| 450 | default: | 571 | default: |
| 451 | pr_warn_ratelimited("Possible leak: not handling descriptor type %d\n", | 572 | pr_warn_ratelimited("Possible leak: not handling descriptor type %d\n", |
| 452 | tmp->type); | 573 | tmp->type); |
| @@ -513,63 +634,119 @@ void vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt, · 60 unmodified lines | |||
| 513 | vidtv_psi_update_version_num(&sdt->header); | 634 | vidtv_psi_update_version_num(&sdt->header); |
| 514 | } | 635 | } |
| 515 | 636 | ||
| 516 | static u32 vidtv_psi_desc_write_into(struct desc_write_args args) | 637 | static u32 vidtv_psi_desc_write_into(struct desc_write_args *args) |
| 517 | { | 638 | { |
| 518 | /* the number of bytes written by this function */ | 639 | struct psi_write_args psi_args = { |
| 640 | .dest_buf = args->dest_buf, | ||
| 641 | .from = &args->desc->type, | ||
| 642 | .pid = args->pid, | ||
| 643 | .new_psi_section = false, | ||
| 644 | .continuity_counter = args->continuity_counter, | ||
| 645 | .is_crc = false, | ||
| 646 | .dest_buf_sz = args->dest_buf_sz, | ||
| 647 | .crc = args->crc, | ||
| 648 | .len = sizeof_field(struct vidtv_psi_desc, type) + | ||
| 649 | sizeof_field(struct vidtv_psi_desc, length), | ||
| 650 | }; | ||
| 651 | struct vidtv_psi_desc_service_list_entry *serv_list_entry = NULL; | ||
| 519 | u32 nbytes = 0; | 652 | u32 nbytes = 0; |
| 520 | struct psi_write_args psi_args = {}; | ||
| 521 | |||
| 522 | psi_args.dest_buf = args.dest_buf; | ||
| 523 | psi_args.from = &args.desc->type; | ||
| 524 | 653 | ||
| 525 | psi_args.len = sizeof_field(struct vidtv_psi_desc, type) + | 654 | psi_args.dest_offset = args->dest_offset + nbytes; |
| 526 | sizeof_field(struct vidtv_psi_desc, length); | ||
| 527 | 655 | ||
| 528 | psi_args.dest_offset = args.dest_offset + nbytes; | 656 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 529 | psi_args.pid = args.pid; | ||
| 530 | psi_args.new_psi_section = false; | ||
| 531 | psi_args.continuity_counter = args.continuity_counter; | ||
| 532 | psi_args.is_crc = false; | ||
| 533 | psi_args.dest_buf_sz = args.dest_buf_sz; | ||
| 534 | psi_args.crc = args.crc; | ||
| 535 | 657 | ||
| 536 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 658 | switch (args->desc->type) { |
| 537 | |||
| 538 | switch (args.desc->type) { | ||
| 539 | case SERVICE_DESCRIPTOR: | 659 | case SERVICE_DESCRIPTOR: |
| 540 | psi_args.dest_offset = args.dest_offset + nbytes; | 660 | psi_args.dest_offset = args->dest_offset + nbytes; |
| 541 | psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_type) + | 661 | psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_type) + |
| 542 | sizeof_field(struct vidtv_psi_desc_service, provider_name_len); | 662 | sizeof_field(struct vidtv_psi_desc_service, provider_name_len); |
| 543 | psi_args.from = &((struct vidtv_psi_desc_service *)args.desc)->service_type; | 663 | psi_args.from = &((struct vidtv_psi_desc_service *)args->desc)->service_type; |
| 544 | 664 | ||
| 545 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 665 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 546 | 666 | ||
| 547 | psi_args.dest_offset = args.dest_offset + nbytes; | 667 | psi_args.dest_offset = args->dest_offset + nbytes; |
| 548 | psi_args.len = ((struct vidtv_psi_desc_service *)args.desc)->provider_name_len; | 668 | psi_args.len = ((struct vidtv_psi_desc_service *)args->desc)->provider_name_len; |
| 549 | psi_args.from = ((struct vidtv_psi_desc_service *)args.desc)->provider_name; | 669 | psi_args.from = ((struct vidtv_psi_desc_service *)args->desc)->provider_name; |
| 550 | 670 | ||
| 551 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 671 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 552 | 672 | ||
| 553 | psi_args.dest_offset = args.dest_offset + nbytes; | 673 | psi_args.dest_offset = args->dest_offset + nbytes; |
| 554 | psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_name_len); | 674 | psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_name_len); |
| 555 | psi_args.from = &((struct vidtv_psi_desc_service *)args.desc)->service_name_len; | 675 | psi_args.from = &((struct vidtv_psi_desc_service *)args->desc)->service_name_len; |
| 556 | 676 | ||
| 557 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 677 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 558 | 678 | ||
| 559 | psi_args.dest_offset = args.dest_offset + nbytes; | 679 | psi_args.dest_offset = args->dest_offset + nbytes; |
| 560 | psi_args.len = ((struct vidtv_psi_desc_service *)args.desc)->service_name_len; | 680 | psi_args.len = ((struct vidtv_psi_desc_service *)args->desc)->service_name_len; |
| 561 | psi_args.from = ((struct vidtv_psi_desc_service *)args.desc)->service_name; | 681 | psi_args.from = ((struct vidtv_psi_desc_service *)args->desc)->service_name; |
| 682 | |||
| 683 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 684 | break; | ||
| 685 | |||
| 686 | case NETWORK_NAME_DESCRIPTOR: | ||
| 687 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 688 | psi_args.len = args->desc->length; | ||
| 689 | psi_args.from = ((struct vidtv_psi_desc_network_name *)args->desc)->network_name; | ||
| 690 | |||
| 691 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 692 | break; | ||
| 693 | |||
| 694 | case SERVICE_LIST_DESCRIPTOR: | ||
| 695 | serv_list_entry = ((struct vidtv_psi_desc_service_list *)args->desc)->service_list; | ||
| 696 | while (serv_list_entry) { | ||
| 697 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 698 | psi_args.len = sizeof(struct vidtv_psi_desc_service_list_entry) - | ||
| 699 | sizeof(struct vidtv_psi_desc_service_list_entry *); | ||
| 700 | psi_args.from = serv_list_entry; | ||
| 701 | |||
| 702 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 703 | |||
| 704 | serv_list_entry = serv_list_entry->next; | ||
| 705 | } | ||
| 706 | break; | ||
| 707 | |||
| 708 | case SHORT_EVENT_DESCRIPTOR: | ||
| 709 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 710 | psi_args.len = ISO_LANGUAGE_CODE_LEN; | ||
| 711 | psi_args.from = ((struct vidtv_psi_desc_short_event *) | ||
| 712 | args->desc)->iso_language_code; | ||
| 713 | |||
| 714 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 715 | |||
| 716 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 717 | psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, event_name_len); | ||
| 718 | psi_args.from = &((struct vidtv_psi_desc_short_event *) | ||
| 719 | args->desc)->event_name_len; | ||
| 720 | |||
| 721 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 722 | |||
| 723 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 724 | psi_args.len = ((struct vidtv_psi_desc_short_event *)args->desc)->event_name_len; | ||
| 725 | psi_args.from = ((struct vidtv_psi_desc_short_event *)args->desc)->event_name; | ||
| 726 | |||
| 727 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 728 | |||
| 729 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 730 | psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, text_len); | ||
| 731 | psi_args.from = &((struct vidtv_psi_desc_short_event *)args->desc)->text_len; | ||
| 732 | |||
| 733 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 734 | |||
| 735 | psi_args.dest_offset = args->dest_offset + nbytes; | ||
| 736 | psi_args.len = ((struct vidtv_psi_desc_short_event *)args->desc)->text_len; | ||
| 737 | psi_args.from = ((struct vidtv_psi_desc_short_event *)args->desc)->text; | ||
| 738 | |||
| 739 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 562 | 740 | ||
| 563 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | ||
| 564 | break; | 741 | break; |
| 565 | 742 | ||
| 566 | case REGISTRATION_DESCRIPTOR: | 743 | case REGISTRATION_DESCRIPTOR: |
| 567 | default: | 744 | default: |
| 568 | psi_args.dest_offset = args.dest_offset + nbytes; | 745 | psi_args.dest_offset = args->dest_offset + nbytes; |
| 569 | psi_args.len = args.desc->length; | 746 | psi_args.len = args->desc->length; |
| 570 | psi_args.from = &args.desc->data; | 747 | psi_args.from = &args->desc->data; |
| 571 | 748 | ||
| 572 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 749 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 573 | break; | 750 | break; |
| 574 | } | 751 | } |
| 575 | 752 | ||
| @@ -577,40 +754,37 @@ static u32 vidtv_psi_desc_write_into(struct desc_write_args args) · 1 unmodified line | |||
| 577 | } | 754 | } |
| 578 | 755 | ||
| 579 | static u32 | 756 | static u32 |
| 580 | vidtv_psi_table_header_write_into(struct header_write_args args) | 757 | vidtv_psi_table_header_write_into(struct header_write_args *args) |
| 581 | { | 758 | { |
| 582 | /* the number of bytes written by this function */ | 759 | struct psi_write_args psi_args = { |
| 583 | u32 nbytes = 0; | 760 | .dest_buf = args->dest_buf, |
| 584 | struct psi_write_args psi_args = {}; | 761 | .from = args->h, |
| 585 | 762 | .len = sizeof(struct vidtv_psi_table_header), | |
| 586 | psi_args.dest_buf = args.dest_buf; | 763 | .dest_offset = args->dest_offset, |
| 587 | psi_args.from = args.h; | 764 | .pid = args->pid, |
| 588 | psi_args.len = sizeof(struct vidtv_psi_table_header); | 765 | .new_psi_section = true, |
| 589 | psi_args.dest_offset = args.dest_offset; | 766 | .continuity_counter = args->continuity_counter, |
| 590 | psi_args.pid = args.pid; | 767 | .is_crc = false, |
| 591 | psi_args.new_psi_section = true; | 768 | .dest_buf_sz = args->dest_buf_sz, |
| 592 | psi_args.continuity_counter = args.continuity_counter; | 769 | .crc = args->crc, |
| 593 | psi_args.is_crc = false; | 770 | }; |
| 594 | psi_args.dest_buf_sz = args.dest_buf_sz; | 771 | |
| 595 | psi_args.crc = args.crc; | 772 | return vidtv_psi_ts_psi_write_into(&psi_args); |
| 596 | |||
| 597 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | ||
| 598 | |||
| 599 | return nbytes; | ||
| 600 | } | 773 | } |
| 601 | 774 | ||
| 602 | void | 775 | void |
| 603 | vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat) | 776 | vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat) |
| 604 | { | 777 | { |
| 605 | /* see ISO/IEC 13818-1 : 2000 p.43 */ | ||
| 606 | u16 length = 0; | 778 | u16 length = 0; |
| 607 | u32 i; | 779 | u32 i; |
| 608 | 780 | ||
| 781 | /* see ISO/IEC 13818-1 : 2000 p.43 */ | ||
| 782 | |||
| 609 | /* from immediately after 'section_length' until 'last_section_number'*/ | 783 | /* from immediately after 'section_length' until 'last_section_number'*/ |
| 610 | length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER; | 784 | length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER; |
| 611 | 785 | ||
| 612 | /* do not count the pointer */ | 786 | /* do not count the pointer */ |
| 613 | for (i = 0; i < pat->programs; ++i) | 787 | for (i = 0; i < pat->num_pat; ++i) |
| 614 | length += sizeof(struct vidtv_psi_table_pat_program) - | 788 | length += sizeof(struct vidtv_psi_table_pat_program) - |
| 615 | sizeof(struct vidtv_psi_table_pat_program *); | 789 | sizeof(struct vidtv_psi_table_pat_program *); |
| 616 | 790 | ||
| @@ -621,10 +795,11 @@ vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat) · 4 unmodified lines | |||
| 621 | 795 | ||
| 622 | void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt) | 796 | void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt) |
| 623 | { | 797 | { |
| 624 | /* see ISO/IEC 13818-1 : 2000 p.46 */ | ||
| 625 | u16 length = 0; | ||
| 626 | struct vidtv_psi_table_pmt_stream *s = pmt->stream; | 798 | struct vidtv_psi_table_pmt_stream *s = pmt->stream; |
| 627 | u16 desc_loop_len; | 799 | u16 desc_loop_len; |
| 800 | u16 length = 0; | ||
| 801 | |||
| 802 | /* see ISO/IEC 13818-1 : 2000 p.46 */ | ||
| 628 | 803 | ||
| 629 | /* from immediately after 'section_length' until 'program_info_length'*/ | 804 | /* from immediately after 'section_length' until 'program_info_length'*/ |
| 630 | length += PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH; | 805 | length += PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH; |
| @@ -655,10 +830,11 @@ void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt) · 24 unmodified lines | |||
| 655 | 830 | ||
| 656 | void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt) | 831 | void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt) |
| 657 | { | 832 | { |
| 658 | /* see ETSI EN 300 468 V 1.10.1 p.24 */ | ||
| 659 | u16 length = 0; | ||
| 660 | struct vidtv_psi_table_sdt_service *s = sdt->service; | 833 | struct vidtv_psi_table_sdt_service *s = sdt->service; |
| 661 | u16 desc_loop_len; | 834 | u16 desc_loop_len; |
| 835 | u16 length = 0; | ||
| 836 | |||
| 837 | /* see ETSI EN 300 468 V 1.10.1 p.24 */ | ||
| 662 | 838 | ||
| 663 | /* | 839 | /* |
| 664 | * from immediately after 'section_length' until | 840 | * from immediately after 'section_length' until |
| @@ -681,7 +857,6 @@ void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt) · 16 unmodified lines | |||
| 681 | } | 857 | } |
| 682 | 858 | ||
| 683 | length += CRC_SIZE_IN_BYTES; | 859 | length += CRC_SIZE_IN_BYTES; |
| 684 | |||
| 685 | vidtv_psi_set_sec_len(&sdt->header, length); | 860 | vidtv_psi_set_sec_len(&sdt->header, length); |
| 686 | } | 861 | } |
| 687 | 862 | ||
| @@ -694,6 +869,8 @@ vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, · 6 unmodified lines | |||
| 694 | const u16 RESERVED = 0x07; | 869 | const u16 RESERVED = 0x07; |
| 695 | 870 | ||
| 696 | program = kzalloc(sizeof(*program), GFP_KERNEL); | 871 | program = kzalloc(sizeof(*program), GFP_KERNEL); |
| 872 | if (!program) | ||
| 873 | return NULL; | ||
| 697 | 874 | ||
| 698 | program->service_id = cpu_to_be16(service_id); | 875 | program->service_id = cpu_to_be16(service_id); |
| 699 | 876 | ||
| @@ -714,8 +891,8 @@ vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, · 14 unmodified lines | |||
| 714 | void | 891 | void |
| 715 | vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p) | 892 | vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p) |
| 716 | { | 893 | { |
| 717 | struct vidtv_psi_table_pat_program *curr = p; | ||
| 718 | struct vidtv_psi_table_pat_program *tmp = NULL; | 894 | struct vidtv_psi_table_pat_program *tmp = NULL; |
| 895 | struct vidtv_psi_table_pat_program *curr = p; | ||
| 719 | 896 | ||
| 720 | while (curr) { | 897 | while (curr) { |
| 721 | tmp = curr; | 898 | tmp = curr; |
| @@ -724,42 +901,49 @@ vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p) · 2 unmodified lines | |||
| 724 | } | 901 | } |
| 725 | } | 902 | } |
| 726 | 903 | ||
| 904 | /* This function transfers ownership of p to the table */ | ||
| 727 | void | 905 | void |
| 728 | vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, | 906 | vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, |
| 729 | struct vidtv_psi_table_pat_program *p) | 907 | struct vidtv_psi_table_pat_program *p) |
| 730 | { | 908 | { |
| 731 | /* This function transfers ownership of p to the table */ | 909 | struct vidtv_psi_table_pat_program *program; |
| 910 | u16 program_count; | ||
| 732 | 911 | ||
| 733 | u16 program_count = 0; | 912 | do { |
| 734 | struct vidtv_psi_table_pat_program *program = p; | 913 | program_count = 0; |
| 914 | program = p; | ||
| 735 | 915 | ||
| 736 | if (p == pat->program) | 916 | if (p == pat->program) |
| 737 | return; | 917 | return; |
| 738 | 918 | ||
| 739 | while (program) { | 919 | while (program) { |
| 740 | ++program_count; | 920 | ++program_count; |
| 741 | program = program->next; | 921 | program = program->next; |
| 742 | } | 922 | } |
| 743 | 923 | ||
| 744 | pat->programs = program_count; | 924 | pat->num_pat = program_count; |
| 745 | pat->program = p; | 925 | pat->program = p; |
| 746 | 926 | ||
| 747 | /* Recompute section length */ | 927 | /* Recompute section length */ |
| 748 | vidtv_psi_pat_table_update_sec_len(pat); | 928 | vidtv_psi_pat_table_update_sec_len(pat); |
| 749 | 929 | ||
| 750 | if (vidtv_psi_get_sec_len(&pat->header) > MAX_SECTION_LEN) | 930 | p = NULL; |
| 751 | vidtv_psi_pat_program_assign(pat, NULL); | 931 | } while (vidtv_psi_get_sec_len(&pat->header) > MAX_SECTION_LEN); |
| 752 | 932 | ||
| 753 | vidtv_psi_update_version_num(&pat->header); | 933 | vidtv_psi_update_version_num(&pat->header); |
| 754 | } | 934 | } |
| 755 | 935 | ||
| 756 | struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) | 936 | struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) |
| 757 | { | 937 | { |
| 758 | struct vidtv_psi_table_pat *pat = kzalloc(sizeof(*pat), GFP_KERNEL); | 938 | struct vidtv_psi_table_pat *pat; |
| 759 | const u16 SYNTAX = 0x1; | 939 | const u16 SYNTAX = 0x1; |
| 760 | const u16 ZERO = 0x0; | 940 | const u16 ZERO = 0x0; |
| 761 | const u16 ONES = 0x03; | 941 | const u16 ONES = 0x03; |
| 762 | 942 | ||
| 943 | pat = kzalloc(sizeof(*pat), GFP_KERNEL); | ||
| 944 | if (!pat) | ||
| 945 | return NULL; | ||
| 946 | |||
| 763 | pat->header.table_id = 0x0; | 947 | pat->header.table_id = 0x0; |
| 764 | 948 | ||
| 765 | pat->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ZERO << 14) | (ONES << 12)); | 949 | pat->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ZERO << 14) | (ONES << 12)); |
| @@ -772,70 +956,68 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) · 6 unmodified lines | |||
| 772 | pat->header.section_id = 0x0; | 956 | pat->header.section_id = 0x0; |
| 773 | pat->header.last_section = 0x0; | 957 | pat->header.last_section = 0x0; |
| 774 | 958 | ||
| 775 | pat->programs = 0; | ||
| 776 | |||
| 777 | vidtv_psi_pat_table_update_sec_len(pat); | 959 | vidtv_psi_pat_table_update_sec_len(pat); |
| 778 | 960 | ||
| 779 | return pat; | 961 | return pat; |
| 780 | } | 962 | } |
| 781 | 963 | ||
| 782 | u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args) | 964 | u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args) |
| 783 | { | 965 | { |
| 784 | /* the number of bytes written by this function */ | 966 | struct vidtv_psi_table_pat_program *p = args->pat->program; |
| 967 | struct header_write_args h_args = { | ||
| 968 | .dest_buf = args->buf, | ||
| 969 | .dest_offset = args->offset, | ||
| 970 | .pid = VIDTV_PAT_PID, | ||
| 971 | .h = &args->pat->header, | ||
| 972 | .continuity_counter = args->continuity_counter, | ||
| 973 | .dest_buf_sz = args->buf_sz, | ||
| 974 | }; | ||
| 975 | struct psi_write_args psi_args = { | ||
| 976 | .dest_buf = args->buf, | ||
| 977 | .pid = VIDTV_PAT_PID, | ||
| 978 | .new_psi_section = false, | ||
| 979 | .continuity_counter = args->continuity_counter, | ||
| 980 | .is_crc = false, | ||
| 981 | .dest_buf_sz = args->buf_sz, | ||
| 982 | }; | ||
| 983 | struct crc32_write_args c_args = { | ||
| 984 | .dest_buf = args->buf, | ||
| 985 | .pid = VIDTV_PAT_PID, | ||
| 986 | .dest_buf_sz = args->buf_sz, | ||
| 987 | }; | ||
| 988 | u32 crc = INITIAL_CRC; | ||
| 785 | u32 nbytes = 0; | 989 | u32 nbytes = 0; |
| 786 | const u16 pat_pid = VIDTV_PAT_PID; | ||
| 787 | u32 crc = 0xffffffff; | ||
| 788 | |||
| 789 | struct vidtv_psi_table_pat_program *p = args.pat->program; | ||
| 790 | 990 | ||
| 791 | struct header_write_args h_args = {}; | 991 | vidtv_psi_pat_table_update_sec_len(args->pat); |
| 792 | struct psi_write_args psi_args = {}; | ||
| 793 | struct crc32_write_args c_args = {}; | ||
| 794 | 992 | ||
| 795 | vidtv_psi_pat_table_update_sec_len(args.pat); | ||
| 796 | |||
| 797 | h_args.dest_buf = args.buf; | ||
| 798 | h_args.dest_offset = args.offset; | ||
| 799 | h_args.h = &args.pat->header; | ||
| 800 | h_args.pid = pat_pid; | ||
| 801 | h_args.continuity_counter = args.continuity_counter; | ||
| 802 | h_args.dest_buf_sz = args.buf_sz; | ||
| 803 | h_args.crc = &crc; | 993 | h_args.crc = &crc; |
| 804 | 994 | ||
| 805 | nbytes += vidtv_psi_table_header_write_into(h_args); | 995 | nbytes += vidtv_psi_table_header_write_into(&h_args); |
| 806 | 996 | ||
| 807 | /* note that the field 'u16 programs' is not really part of the PAT */ | 997 | /* note that the field 'u16 programs' is not really part of the PAT */ |
| 808 | 998 | ||
| 809 | psi_args.dest_buf = args.buf; | 999 | psi_args.crc = &crc; |
| 810 | psi_args.pid = pat_pid; | ||
| 811 | psi_args.new_psi_section = false; | ||
| 812 | psi_args.continuity_counter = args.continuity_counter; | ||
| 813 | psi_args.is_crc = false; | ||
| 814 | psi_args.dest_buf_sz = args.buf_sz; | ||
| 815 | psi_args.crc = &crc; | ||
| 816 | 1000 | ||
| 817 | while (p) { | 1001 | while (p) { |
| 818 | /* copy the PAT programs */ | 1002 | /* copy the PAT programs */ |
| 819 | psi_args.from = p; | 1003 | psi_args.from = p; |
| 820 | /* skip the pointer */ | 1004 | /* skip the pointer */ |
| 821 | psi_args.len = sizeof(*p) - | 1005 | psi_args.len = sizeof(*p) - |
| 822 | sizeof(struct vidtv_psi_table_pat_program *); | 1006 | sizeof(struct vidtv_psi_table_pat_program *); |
| 823 | psi_args.dest_offset = args.offset + nbytes; | 1007 | psi_args.dest_offset = args->offset + nbytes; |
| 1008 | psi_args.continuity_counter = args->continuity_counter; | ||
| 824 | 1009 | ||
| 825 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 1010 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 826 | 1011 | ||
| 827 | p = p->next; | 1012 | p = p->next; |
| 828 | } | 1013 | } |
| 829 | 1014 | ||
| 830 | c_args.dest_buf = args.buf; | 1015 | c_args.dest_offset = args->offset + nbytes; |
| 831 | c_args.dest_offset = args.offset + nbytes; | 1016 | c_args.continuity_counter = args->continuity_counter; |
| 832 | c_args.crc = cpu_to_be32(crc); | 1017 | c_args.crc = cpu_to_be32(crc); |
| 833 | c_args.pid = pat_pid; | ||
| 834 | c_args.continuity_counter = args.continuity_counter; | ||
| 835 | c_args.dest_buf_sz = args.buf_sz; | ||
| 836 | 1018 | ||
| 837 | /* Write the CRC32 at the end */ | 1019 | /* Write the CRC32 at the end */ |
| 838 | nbytes += table_section_crc32_write_into(c_args); | 1020 | nbytes += table_section_crc32_write_into(&c_args); |
| 839 | 1021 | ||
| 840 | return nbytes; | 1022 | return nbytes; |
| 841 | } | 1023 | } |
| @@ -859,6 +1041,8 @@ vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head, · 17 unmodified lines | |||
| 859 | u16 desc_loop_len; | 1041 | u16 desc_loop_len; |
| 860 | 1042 | ||
| 861 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | 1043 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); |
| 1044 | if (!stream) | ||
| 1045 | return NULL; | ||
| 862 | 1046 | ||
| 863 | stream->type = stream_type; | 1047 | stream->type = stream_type; |
| 864 | 1048 | ||
| @@ -883,8 +1067,8 @@ vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head, · 18 unmodified lines | |||
| 883 | 1067 | ||
| 884 | void vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s) | 1068 | void vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s) |
| 885 | { | 1069 | { |
| 886 | struct vidtv_psi_table_pmt_stream *curr_stream = s; | ||
| 887 | struct vidtv_psi_table_pmt_stream *tmp_stream = NULL; | 1070 | struct vidtv_psi_table_pmt_stream *tmp_stream = NULL; |
| 1071 | struct vidtv_psi_table_pmt_stream *curr_stream = s; | ||
| 888 | 1072 | ||
| 889 | while (curr_stream) { | 1073 | while (curr_stream) { |
| 890 | tmp_stream = curr_stream; | 1074 | tmp_stream = curr_stream; |
| @@ -897,15 +1081,16 @@ void vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s) · 6 unmodified lines | |||
| 897 | void vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt, | 1081 | void vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt, |
| 898 | struct vidtv_psi_table_pmt_stream *s) | 1082 | struct vidtv_psi_table_pmt_stream *s) |
| 899 | { | 1083 | { |
| 900 | /* This function transfers ownership of s to the table */ | 1084 | do { |
| 901 | if (s == pmt->stream) | 1085 | /* This function transfers ownership of s to the table */ |
| 902 | return; | 1086 | if (s == pmt->stream) |
| 1087 | return; | ||
| 903 | 1088 | ||
| 904 | pmt->stream = s; | 1089 | pmt->stream = s; |
| 905 | vidtv_psi_pmt_table_update_sec_len(pmt); | 1090 | vidtv_psi_pmt_table_update_sec_len(pmt); |
| 906 | 1091 | ||
| 907 | if (vidtv_psi_get_sec_len(&pmt->header) > MAX_SECTION_LEN) | 1092 | s = NULL; |
| 908 | vidtv_psi_pmt_stream_assign(pmt, NULL); | 1093 | } while (vidtv_psi_get_sec_len(&pmt->header) > MAX_SECTION_LEN); |
| 909 | 1094 | ||
| 910 | vidtv_psi_update_version_num(&pmt->header); | 1095 | vidtv_psi_update_version_num(&pmt->header); |
| 911 | } | 1096 | } |
| @@ -933,14 +1118,18 @@ u16 vidtv_psi_pmt_get_pid(struct vidtv_psi_table_pmt *section, · 21 unmodified lines | |||
| 933 | struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, | 1118 | struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, |
| 934 | u16 pcr_pid) | 1119 | u16 pcr_pid) |
| 935 | { | 1120 | { |
| 936 | struct vidtv_psi_table_pmt *pmt = kzalloc(sizeof(*pmt), GFP_KERNEL); | 1121 | struct vidtv_psi_table_pmt *pmt; |
| 937 | const u16 SYNTAX = 0x1; | ||
| 938 | const u16 ZERO = 0x0; | ||
| 939 | const u16 ONES = 0x03; | ||
| 940 | const u16 RESERVED1 = 0x07; | 1122 | const u16 RESERVED1 = 0x07; |
| 941 | const u16 RESERVED2 = 0x0f; | 1123 | const u16 RESERVED2 = 0x0f; |
| 1124 | const u16 SYNTAX = 0x1; | ||
| 1125 | const u16 ONES = 0x03; | ||
| 1126 | const u16 ZERO = 0x0; | ||
| 942 | u16 desc_loop_len; | 1127 | u16 desc_loop_len; |
| 943 | 1128 | ||
| 1129 | pmt = kzalloc(sizeof(*pmt), GFP_KERNEL); | ||
| 1130 | if (!pmt) | ||
| 1131 | return NULL; | ||
| 1132 | |||
| 944 | if (!pcr_pid) | 1133 | if (!pcr_pid) |
| 945 | pcr_pid = 0x1fff; | 1134 | pcr_pid = 0x1fff; |
| 946 | 1135 | ||
| @@ -970,87 +1159,84 @@ struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, · 23 unmodified lines | |||
| 970 | return pmt; | 1159 | return pmt; |
| 971 | } | 1160 | } |
| 972 | 1161 | ||
| 973 | u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) | 1162 | u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args) |
| 974 | { | 1163 | { |
| 975 | /* the number of bytes written by this function */ | 1164 | struct vidtv_psi_desc *table_descriptor = args->pmt->descriptor; |
| 1165 | struct vidtv_psi_table_pmt_stream *stream = args->pmt->stream; | ||
| 1166 | struct vidtv_psi_desc *stream_descriptor; | ||
| 1167 | struct header_write_args h_args = { | ||
| 1168 | .dest_buf = args->buf, | ||
| 1169 | .dest_offset = args->offset, | ||
| 1170 | .h = &args->pmt->header, | ||
| 1171 | .pid = args->pid, | ||
| 1172 | .continuity_counter = args->continuity_counter, | ||
| 1173 | .dest_buf_sz = args->buf_sz, | ||
| 1174 | }; | ||
| 1175 | struct psi_write_args psi_args = { | ||
| 1176 | .dest_buf = args->buf, | ||
| 1177 | .from = &args->pmt->bitfield, | ||
| 1178 | .len = sizeof_field(struct vidtv_psi_table_pmt, bitfield) + | ||
| 1179 | sizeof_field(struct vidtv_psi_table_pmt, bitfield2), | ||
| 1180 | .pid = args->pid, | ||
| 1181 | .new_psi_section = false, | ||
| 1182 | .is_crc = false, | ||
| 1183 | .dest_buf_sz = args->buf_sz, | ||
| 1184 | }; | ||
| 1185 | struct desc_write_args d_args = { | ||
| 1186 | .dest_buf = args->buf, | ||
| 1187 | .desc = table_descriptor, | ||
| 1188 | .pid = args->pid, | ||
| 1189 | .dest_buf_sz = args->buf_sz, | ||
| 1190 | }; | ||
| 1191 | struct crc32_write_args c_args = { | ||
| 1192 | .dest_buf = args->buf, | ||
| 1193 | .pid = args->pid, | ||
| 1194 | .dest_buf_sz = args->buf_sz, | ||
| 1195 | }; | ||
| 1196 | u32 crc = INITIAL_CRC; | ||
| 976 | u32 nbytes = 0; | 1197 | u32 nbytes = 0; |
| 977 | u32 crc = 0xffffffff; | 1198 | |
| 978 | 1199 | vidtv_psi_pmt_table_update_sec_len(args->pmt); | |
| 979 | struct vidtv_psi_desc *table_descriptor = args.pmt->descriptor; | 1200 | |
| 980 | struct vidtv_psi_table_pmt_stream *stream = args.pmt->stream; | ||
| 981 | struct vidtv_psi_desc *stream_descriptor = (stream) ? | ||
| 982 | args.pmt->stream->descriptor : | ||
| 983 | NULL; | ||
| 984 | |||
| 985 | struct header_write_args h_args = {}; | ||
| 986 | struct psi_write_args psi_args = {}; | ||
| 987 | struct desc_write_args d_args = {}; | ||
| 988 | struct crc32_write_args c_args = {}; | ||
| 989 | |||
| 990 | vidtv_psi_pmt_table_update_sec_len(args.pmt); | ||
| 991 | |||
| 992 | h_args.dest_buf = args.buf; | ||
| 993 | h_args.dest_offset = args.offset; | ||
| 994 | h_args.h = &args.pmt->header; | ||
| 995 | h_args.pid = args.pid; | ||
| 996 | h_args.continuity_counter = args.continuity_counter; | ||
| 997 | h_args.dest_buf_sz = args.buf_sz; | ||
| 998 | h_args.crc = &crc; | 1201 | h_args.crc = &crc; |
| 999 | 1202 | ||
| 1000 | nbytes += vidtv_psi_table_header_write_into(h_args); | 1203 | nbytes += vidtv_psi_table_header_write_into(&h_args); |
| 1001 | 1204 | ||
| 1002 | /* write the two bitfields */ | 1205 | /* write the two bitfields */ |
| 1003 | psi_args.dest_buf = args.buf; | 1206 | psi_args.dest_offset = args->offset + nbytes; |
| 1004 | psi_args.from = &args.pmt->bitfield; | 1207 | psi_args.continuity_counter = args->continuity_counter; |
| 1005 | psi_args.len = sizeof_field(struct vidtv_psi_table_pmt, bitfield) + | 1208 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 1006 | sizeof_field(struct vidtv_psi_table_pmt, bitfield2); | ||
| 1007 | |||
| 1008 | psi_args.dest_offset = args.offset + nbytes; | ||
| 1009 | psi_args.pid = args.pid; | ||
| 1010 | psi_args.new_psi_section = false; | ||
| 1011 | psi_args.continuity_counter = args.continuity_counter; | ||
| 1012 | psi_args.is_crc = false; | ||
| 1013 | psi_args.dest_buf_sz = args.buf_sz; | ||
| 1014 | psi_args.crc = &crc; | ||
| 1015 | |||
| 1016 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | ||
| 1017 | 1209 | ||
| 1018 | while (table_descriptor) { | 1210 | while (table_descriptor) { |
| 1019 | /* write the descriptors, if any */ | 1211 | /* write the descriptors, if any */ |
| 1020 | d_args.dest_buf = args.buf; | 1212 | d_args.dest_offset = args->offset + nbytes; |
| 1021 | d_args.dest_offset = args.offset + nbytes; | 1213 | d_args.continuity_counter = args->continuity_counter; |
| 1022 | d_args.desc = table_descriptor; | ||
| 1023 | d_args.pid = args.pid; | ||
| 1024 | d_args.continuity_counter = args.continuity_counter; | ||
| 1025 | d_args.dest_buf_sz = args.buf_sz; | ||
| 1026 | d_args.crc = &crc; | 1214 | d_args.crc = &crc; |
| 1027 | 1215 | ||
| 1028 | nbytes += vidtv_psi_desc_write_into(d_args); | 1216 | nbytes += vidtv_psi_desc_write_into(&d_args); |
| 1029 | 1217 | ||
| 1030 | table_descriptor = table_descriptor->next; | 1218 | table_descriptor = table_descriptor->next; |
| 1031 | } | 1219 | } |
| 1032 | 1220 | ||
| 1221 | psi_args.len += sizeof_field(struct vidtv_psi_table_pmt_stream, type); | ||
| 1033 | while (stream) { | 1222 | while (stream) { |
| 1034 | /* write the streams, if any */ | 1223 | /* write the streams, if any */ |
| 1035 | psi_args.from = stream; | 1224 | psi_args.from = stream; |
| 1036 | psi_args.len = sizeof_field(struct vidtv_psi_table_pmt_stream, type) + | 1225 | psi_args.dest_offset = args->offset + nbytes; |
| 1037 | sizeof_field(struct vidtv_psi_table_pmt_stream, bitfield) + | 1226 | psi_args.continuity_counter = args->continuity_counter; |
| 1038 | sizeof_field(struct vidtv_psi_table_pmt_stream, bitfield2); | 1227 | |
| 1039 | psi_args.dest_offset = args.offset + nbytes; | 1228 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 1040 | 1229 | ||
| 1041 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 1230 | stream_descriptor = stream->descriptor; |
| 1042 | 1231 | ||
| 1043 | while (stream_descriptor) { | 1232 | while (stream_descriptor) { |
| 1044 | /* write the stream descriptors, if any */ | 1233 | /* write the stream descriptors, if any */ |
| 1045 | d_args.dest_buf = args.buf; | 1234 | d_args.dest_offset = args->offset + nbytes; |
| 1046 | d_args.dest_offset = args.offset + nbytes; | ||
| 1047 | d_args.desc = stream_descriptor; | 1235 | d_args.desc = stream_descriptor; |
| 1048 | d_args.pid = args.pid; | 1236 | d_args.continuity_counter = args->continuity_counter; |
| 1049 | d_args.continuity_counter = args.continuity_counter; | ||
| 1050 | d_args.dest_buf_sz = args.buf_sz; | ||
| 1051 | d_args.crc = &crc; | 1237 | d_args.crc = &crc; |
| 1052 | 1238 | ||
| 1053 | nbytes += vidtv_psi_desc_write_into(d_args); | 1239 | nbytes += vidtv_psi_desc_write_into(&d_args); |
| 1054 | 1240 | ||
| 1055 | stream_descriptor = stream_descriptor->next; | 1241 | stream_descriptor = stream_descriptor->next; |
| 1056 | } | 1242 | } |
| @@ -1058,15 +1244,12 @@ u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args) · 1 unmodified line | |||
| 1058 | stream = stream->next; | 1244 | stream = stream->next; |
| 1059 | } | 1245 | } |
| 1060 | 1246 | ||
| 1061 | c_args.dest_buf = args.buf; | 1247 | c_args.dest_offset = args->offset + nbytes; |
| 1062 | c_args.dest_offset = args.offset + nbytes; | ||
| 1063 | c_args.crc = cpu_to_be32(crc); | 1248 | c_args.crc = cpu_to_be32(crc); |
| 1064 | c_args.pid = args.pid; | 1249 | c_args.continuity_counter = args->continuity_counter; |
| 1065 | c_args.continuity_counter = args.continuity_counter; | ||
| 1066 | c_args.dest_buf_sz = args.buf_sz; | ||
| 1067 | 1250 | ||
| 1068 | /* Write the CRC32 at the end */ | 1251 | /* Write the CRC32 at the end */ |
| 1069 | nbytes += table_section_crc32_write_into(c_args); | 1252 | nbytes += table_section_crc32_write_into(&c_args); |
| 1070 | 1253 | ||
| 1071 | return nbytes; | 1254 | return nbytes; |
| 1072 | } | 1255 | } |
| @@ -1078,16 +1261,20 @@ void vidtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt) · 5 unmodified lines | |||
| 1078 | kfree(pmt); | 1261 | kfree(pmt); |
| 1079 | } | 1262 | } |
| 1080 | 1263 | ||
| 1081 | struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) | 1264 | struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, |
| 1265 | u16 transport_stream_id) | ||
| 1082 | { | 1266 | { |
| 1083 | struct vidtv_psi_table_sdt *sdt = kzalloc(sizeof(*sdt), GFP_KERNEL); | 1267 | struct vidtv_psi_table_sdt *sdt; |
| 1268 | const u16 RESERVED = 0xff; | ||
| 1084 | const u16 SYNTAX = 0x1; | 1269 | const u16 SYNTAX = 0x1; |
| 1085 | const u16 ONE = 0x1; | ||
| 1086 | const u16 ONES = 0x03; | 1270 | const u16 ONES = 0x03; |
| 1087 | const u16 RESERVED = 0xff; | 1271 | const u16 ONE = 0x1; |
| 1088 | 1272 | ||
| 1089 | sdt->header.table_id = 0x42; | 1273 | sdt = kzalloc(sizeof(*sdt), GFP_KERNEL); |
| 1274 | if (!sdt) | ||
| 1275 | return NULL; | ||
| 1090 | 1276 | ||
| 1277 | sdt->header.table_id = 0x42; | ||
| 1091 | sdt->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); | 1278 | sdt->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); |
| 1092 | 1279 | ||
| 1093 | /* | 1280 | /* |
| @@ -1111,7 +1298,7 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) · 17 unmodified lines | |||
| 1111 | * This can be changed to something more useful, when support for | 1298 | * This can be changed to something more useful, when support for |
| 1112 | * NIT gets added | 1299 | * NIT gets added |
| 1113 | */ | 1300 | */ |
| 1114 | sdt->network_id = cpu_to_be16(0xff01); | 1301 | sdt->network_id = cpu_to_be16(network_id); |
| 1115 | sdt->reserved = RESERVED; | 1302 | sdt->reserved = RESERVED; |
| 1116 | 1303 | ||
| 1117 | vidtv_psi_sdt_table_update_sec_len(sdt); | 1304 | vidtv_psi_sdt_table_update_sec_len(sdt); |
| @@ -1119,74 +1306,79 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id) · 1 unmodified line | |||
| 1119 | return sdt; | 1306 | return sdt; |
| 1120 | } | 1307 | } |
| 1121 | 1308 | ||
| 1122 | u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) | 1309 | u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args) |
| 1123 | { | 1310 | { |
| 1311 | struct header_write_args h_args = { | ||
| 1312 | .dest_buf = args->buf, | ||
| 1313 | .dest_offset = args->offset, | ||
| 1314 | .h = &args->sdt->header, | ||
| 1315 | .pid = VIDTV_SDT_PID, | ||
| 1316 | .dest_buf_sz = args->buf_sz, | ||
| 1317 | }; | ||
| 1318 | struct psi_write_args psi_args = { | ||
| 1319 | .dest_buf = args->buf, | ||
| 1320 | .len = sizeof_field(struct vidtv_psi_table_sdt, network_id) + | ||
| 1321 | sizeof_field(struct vidtv_psi_table_sdt, reserved), | ||
| 1322 | .pid = VIDTV_SDT_PID, | ||
| 1323 | .new_psi_section = false, | ||
| 1324 | .is_crc = false, | ||
| 1325 | .dest_buf_sz = args->buf_sz, | ||
| 1326 | }; | ||
| 1327 | struct desc_write_args d_args = { | ||
| 1328 | .dest_buf = args->buf, | ||
| 1329 | .pid = VIDTV_SDT_PID, | ||
| 1330 | .dest_buf_sz = args->buf_sz, | ||
| 1331 | }; | ||
| 1332 | struct crc32_write_args c_args = { | ||
| 1333 | .dest_buf = args->buf, | ||
| 1334 | .pid = VIDTV_SDT_PID, | ||
| 1335 | .dest_buf_sz = args->buf_sz, | ||
| 1336 | }; | ||
| 1337 | struct vidtv_psi_table_sdt_service *service = args->sdt->service; | ||
| 1338 | struct vidtv_psi_desc *service_desc; | ||
| 1124 | u32 nbytes = 0; | 1339 | u32 nbytes = 0; |
| 1125 | u16 sdt_pid = VIDTV_SDT_PID; /* see ETSI EN 300 468 v1.15.1 p. 11 */ | 1340 | u32 crc = INITIAL_CRC; |
| 1126 | 1341 | ||
| 1127 | u32 crc = 0xffffffff; | 1342 | /* see ETSI EN 300 468 v1.15.1 p. 11 */ |
| 1128 | 1343 | ||
| 1129 | struct vidtv_psi_table_sdt_service *service = args.sdt->service; | 1344 | vidtv_psi_sdt_table_update_sec_len(args->sdt); |
| 1130 | struct vidtv_psi_desc *service_desc = (args.sdt->service) ? | ||
| 1131 | args.sdt->service->descriptor : | ||
| 1132 | NULL; | ||
| 1133 | 1345 | ||
| 1134 | struct header_write_args h_args = {}; | 1346 | h_args.continuity_counter = args->continuity_counter; |
| 1135 | struct psi_write_args psi_args = {}; | ||
| 1136 | struct desc_write_args d_args = {}; | ||
| 1137 | struct crc32_write_args c_args = {}; | ||
| 1138 | |||
| 1139 | vidtv_psi_sdt_table_update_sec_len(args.sdt); | ||
| 1140 | |||
| 1141 | h_args.dest_buf = args.buf; | ||
| 1142 | h_args.dest_offset = args.offset; | ||
| 1143 | h_args.h = &args.sdt->header; | ||
| 1144 | h_args.pid = sdt_pid; | ||
| 1145 | h_args.continuity_counter = args.continuity_counter; | ||
| 1146 | h_args.dest_buf_sz = args.buf_sz; | ||
| 1147 | h_args.crc = &crc; | 1347 | h_args.crc = &crc; |
| 1148 | 1348 | ||
| 1149 | nbytes += vidtv_psi_table_header_write_into(h_args); | 1349 | nbytes += vidtv_psi_table_header_write_into(&h_args); |
| 1150 | |||
| 1151 | psi_args.dest_buf = args.buf; | ||
| 1152 | psi_args.from = &args.sdt->network_id; | ||
| 1153 | 1350 | ||
| 1154 | psi_args.len = sizeof_field(struct vidtv_psi_table_sdt, network_id) + | 1351 | psi_args.from = &args->sdt->network_id; |
| 1155 | sizeof_field(struct vidtv_psi_table_sdt, reserved); | 1352 | psi_args.dest_offset = args->offset + nbytes; |
| 1156 | 1353 | psi_args.continuity_counter = args->continuity_counter; | |
| 1157 | psi_args.dest_offset = args.offset + nbytes; | ||
| 1158 | psi_args.pid = sdt_pid; | ||
| 1159 | psi_args.new_psi_section = false; | ||
| 1160 | psi_args.continuity_counter = args.continuity_counter; | ||
| 1161 | psi_args.is_crc = false; | ||
| 1162 | psi_args.dest_buf_sz = args.buf_sz; | ||
| 1163 | psi_args.crc = &crc; | 1354 | psi_args.crc = &crc; |
| 1164 | 1355 | ||
| 1165 | /* copy u16 network_id + u8 reserved)*/ | 1356 | /* copy u16 network_id + u8 reserved)*/ |
| 1166 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 1357 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 1358 | |||
| 1359 | /* skip both pointers at the end */ | ||
| 1360 | psi_args.len = sizeof(struct vidtv_psi_table_sdt_service) - | ||
| 1361 | sizeof(struct vidtv_psi_desc *) - | ||
| 1362 | sizeof(struct vidtv_psi_table_sdt_service *); | ||
| 1167 | 1363 | ||
| 1168 | while (service) { | 1364 | while (service) { |
| 1169 | /* copy the services, if any */ | 1365 | /* copy the services, if any */ |
| 1170 | psi_args.from = service; | 1366 | psi_args.from = service; |
| 1171 | /* skip both pointers at the end */ | 1367 | psi_args.dest_offset = args->offset + nbytes; |
| 1172 | psi_args.len = sizeof(struct vidtv_psi_table_sdt_service) - | 1368 | psi_args.continuity_counter = args->continuity_counter; |
| 1173 | sizeof(struct vidtv_psi_desc *) - | 1369 | |
| 1174 | sizeof(struct vidtv_psi_table_sdt_service *); | 1370 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); |
| 1175 | psi_args.dest_offset = args.offset + nbytes; | ||
| 1176 | 1371 | ||
| 1177 | nbytes += vidtv_psi_ts_psi_write_into(psi_args); | 1372 | service_desc = service->descriptor; |
| 1178 | 1373 | ||
| 1179 | while (service_desc) { | 1374 | while (service_desc) { |
| 1180 | /* copy the service descriptors, if any */ | 1375 | /* copy the service descriptors, if any */ |
| 1181 | d_args.dest_buf = args.buf; | 1376 | d_args.dest_offset = args->offset + nbytes; |
| 1182 | d_args.dest_offset = args.offset + nbytes; | ||
| 1183 | d_args.desc = service_desc; | 1377 | d_args.desc = service_desc; |
| 1184 | d_args.pid = sdt_pid; | 1378 | d_args.continuity_counter = args->continuity_counter; |
| 1185 | d_args.continuity_counter = args.continuity_counter; | ||
| 1186 | d_args.dest_buf_sz = args.buf_sz; | ||
| 1187 | d_args.crc = &crc; | 1379 | d_args.crc = &crc; |
| 1188 | 1380 | ||
| 1189 | nbytes += vidtv_psi_desc_write_into(d_args); | 1381 | nbytes += vidtv_psi_desc_write_into(&d_args); |
| 1190 | 1382 | ||
| 1191 | service_desc = service_desc->next; | 1383 | service_desc = service_desc->next; |
| 1192 | } | 1384 | } |
| @@ -1194,15 +1386,12 @@ u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args) · 1 unmodified line | |||
| 1194 | service = service->next; | 1386 | service = service->next; |
| 1195 | } | 1387 | } |
| 1196 | 1388 | ||
| 1197 | c_args.dest_buf = args.buf; | 1389 | c_args.dest_offset = args->offset + nbytes; |
| 1198 | c_args.dest_offset = args.offset + nbytes; | ||
| 1199 | c_args.crc = cpu_to_be32(crc); | 1390 | c_args.crc = cpu_to_be32(crc); |
| 1200 | c_args.pid = sdt_pid; | 1391 | c_args.continuity_counter = args->continuity_counter; |
| 1201 | c_args.continuity_counter = args.continuity_counter; | ||
| 1202 | c_args.dest_buf_sz = args.buf_sz; | ||
| 1203 | 1392 | ||
| 1204 | /* Write the CRC at the end */ | 1393 | /* Write the CRC at the end */ |
| 1205 | nbytes += table_section_crc32_write_into(c_args); | 1394 | nbytes += table_section_crc32_write_into(&c_args); |
| 1206 | 1395 | ||
| 1207 | return nbytes; | 1396 | return nbytes; |
| 1208 | } | 1397 | } |
| @@ -1215,11 +1404,15 @@ void vidtv_psi_sdt_table_destroy(struct vidtv_psi_table_sdt *sdt) · 6 unmodified lines | |||
| 1215 | 1404 | ||
| 1216 | struct vidtv_psi_table_sdt_service | 1405 | struct vidtv_psi_table_sdt_service |
| 1217 | *vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, | 1406 | *vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, |
| 1218 | u16 service_id) | 1407 | u16 service_id, |
| 1408 | bool eit_schedule, | ||
| 1409 | bool eit_present_following) | ||
| 1219 | { | 1410 | { |
| 1220 | struct vidtv_psi_table_sdt_service *service; | 1411 | struct vidtv_psi_table_sdt_service *service; |
| 1221 | 1412 | ||
| 1222 | service = kzalloc(sizeof(*service), GFP_KERNEL); | 1413 | service = kzalloc(sizeof(*service), GFP_KERNEL); |
| 1414 | if (!service) | ||
| 1415 | return NULL; | ||
| 1223 | 1416 | ||
| 1224 | /* | 1417 | /* |
| 1225 | * ETSI 300 468: this is a 16bit field which serves as a label to | 1418 | * ETSI 300 468: this is a 16bit field which serves as a label to |
| @@ -1228,8 +1421,8 @@ struct vidtv_psi_table_sdt_service · 2 unmodified lines | |||
| 1228 | * corresponding program_map_section | 1421 | * corresponding program_map_section |
| 1229 | */ | 1422 | */ |
| 1230 | service->service_id = cpu_to_be16(service_id); | 1423 | service->service_id = cpu_to_be16(service_id); |
| 1231 | service->EIT_schedule = 0x0; | 1424 | service->EIT_schedule = eit_schedule; |
| 1232 | service->EIT_present_following = 0x0; | 1425 | service->EIT_present_following = eit_present_following; |
| 1233 | service->reserved = 0x3f; | 1426 | service->reserved = 0x3f; |
| 1234 | 1427 | ||
| 1235 | service->bitfield = cpu_to_be16(RUNNING << 13); | 1428 | service->bitfield = cpu_to_be16(RUNNING << 13); |
| @@ -1262,53 +1455,78 @@ void · 26 unmodified lines | |||
| 1262 | vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt, | 1455 | vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt, |
| 1263 | struct vidtv_psi_table_sdt_service *service) | 1456 | struct vidtv_psi_table_sdt_service *service) |
| 1264 | { | 1457 | { |
| 1265 | if (service == sdt->service) | 1458 | do { |
| 1266 | return; | 1459 | if (service == sdt->service) |
| 1460 | return; | ||
| 1267 | 1461 | ||
| 1268 | sdt->service = service; | 1462 | sdt->service = service; |
| 1269 | 1463 | ||
| 1270 | /* recompute section length */ | 1464 | /* recompute section length */ |
| 1271 | vidtv_psi_sdt_table_update_sec_len(sdt); | 1465 | vidtv_psi_sdt_table_update_sec_len(sdt); |
| 1272 | 1466 | ||
| 1273 | if (vidtv_psi_get_sec_len(&sdt->header) > MAX_SECTION_LEN) | 1467 | service = NULL; |
| 1274 | vidtv_psi_sdt_service_assign(sdt, NULL); | 1468 | } while (vidtv_psi_get_sec_len(&sdt->header) > MAX_SECTION_LEN); |
| 1275 | 1469 | ||
| 1276 | vidtv_psi_update_version_num(&sdt->header); | 1470 | vidtv_psi_update_version_num(&sdt->header); |
| 1277 | } | 1471 | } |
| 1278 | 1472 | ||
| 1473 | /* | ||
| 1474 | * PMTs contain information about programs. For each program, | ||
| 1475 | * there is one PMT section. This function will create a section | ||
| 1476 | * for each program found in the PAT | ||
| 1477 | */ | ||
| 1279 | struct vidtv_psi_table_pmt** | 1478 | struct vidtv_psi_table_pmt** |
| 1280 | vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 pcr_pid) | 1479 | vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, |
| 1480 | u16 pcr_pid) | ||
| 1281 | 1481 | ||
| 1282 | { | 1482 | { |
| 1483 | struct vidtv_psi_table_pat_program *program; | ||
| 1484 | struct vidtv_psi_table_pmt **pmt_secs; | ||
| 1485 | u32 i = 0, num_pmt = 0; | ||
| 1486 | |||
| 1283 | /* | 1487 | /* |
| 1284 | * PMTs contain information about programs. For each program, | 1488 | * The number of PMT entries is the number of PAT entries |
| 1285 | * there is one PMT section. This function will create a section | 1489 | * that contain service_id. That exclude special tables, like NIT |
| 1286 | * for each program found in the PAT | ||
| 1287 | */ | 1490 | */ |
| 1288 | struct vidtv_psi_table_pat_program *program = pat->program; | 1491 | program = pat->program; |
| 1289 | struct vidtv_psi_table_pmt **pmt_secs; | 1492 | while (program) { |
| 1290 | u32 i = 0; | 1493 | if (program->service_id) |
| 1494 | num_pmt++; | ||
| 1495 | program = program->next; | ||
| 1496 | } | ||
| 1291 | 1497 | ||
| 1292 | /* a section for each program_id */ | 1498 | pmt_secs = kcalloc(num_pmt, |
| 1293 | pmt_secs = kcalloc(pat->programs, | ||
| 1294 | sizeof(struct vidtv_psi_table_pmt *), | 1499 | sizeof(struct vidtv_psi_table_pmt *), |
| 1295 | GFP_KERNEL); | 1500 | GFP_KERNEL); |
| 1296 | 1501 | if (!pmt_secs) | |
| 1297 | while (program) { | 1502 | return NULL; |
| 1298 | pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id), pcr_pid); | 1503 | |
| 1299 | ++i; | 1504 | for (program = pat->program; program; program = program->next) { |
| 1300 | program = program->next; | 1505 | if (!program->service_id) |
| 1506 | continue; | ||
| 1507 | pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id), | ||
| 1508 | pcr_pid); | ||
| 1509 | |||
| 1510 | if (!pmt_secs[i]) { | ||
| 1511 | while (i > 0) { | ||
| 1512 | i--; | ||
| 1513 | vidtv_psi_pmt_table_destroy(pmt_secs[i]); | ||
| 1514 | } | ||
| 1515 | return NULL; | ||
| 1516 | } | ||
| 1517 | i++; | ||
| 1301 | } | 1518 | } |
| 1519 | pat->num_pmt = num_pmt; | ||
| 1302 | 1520 | ||
| 1303 | return pmt_secs; | 1521 | return pmt_secs; |
| 1304 | } | 1522 | } |
| 1305 | 1523 | ||
| 1524 | /* find the PMT section associated with 'program_num' */ | ||
| 1306 | struct vidtv_psi_table_pmt | 1525 | struct vidtv_psi_table_pmt |
| 1307 | *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections, | 1526 | *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections, |
| 1308 | u16 nsections, | 1527 | u16 nsections, |
| 1309 | u16 program_num) | 1528 | u16 program_num) |
| 1310 | { | 1529 | { |
| 1311 | /* find the PMT section associated with 'program_num' */ | ||
| 1312 | struct vidtv_psi_table_pmt *sec = NULL; | 1530 | struct vidtv_psi_table_pmt *sec = NULL; |
| 1313 | u32 i; | 1531 | u32 i; |
| 1314 | 1532 | ||
| @@ -1320,3 +1538,488 @@ struct vidtv_psi_table_pmt · 5 unmodified lines | |||
| 1320 | 1538 | ||
| 1321 | return NULL; /* not found */ | 1539 | return NULL; /* not found */ |
| 1322 | } | 1540 | } |
| 1541 | |||
| 1542 | static void vidtv_psi_nit_table_update_sec_len(struct vidtv_psi_table_nit *nit) | ||
| 1543 | { | ||
| 1544 | u16 length = 0; | ||
| 1545 | struct vidtv_psi_table_transport *t = nit->transport; | ||
| 1546 | u16 desc_loop_len; | ||
| 1547 | u16 transport_loop_len = 0; | ||
| 1548 | |||
| 1549 | /* | ||
| 1550 | * from immediately after 'section_length' until | ||
| 1551 | * 'network_descriptor_length' | ||
| 1552 | */ | ||
| 1553 | length += NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN; | ||
| 1554 | |||
| 1555 | desc_loop_len = vidtv_psi_desc_comp_loop_len(nit->descriptor); | ||
| 1556 | vidtv_psi_set_desc_loop_len(&nit->bitfield, desc_loop_len, 12); | ||
| 1557 | |||
| 1558 | length += desc_loop_len; | ||
| 1559 | |||
| 1560 | length += sizeof_field(struct vidtv_psi_table_nit, bitfield2); | ||
| 1561 | |||
| 1562 | while (t) { | ||
| 1563 | /* skip both pointers at the end */ | ||
| 1564 | transport_loop_len += sizeof(struct vidtv_psi_table_transport) - | ||
| 1565 | sizeof(struct vidtv_psi_desc *) - | ||
| 1566 | sizeof(struct vidtv_psi_table_transport *); | ||
| 1567 | |||
| 1568 | length += transport_loop_len; | ||
| 1569 | |||
| 1570 | desc_loop_len = vidtv_psi_desc_comp_loop_len(t->descriptor); | ||
| 1571 | vidtv_psi_set_desc_loop_len(&t->bitfield, desc_loop_len, 12); | ||
| 1572 | |||
| 1573 | length += desc_loop_len; | ||
| 1574 | |||
| 1575 | t = t->next; | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | // Actually sets the transport stream loop len, maybe rename this function later | ||
| 1579 | vidtv_psi_set_desc_loop_len(&nit->bitfield2, transport_loop_len, 12); | ||
| 1580 | length += CRC_SIZE_IN_BYTES; | ||
| 1581 | |||
| 1582 | vidtv_psi_set_sec_len(&nit->header, length); | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | struct vidtv_psi_table_nit | ||
| 1586 | *vidtv_psi_nit_table_init(u16 network_id, | ||
| 1587 | u16 transport_stream_id, | ||
| 1588 | char *network_name, | ||
| 1589 | struct vidtv_psi_desc_service_list_entry *service_list) | ||
| 1590 | { | ||
| 1591 | struct vidtv_psi_table_transport *transport; | ||
| 1592 | struct vidtv_psi_table_nit *nit; | ||
| 1593 | const u16 SYNTAX = 0x1; | ||
| 1594 | const u16 ONES = 0x03; | ||
| 1595 | const u16 ONE = 0x1; | ||
| 1596 | |||
| 1597 | nit = kzalloc(sizeof(*nit), GFP_KERNEL); | ||
| 1598 | if (!nit) | ||
| 1599 | return NULL; | ||
| 1600 | |||
| 1601 | transport = kzalloc(sizeof(*transport), GFP_KERNEL); | ||
| 1602 | if (!transport) | ||
| 1603 | goto free_nit; | ||
| 1604 | |||
| 1605 | nit->header.table_id = 0x40; // ACTUAL_NETWORK | ||
| 1606 | |||
| 1607 | nit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); | ||
| 1608 | |||
| 1609 | nit->header.id = cpu_to_be16(network_id); | ||
| 1610 | nit->header.current_next = ONE; | ||
| 1611 | |||
| 1612 | nit->header.version = 0x1f; | ||
| 1613 | |||
| 1614 | nit->header.one2 = ONES; | ||
| 1615 | nit->header.section_id = 0; | ||
| 1616 | nit->header.last_section = 0; | ||
| 1617 | |||
| 1618 | nit->bitfield = cpu_to_be16(0xf); | ||
| 1619 | nit->bitfield2 = cpu_to_be16(0xf); | ||
| 1620 | |||
| 1621 | nit->descriptor = (struct vidtv_psi_desc *) | ||
| 1622 | vidtv_psi_network_name_desc_init(NULL, network_name); | ||
| 1623 | if (!nit->descriptor) | ||
| 1624 | goto free_transport; | ||
| 1625 | |||
| 1626 | transport->transport_id = cpu_to_be16(transport_stream_id); | ||
| 1627 | transport->network_id = cpu_to_be16(network_id); | ||
| 1628 | transport->bitfield = cpu_to_be16(0xf); | ||
| 1629 | transport->descriptor = (struct vidtv_psi_desc *) | ||
| 1630 | vidtv_psi_service_list_desc_init(NULL, service_list); | ||
| 1631 | if (!transport->descriptor) | ||
| 1632 | goto free_nit_desc; | ||
| 1633 | |||
| 1634 | nit->transport = transport; | ||
| 1635 | |||
| 1636 | vidtv_psi_nit_table_update_sec_len(nit); | ||
| 1637 | |||
| 1638 | return nit; | ||
| 1639 | |||
| 1640 | free_nit_desc: | ||
| 1641 | vidtv_psi_desc_destroy((struct vidtv_psi_desc *)nit->descriptor); | ||
| 1642 | |||
| 1643 | free_transport: | ||
| 1644 | kfree(transport); | ||
| 1645 | free_nit: | ||
| 1646 | kfree(nit); | ||
| 1647 | return NULL; | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args) | ||
| 1651 | { | ||
| 1652 | struct header_write_args h_args = { | ||
| 1653 | .dest_buf = args->buf, | ||
| 1654 | .dest_offset = args->offset, | ||
| 1655 | .h = &args->nit->header, | ||
| 1656 | .pid = VIDTV_NIT_PID, | ||
| 1657 | .dest_buf_sz = args->buf_sz, | ||
| 1658 | }; | ||
| 1659 | struct psi_write_args psi_args = { | ||
| 1660 | .dest_buf = args->buf, | ||
| 1661 | .from = &args->nit->bitfield, | ||
| 1662 | .len = sizeof_field(struct vidtv_psi_table_nit, bitfield), | ||
| 1663 | .pid = VIDTV_NIT_PID, | ||
| 1664 | .new_psi_section = false, | ||
| 1665 | .is_crc = false, | ||
| 1666 | .dest_buf_sz = args->buf_sz, | ||
| 1667 | }; | ||
| 1668 | struct desc_write_args d_args = { | ||
| 1669 | .dest_buf = args->buf, | ||
| 1670 | .pid = VIDTV_NIT_PID, | ||
| 1671 | .dest_buf_sz = args->buf_sz, | ||
| 1672 | }; | ||
| 1673 | struct crc32_write_args c_args = { | ||
| 1674 | .dest_buf = args->buf, | ||
| 1675 | .pid = VIDTV_NIT_PID, | ||
| 1676 | .dest_buf_sz = args->buf_sz, | ||
| 1677 | }; | ||
| 1678 | struct vidtv_psi_desc *table_descriptor = args->nit->descriptor; | ||
| 1679 | struct vidtv_psi_table_transport *transport = args->nit->transport; | ||
| 1680 | struct vidtv_psi_desc *transport_descriptor; | ||
| 1681 | u32 crc = INITIAL_CRC; | ||
| 1682 | u32 nbytes = 0; | ||
| 1683 | |||
| 1684 | vidtv_psi_nit_table_update_sec_len(args->nit); | ||
| 1685 | |||
| 1686 | h_args.continuity_counter = args->continuity_counter; | ||
| 1687 | h_args.crc = &crc; | ||
| 1688 | |||
| 1689 | nbytes += vidtv_psi_table_header_write_into(&h_args); | ||
| 1690 | |||
| 1691 | /* write the bitfield */ | ||
| 1692 | |||
| 1693 | psi_args.dest_offset = args->offset + nbytes; | ||
| 1694 | psi_args.continuity_counter = args->continuity_counter; | ||
| 1695 | psi_args.crc = &crc; | ||
| 1696 | |||
| 1697 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 1698 | |||
| 1699 | while (table_descriptor) { | ||
| 1700 | /* write the descriptors, if any */ | ||
| 1701 | d_args.dest_offset = args->offset + nbytes; | ||
| 1702 | d_args.desc = table_descriptor; | ||
| 1703 | d_args.continuity_counter = args->continuity_counter; | ||
| 1704 | d_args.crc = &crc; | ||
| 1705 | |||
| 1706 | nbytes += vidtv_psi_desc_write_into(&d_args); | ||
| 1707 | |||
| 1708 | table_descriptor = table_descriptor->next; | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | /* write the second bitfield */ | ||
| 1712 | psi_args.from = &args->nit->bitfield2; | ||
| 1713 | psi_args.len = sizeof_field(struct vidtv_psi_table_nit, bitfield2); | ||
| 1714 | psi_args.dest_offset = args->offset + nbytes; | ||
| 1715 | |||
| 1716 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 1717 | |||
| 1718 | psi_args.len = sizeof_field(struct vidtv_psi_table_transport, transport_id) + | ||
| 1719 | sizeof_field(struct vidtv_psi_table_transport, network_id) + | ||
| 1720 | sizeof_field(struct vidtv_psi_table_transport, bitfield); | ||
| 1721 | while (transport) { | ||
| 1722 | /* write the transport sections, if any */ | ||
| 1723 | psi_args.from = transport; | ||
| 1724 | psi_args.dest_offset = args->offset + nbytes; | ||
| 1725 | |||
| 1726 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 1727 | |||
| 1728 | transport_descriptor = transport->descriptor; | ||
| 1729 | |||
| 1730 | while (transport_descriptor) { | ||
| 1731 | /* write the transport descriptors, if any */ | ||
| 1732 | d_args.dest_offset = args->offset + nbytes; | ||
| 1733 | d_args.desc = transport_descriptor; | ||
| 1734 | d_args.continuity_counter = args->continuity_counter; | ||
| 1735 | d_args.crc = &crc; | ||
| 1736 | |||
| 1737 | nbytes += vidtv_psi_desc_write_into(&d_args); | ||
| 1738 | |||
| 1739 | transport_descriptor = transport_descriptor->next; | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | transport = transport->next; | ||
| 1743 | } | ||
| 1744 | |||
| 1745 | c_args.dest_offset = args->offset + nbytes; | ||
| 1746 | c_args.crc = cpu_to_be32(crc); | ||
| 1747 | c_args.continuity_counter = args->continuity_counter; | ||
| 1748 | |||
| 1749 | /* Write the CRC32 at the end */ | ||
| 1750 | nbytes += table_section_crc32_write_into(&c_args); | ||
| 1751 | |||
| 1752 | return nbytes; | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | static void vidtv_psi_transport_destroy(struct vidtv_psi_table_transport *t) | ||
| 1756 | { | ||
| 1757 | struct vidtv_psi_table_transport *tmp_t = NULL; | ||
| 1758 | struct vidtv_psi_table_transport *curr_t = t; | ||
| 1759 | |||
| 1760 | while (curr_t) { | ||
| 1761 | tmp_t = curr_t; | ||
| 1762 | curr_t = curr_t->next; | ||
| 1763 | vidtv_psi_desc_destroy(tmp_t->descriptor); | ||
| 1764 | kfree(tmp_t); | ||
| 1765 | } | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit) | ||
| 1769 | { | ||
| 1770 | vidtv_psi_desc_destroy(nit->descriptor); | ||
| 1771 | vidtv_psi_transport_destroy(nit->transport); | ||
| 1772 | kfree(nit); | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit) | ||
| 1776 | { | ||
| 1777 | struct vidtv_psi_table_eit_event *e = eit->event; | ||
| 1778 | u16 desc_loop_len; | ||
| 1779 | u16 length = 0; | ||
| 1780 | |||
| 1781 | /* | ||
| 1782 | * from immediately after 'section_length' until | ||
| 1783 | * 'last_table_id' | ||
| 1784 | */ | ||
| 1785 | length += EIT_LEN_UNTIL_LAST_TABLE_ID; | ||
| 1786 | |||
| 1787 | while (e) { | ||
| 1788 | /* skip both pointers at the end */ | ||
| 1789 | length += sizeof(struct vidtv_psi_table_eit_event) - | ||
| 1790 | sizeof(struct vidtv_psi_desc *) - | ||
| 1791 | sizeof(struct vidtv_psi_table_eit_event *); | ||
| 1792 | |||
| 1793 | desc_loop_len = vidtv_psi_desc_comp_loop_len(e->descriptor); | ||
| 1794 | vidtv_psi_set_desc_loop_len(&e->bitfield, desc_loop_len, 12); | ||
| 1795 | |||
| 1796 | length += desc_loop_len; | ||
| 1797 | |||
| 1798 | e = e->next; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | length += CRC_SIZE_IN_BYTES; | ||
| 1802 | |||
| 1803 | vidtv_psi_set_sec_len(&eit->header, length); | ||
| 1804 | } | ||
| 1805 | |||
| 1806 | void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, | ||
| 1807 | struct vidtv_psi_table_eit_event *e) | ||
| 1808 | { | ||
| 1809 | do { | ||
| 1810 | if (e == eit->event) | ||
| 1811 | return; | ||
| 1812 | |||
| 1813 | eit->event = e; | ||
| 1814 | vidtv_psi_eit_table_update_sec_len(eit); | ||
| 1815 | |||
| 1816 | e = NULL; | ||
| 1817 | } while (vidtv_psi_get_sec_len(&eit->header) > EIT_MAX_SECTION_LEN); | ||
| 1818 | |||
| 1819 | vidtv_psi_update_version_num(&eit->header); | ||
| 1820 | } | ||
| 1821 | |||
| 1822 | struct vidtv_psi_table_eit | ||
| 1823 | *vidtv_psi_eit_table_init(u16 network_id, | ||
| 1824 | u16 transport_stream_id, | ||
| 1825 | __be16 service_id) | ||
| 1826 | { | ||
| 1827 | struct vidtv_psi_table_eit *eit; | ||
| 1828 | const u16 SYNTAX = 0x1; | ||
| 1829 | const u16 ONE = 0x1; | ||
| 1830 | const u16 ONES = 0x03; | ||
| 1831 | |||
| 1832 | eit = kzalloc(sizeof(*eit), GFP_KERNEL); | ||
| 1833 | if (!eit) | ||
| 1834 | return NULL; | ||
| 1835 | |||
| 1836 | eit->header.table_id = 0x4e; //actual_transport_stream: present/following | ||
| 1837 | |||
| 1838 | eit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12)); | ||
| 1839 | |||
| 1840 | eit->header.id = service_id; | ||
| 1841 | eit->header.current_next = ONE; | ||
| 1842 | |||
| 1843 | eit->header.version = 0x1f; | ||
| 1844 | |||
| 1845 | eit->header.one2 = ONES; | ||
| 1846 | eit->header.section_id = 0; | ||
| 1847 | eit->header.last_section = 0; | ||
| 1848 | |||
| 1849 | eit->transport_id = cpu_to_be16(transport_stream_id); | ||
| 1850 | eit->network_id = cpu_to_be16(network_id); | ||
| 1851 | |||
| 1852 | eit->last_segment = eit->header.last_section; /* not implemented */ | ||
| 1853 | eit->last_table_id = eit->header.table_id; /* not implemented */ | ||
| 1854 | |||
| 1855 | vidtv_psi_eit_table_update_sec_len(eit); | ||
| 1856 | |||
| 1857 | return eit; | ||
| 1858 | } | ||
| 1859 | |||
| 1860 | u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args) | ||
| 1861 | { | ||
| 1862 | struct header_write_args h_args = { | ||
| 1863 | .dest_buf = args->buf, | ||
| 1864 | .dest_offset = args->offset, | ||
| 1865 | .h = &args->eit->header, | ||
| 1866 | .pid = VIDTV_EIT_PID, | ||
| 1867 | .dest_buf_sz = args->buf_sz, | ||
| 1868 | }; | ||
| 1869 | struct psi_write_args psi_args = { | ||
| 1870 | .dest_buf = args->buf, | ||
| 1871 | .len = sizeof_field(struct vidtv_psi_table_eit, transport_id) + | ||
| 1872 | sizeof_field(struct vidtv_psi_table_eit, network_id) + | ||
| 1873 | sizeof_field(struct vidtv_psi_table_eit, last_segment) + | ||
| 1874 | sizeof_field(struct vidtv_psi_table_eit, last_table_id), | ||
| 1875 | .pid = VIDTV_EIT_PID, | ||
| 1876 | .new_psi_section = false, | ||
| 1877 | .is_crc = false, | ||
| 1878 | .dest_buf_sz = args->buf_sz, | ||
| 1879 | }; | ||
| 1880 | struct desc_write_args d_args = { | ||
| 1881 | .dest_buf = args->buf, | ||
| 1882 | .pid = VIDTV_EIT_PID, | ||
| 1883 | .dest_buf_sz = args->buf_sz, | ||
| 1884 | }; | ||
| 1885 | struct crc32_write_args c_args = { | ||
| 1886 | .dest_buf = args->buf, | ||
| 1887 | .pid = VIDTV_EIT_PID, | ||
| 1888 | .dest_buf_sz = args->buf_sz, | ||
| 1889 | }; | ||
| 1890 | struct vidtv_psi_table_eit_event *event = args->eit->event; | ||
| 1891 | struct vidtv_psi_desc *event_descriptor; | ||
| 1892 | u32 crc = INITIAL_CRC; | ||
| 1893 | u32 nbytes = 0; | ||
| 1894 | |||
| 1895 | vidtv_psi_eit_table_update_sec_len(args->eit); | ||
| 1896 | |||
| 1897 | h_args.continuity_counter = args->continuity_counter; | ||
| 1898 | h_args.crc = &crc; | ||
| 1899 | |||
| 1900 | nbytes += vidtv_psi_table_header_write_into(&h_args); | ||
| 1901 | |||
| 1902 | psi_args.from = &args->eit->transport_id; | ||
| 1903 | psi_args.dest_offset = args->offset + nbytes; | ||
| 1904 | psi_args.continuity_counter = args->continuity_counter; | ||
| 1905 | psi_args.crc = &crc; | ||
| 1906 | |||
| 1907 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 1908 | |||
| 1909 | /* skip both pointers at the end */ | ||
| 1910 | psi_args.len = sizeof(struct vidtv_psi_table_eit_event) - | ||
| 1911 | sizeof(struct vidtv_psi_desc *) - | ||
| 1912 | sizeof(struct vidtv_psi_table_eit_event *); | ||
| 1913 | while (event) { | ||
| 1914 | /* copy the events, if any */ | ||
| 1915 | psi_args.from = event; | ||
| 1916 | psi_args.dest_offset = args->offset + nbytes; | ||
| 1917 | |||
| 1918 | nbytes += vidtv_psi_ts_psi_write_into(&psi_args); | ||
| 1919 | |||
| 1920 | event_descriptor = event->descriptor; | ||
| 1921 | |||
| 1922 | while (event_descriptor) { | ||
| 1923 | /* copy the event descriptors, if any */ | ||
| 1924 | d_args.dest_offset = args->offset + nbytes; | ||
| 1925 | d_args.desc = event_descriptor; | ||
| 1926 | d_args.continuity_counter = args->continuity_counter; | ||
| 1927 | d_args.crc = &crc; | ||
| 1928 | |||
| 1929 | nbytes += vidtv_psi_desc_write_into(&d_args); | ||
| 1930 | |||
| 1931 | event_descriptor = event_descriptor->next; | ||
| 1932 | } | ||
| 1933 | |||
| 1934 | event = event->next; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | c_args.dest_offset = args->offset + nbytes; | ||
| 1938 | c_args.crc = cpu_to_be32(crc); | ||
| 1939 | c_args.continuity_counter = args->continuity_counter; | ||
| 1940 | |||
| 1941 | /* Write the CRC at the end */ | ||
| 1942 | nbytes += table_section_crc32_write_into(&c_args); | ||
| 1943 | |||
| 1944 | return nbytes; | ||
| 1945 | } | ||
| 1946 | |||
| 1947 | struct vidtv_psi_table_eit_event | ||
| 1948 | *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id) | ||
| 1949 | { | ||
| 1950 | const u8 DURATION[] = {0x23, 0x59, 0x59}; /* BCD encoded */ | ||
| 1951 | struct vidtv_psi_table_eit_event *e; | ||
| 1952 | struct timespec64 ts; | ||
| 1953 | struct tm time; | ||
| 1954 | int mjd, l; | ||
| 1955 | __be16 mjd_be; | ||
| 1956 | |||
| 1957 | e = kzalloc(sizeof(*e), GFP_KERNEL); | ||
| 1958 | if (!e) | ||
| 1959 | return NULL; | ||
| 1960 | |||
| 1961 | e->event_id = cpu_to_be16(event_id); | ||
| 1962 | |||
| 1963 | ts = ktime_to_timespec64(ktime_get_real()); | ||
| 1964 | time64_to_tm(ts.tv_sec, 0, &time); | ||
| 1965 | |||
| 1966 | /* Convert date to Modified Julian Date - per EN 300 468 Annex C */ | ||
| 1967 | if (time.tm_mon < 2) | ||
| 1968 | l = 1; | ||
| 1969 | else | ||
| 1970 | l = 0; | ||
| 1971 | |||
| 1972 | mjd = 14956 + time.tm_mday; | ||
| 1973 | mjd += (time.tm_year - l) * 36525 / 100; | ||
| 1974 | mjd += (time.tm_mon + 2 + l * 12) * 306001 / 10000; | ||
| 1975 | mjd_be = cpu_to_be16(mjd); | ||
| 1976 | |||
| 1977 | /* | ||
| 1978 | * Store MJD and hour/min/sec to the event. | ||
| 1979 | * | ||
| 1980 | * Let's make the event to start on a full hour | ||
| 1981 | */ | ||
| 1982 | memcpy(e->start_time, &mjd_be, sizeof(mjd_be)); | ||
| 1983 | e->start_time[2] = bin2bcd(time.tm_hour); | ||
| 1984 | e->start_time[3] = 0; | ||
| 1985 | e->start_time[4] = 0; | ||
| 1986 | |||
| 1987 | /* | ||
| 1988 | * TODO: for now, the event will last for a day. Should be | ||
| 1989 | * enough for testing purposes, but if one runs the driver | ||
| 1990 | * for more than that, the current event will become invalid. | ||
| 1991 | * So, we need a better code here in order to change the start | ||
| 1992 | * time once the event expires. | ||
| 1993 | */ | ||
| 1994 | memcpy(e->duration, DURATION, sizeof(e->duration)); | ||
| 1995 | |||
| 1996 | e->bitfield = cpu_to_be16(RUNNING << 13); | ||
| 1997 | |||
| 1998 | if (head) { | ||
| 1999 | while (head->next) | ||
| 2000 | head = head->next; | ||
| 2001 | |||
| 2002 | head->next = e; | ||
| 2003 | } | ||
| 2004 | |||
| 2005 | return e; | ||
| 2006 | } | ||
| 2007 | |||
| 2008 | void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e) | ||
| 2009 | { | ||
| 2010 | struct vidtv_psi_table_eit_event *tmp_e = NULL; | ||
| 2011 | struct vidtv_psi_table_eit_event *curr_e = e; | ||
| 2012 | |||
| 2013 | while (curr_e) { | ||
| 2014 | tmp_e = curr_e; | ||
| 2015 | curr_e = curr_e->next; | ||
| 2016 | vidtv_psi_desc_destroy(tmp_e->descriptor); | ||
| 2017 | kfree(tmp_e); | ||
| 2018 | } | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit) | ||
| 2022 | { | ||
| 2023 | vidtv_psi_eit_event_destroy(eit->event); | ||
| 2024 | kfree(eit); | ||
| 2025 | } | ||
| @@ -6,10 +6,6 @@ · 5 unmodified lines | |||
| 6 | * technically be broken into one or more sections, we do not do this here, | 6 | * technically be broken into one or more sections, we do not do this here, |
| 7 | * hence 'table' and 'section' are interchangeable for vidtv. | 7 | * hence 'table' and 'section' are interchangeable for vidtv. |
| 8 | * | 8 | * |
| 9 | * This code currently supports three tables: PAT, PMT and SDT. These are the | ||
| 10 | * bare minimum to get userspace to recognize our MPEG transport stream. It can | ||
| 11 | * be extended to support more PSI tables in the future. | ||
| 12 | * | ||
| 13 | * Copyright (C) 2020 Daniel W. S. Almeida | 9 | * Copyright (C) 2020 Daniel W. S. Almeida |
| 14 | */ | 10 | */ |
| 15 | 11 | ||
| @@ -17,7 +13,6 @@ · 1 unmodified line | |||
| 17 | #define VIDTV_PSI_H | 13 | #define VIDTV_PSI_H |
| 18 | 14 | ||
| 19 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 20 | #include <asm/byteorder.h> | ||
| 21 | 16 | ||
| 22 | /* | 17 | /* |
| 23 | * all section lengths start immediately after the 'section_length' field | 18 | * all section lengths start immediately after the 'section_length' field |
| @@ -27,20 +22,28 @@ · 3 unmodified lines | |||
| 27 | #define PAT_LEN_UNTIL_LAST_SECTION_NUMBER 5 | 22 | #define PAT_LEN_UNTIL_LAST_SECTION_NUMBER 5 |
| 28 | #define PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH 9 | 23 | #define PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH 9 |
| 29 | #define SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE 8 | 24 | #define SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE 8 |
| 25 | #define NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN 7 | ||
| 26 | #define EIT_LEN_UNTIL_LAST_TABLE_ID 11 | ||
| 30 | #define MAX_SECTION_LEN 1021 | 27 | #define MAX_SECTION_LEN 1021 |
| 28 | #define EIT_MAX_SECTION_LEN 4093 /* see ETSI 300 468 v.1.10.1 p. 26 */ | ||
| 31 | #define VIDTV_PAT_PID 0 /* mandated by the specs */ | 29 | #define VIDTV_PAT_PID 0 /* mandated by the specs */ |
| 32 | #define VIDTV_SDT_PID 0x0011 /* mandated by the specs */ | 30 | #define VIDTV_SDT_PID 0x0011 /* mandated by the specs */ |
| 31 | #define VIDTV_NIT_PID 0x0010 /* mandated by the specs */ | ||
| 32 | #define VIDTV_EIT_PID 0x0012 /*mandated by the specs */ | ||
| 33 | 33 | ||
| 34 | enum vidtv_psi_descriptors { | 34 | enum vidtv_psi_descriptors { |
| 35 | REGISTRATION_DESCRIPTOR = 0x05, /* See ISO/IEC 13818-1 section 2.6.8 */ | 35 | REGISTRATION_DESCRIPTOR = 0x05, /* See ISO/IEC 13818-1 section 2.6.8 */ |
| 36 | NETWORK_NAME_DESCRIPTOR = 0x40, /* See ETSI EN 300 468 section 6.2.27 */ | ||
| 37 | SERVICE_LIST_DESCRIPTOR = 0x41, /* See ETSI EN 300 468 section 6.2.35 */ | ||
| 36 | SERVICE_DESCRIPTOR = 0x48, /* See ETSI EN 300 468 section 6.2.33 */ | 38 | SERVICE_DESCRIPTOR = 0x48, /* See ETSI EN 300 468 section 6.2.33 */ |
| 39 | SHORT_EVENT_DESCRIPTOR = 0x4d, /* See ETSI EN 300 468 section 6.2.37 */ | ||
| 37 | }; | 40 | }; |
| 38 | 41 | ||
| 39 | enum vidtv_psi_stream_types { | 42 | enum vidtv_psi_stream_types { |
| 40 | STREAM_PRIVATE_DATA = 0x06, /* see ISO/IEC 13818-1 2000 p. 48 */ | 43 | STREAM_PRIVATE_DATA = 0x06, /* see ISO/IEC 13818-1 2000 p. 48 */ |
| 41 | }; | 44 | }; |
| 42 | 45 | ||
| 43 | /** | 46 | /* |
| 44 | * struct vidtv_psi_desc - A generic PSI descriptor type. | 47 | * struct vidtv_psi_desc - A generic PSI descriptor type. |
| 45 | * The descriptor length is an 8-bit field specifying the total number of bytes of the data portion | 48 | * The descriptor length is an 8-bit field specifying the total number of bytes of the data portion |
| 46 | * of the descriptor following the byte defining the value of this field. | 49 | * of the descriptor following the byte defining the value of this field. |
| @@ -52,7 +55,7 @@ struct vidtv_psi_desc { · 5 unmodified lines | |||
| 52 | u8 data[]; | 55 | u8 data[]; |
| 53 | } __packed; | 56 | } __packed; |
| 54 | 57 | ||
| 55 | /** | 58 | /* |
| 56 | * struct vidtv_psi_desc_service - Service descriptor. | 59 | * struct vidtv_psi_desc_service - Service descriptor. |
| 57 | * See ETSI EN 300 468 section 6.2.33. | 60 | * See ETSI EN 300 468 section 6.2.33. |
| 58 | */ | 61 | */ |
| @@ -68,7 +71,7 @@ struct vidtv_psi_desc_service { · 9 unmodified lines | |||
| 68 | char *service_name; | 71 | char *service_name; |
| 69 | } __packed; | 72 | } __packed; |
| 70 | 73 | ||
| 71 | /** | 74 | /* |
| 72 | * struct vidtv_psi_desc_registration - A registration descriptor. | 75 | * struct vidtv_psi_desc_registration - A registration descriptor. |
| 73 | * See ISO/IEC 13818-1 section 2.6.8 | 76 | * See ISO/IEC 13818-1 section 2.6.8 |
| 74 | */ | 77 | */ |
| @@ -90,7 +93,56 @@ struct vidtv_psi_desc_registration { · 15 unmodified lines | |||
| 90 | u8 additional_identification_info[]; | 93 | u8 additional_identification_info[]; |
| 91 | } __packed; | 94 | } __packed; |
| 92 | 95 | ||
| 93 | /** | 96 | /* |
| 97 | * struct vidtv_psi_desc_network_name - A network name descriptor | ||
| 98 | * see ETSI EN 300 468 v1.15.1 section 6.2.27 | ||
| 99 | */ | ||
| 100 | struct vidtv_psi_desc_network_name { | ||
| 101 | struct vidtv_psi_desc *next; | ||
| 102 | u8 type; | ||
| 103 | u8 length; | ||
| 104 | char *network_name; | ||
| 105 | } __packed; | ||
| 106 | |||
| 107 | struct vidtv_psi_desc_service_list_entry { | ||
| 108 | __be16 service_id; | ||
| 109 | u8 service_type; | ||
| 110 | struct vidtv_psi_desc_service_list_entry *next; | ||
| 111 | } __packed; | ||
| 112 | |||
| 113 | /* | ||
| 114 | * struct vidtv_psi_desc_service_list - A service list descriptor | ||
| 115 | * see ETSI EN 300 468 v1.15.1 section 6.2.35 | ||
| 116 | */ | ||
| 117 | struct vidtv_psi_desc_service_list { | ||
| 118 | struct vidtv_psi_desc *next; | ||
| 119 | u8 type; | ||
| 120 | u8 length; | ||
| 121 | struct vidtv_psi_desc_service_list_entry *service_list; | ||
| 122 | } __packed; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * struct vidtv_psi_desc_short_event - A short event descriptor | ||
| 126 | * see ETSI EN 300 468 v1.15.1 section 6.2.37 | ||
| 127 | */ | ||
| 128 | struct vidtv_psi_desc_short_event { | ||
| 129 | struct vidtv_psi_desc *next; | ||
| 130 | u8 type; | ||
| 131 | u8 length; | ||
| 132 | char *iso_language_code; | ||
| 133 | u8 event_name_len; | ||
| 134 | char *event_name; | ||
| 135 | u8 text_len; | ||
| 136 | char *text; | ||
| 137 | } __packed; | ||
| 138 | |||
| 139 | struct vidtv_psi_desc_short_event | ||
| 140 | *vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head, | ||
| 141 | char *iso_language_code, | ||
| 142 | char *event_name, | ||
| 143 | char *text); | ||
| 144 | |||
| 145 | /* | ||
| 94 | * struct vidtv_psi_table_header - A header that is present for all PSI tables. | 146 | * struct vidtv_psi_table_header - A header that is present for all PSI tables. |
| 95 | */ | 147 | */ |
| 96 | struct vidtv_psi_table_header { | 148 | struct vidtv_psi_table_header { |
| @@ -106,7 +158,7 @@ struct vidtv_psi_table_header { · 9 unmodified lines | |||
| 106 | u8 last_section; /* last_section_number */ | 158 | u8 last_section; /* last_section_number */ |
| 107 | } __packed; | 159 | } __packed; |
| 108 | 160 | ||
| 109 | /** | 161 | /* |
| 110 | * struct vidtv_psi_table_pat_program - A single program in the PAT | 162 | * struct vidtv_psi_table_pat_program - A single program in the PAT |
| 111 | * See ISO/IEC 13818-1 : 2000 p.43 | 163 | * See ISO/IEC 13818-1 : 2000 p.43 |
| 112 | */ | 164 | */ |
| @@ -116,17 +168,18 @@ struct vidtv_psi_table_pat_program { · 3 unmodified lines | |||
| 116 | struct vidtv_psi_table_pat_program *next; | 168 | struct vidtv_psi_table_pat_program *next; |
| 117 | } __packed; | 169 | } __packed; |
| 118 | 170 | ||
| 119 | /** | 171 | /* |
| 120 | * struct vidtv_psi_table_pat - The Program Allocation Table (PAT) | 172 | * struct vidtv_psi_table_pat - The Program Allocation Table (PAT) |
| 121 | * See ISO/IEC 13818-1 : 2000 p.43 | 173 | * See ISO/IEC 13818-1 : 2000 p.43 |
| 122 | */ | 174 | */ |
| 123 | struct vidtv_psi_table_pat { | 175 | struct vidtv_psi_table_pat { |
| 124 | struct vidtv_psi_table_header header; | 176 | struct vidtv_psi_table_header header; |
| 125 | u16 programs; /* Included by libdvbv5, not part of the table and not actually serialized */ | 177 | u16 num_pat; |
| 178 | u16 num_pmt; | ||
| 126 | struct vidtv_psi_table_pat_program *program; | 179 | struct vidtv_psi_table_pat_program *program; |
| 127 | } __packed; | 180 | } __packed; |
| 128 | 181 | ||
| 129 | /** | 182 | /* |
| 130 | * struct vidtv_psi_table_sdt_service - Represents a service in the SDT. | 183 | * struct vidtv_psi_table_sdt_service - Represents a service in the SDT. |
| 131 | * see ETSI EN 300 468 v1.15.1 section 5.2.3. | 184 | * see ETSI EN 300 468 v1.15.1 section 5.2.3. |
| 132 | */ | 185 | */ |
| @@ -140,7 +193,7 @@ struct vidtv_psi_table_sdt_service { · 7 unmodified lines | |||
| 140 | struct vidtv_psi_table_sdt_service *next; | 193 | struct vidtv_psi_table_sdt_service *next; |
| 141 | } __packed; | 194 | } __packed; |
| 142 | 195 | ||
| 143 | /** | 196 | /* |
| 144 | * struct vidtv_psi_table_sdt - Represents the Service Description Table | 197 | * struct vidtv_psi_table_sdt - Represents the Service Description Table |
| 145 | * see ETSI EN 300 468 v1.15.1 section 5.2.3. | 198 | * see ETSI EN 300 468 v1.15.1 section 5.2.3. |
| 146 | */ | 199 | */ |
| @@ -152,7 +205,7 @@ struct vidtv_psi_table_sdt { · 5 unmodified lines | |||
| 152 | struct vidtv_psi_table_sdt_service *service; | 205 | struct vidtv_psi_table_sdt_service *service; |
| 153 | } __packed; | 206 | } __packed; |
| 154 | 207 | ||
| 155 | /** | 208 | /* |
| 156 | * enum service_running_status - Status of a SDT service. | 209 | * enum service_running_status - Status of a SDT service. |
| 157 | * see ETSI EN 300 468 v1.15.1 section 5.2.3 table 6. | 210 | * see ETSI EN 300 468 v1.15.1 section 5.2.3 table 6. |
| 158 | */ | 211 | */ |
| @@ -160,16 +213,17 @@ enum service_running_status { · 1 unmodified line | |||
| 160 | RUNNING = 0x4, | 213 | RUNNING = 0x4, |
| 161 | }; | 214 | }; |
| 162 | 215 | ||
| 163 | /** | 216 | /* |
| 164 | * enum service_type - The type of a SDT service. | 217 | * enum service_type - The type of a SDT service. |
| 165 | * see ETSI EN 300 468 v1.15.1 section 6.2.33, table 81. | 218 | * see ETSI EN 300 468 v1.15.1 section 6.2.33, table 81. |
| 166 | */ | 219 | */ |
| 167 | enum service_type { | 220 | enum service_type { |
| 168 | /* see ETSI EN 300 468 v1.15.1 p. 77 */ | 221 | /* see ETSI EN 300 468 v1.15.1 p. 77 */ |
| 169 | DIGITAL_TELEVISION_SERVICE = 0x1, | 222 | DIGITAL_TELEVISION_SERVICE = 0x1, |
| 223 | DIGITAL_RADIO_SOUND_SERVICE = 0X2, | ||
| 170 | }; | 224 | }; |
| 171 | 225 | ||
| 172 | /** | 226 | /* |
| 173 | * struct vidtv_psi_table_pmt_stream - A single stream in the PMT. | 227 | * struct vidtv_psi_table_pmt_stream - A single stream in the PMT. |
| 174 | * See ISO/IEC 13818-1 : 2000 p.46. | 228 | * See ISO/IEC 13818-1 : 2000 p.46. |
| 175 | */ | 229 | */ |
| @@ -181,7 +235,7 @@ struct vidtv_psi_table_pmt_stream { · 5 unmodified lines | |||
| 181 | struct vidtv_psi_table_pmt_stream *next; | 235 | struct vidtv_psi_table_pmt_stream *next; |
| 182 | } __packed; | 236 | } __packed; |
| 183 | 237 | ||
| 184 | /** | 238 | /* |
| 185 | * struct vidtv_psi_table_pmt - The Program Map Table (PMT). | 239 | * struct vidtv_psi_table_pmt - The Program Map Table (PMT). |
| 186 | * See ISO/IEC 13818-1 : 2000 p.46. | 240 | * See ISO/IEC 13818-1 : 2000 p.46. |
| 187 | */ | 241 | */ |
| @@ -290,6 +344,13 @@ struct vidtv_psi_desc_registration · 102 unmodified lines | |||
| 290 | u8 *additional_ident_info, | 344 | u8 *additional_ident_info, |
| 291 | u32 additional_info_len); | 345 | u32 additional_info_len); |
| 292 | 346 | ||
| 347 | struct vidtv_psi_desc_network_name | ||
| 348 | *vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name); | ||
| 349 | |||
| 350 | struct vidtv_psi_desc_service_list | ||
| 351 | *vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head, | ||
| 352 | struct vidtv_psi_desc_service_list_entry *entry); | ||
| 353 | |||
| 293 | struct vidtv_psi_table_pat_program | 354 | struct vidtv_psi_table_pat_program |
| 294 | *vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, | 355 | *vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, |
| 295 | u16 service_id, | 356 | u16 service_id, |
| @@ -305,11 +366,14 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id); · 9 unmodified lines | |||
| 305 | struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, | 366 | struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, |
| 306 | u16 pcr_pid); | 367 | u16 pcr_pid); |
| 307 | 368 | ||
| 308 | struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 transport_stream_id); | 369 | struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, |
| 370 | u16 transport_stream_id); | ||
| 309 | 371 | ||
| 310 | struct vidtv_psi_table_sdt_service* | 372 | struct vidtv_psi_table_sdt_service* |
| 311 | vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, | 373 | vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, |
| 312 | u16 service_id); | 374 | u16 service_id, |
| 375 | bool eit_schedule, | ||
| 376 | bool eit_present_following); | ||
| 313 | 377 | ||
| 314 | void | 378 | void |
| 315 | vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc); | 379 | vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc); |
| @@ -413,7 +477,6 @@ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc); · 97 unmodified lines | |||
| 413 | * vidtv_psi_create_sec_for_each_pat_entry - Create a PMT section for each | 477 | * vidtv_psi_create_sec_for_each_pat_entry - Create a PMT section for each |
| 414 | * program found in the PAT | 478 | * program found in the PAT |
| 415 | * @pat: The PAT to look for programs. | 479 | * @pat: The PAT to look for programs. |
| 416 | * @s: The stream loop (one or more streams) | ||
| 417 | * @pcr_pid: packet ID for the PCR to be used for the program described in this | 480 | * @pcr_pid: packet ID for the PCR to be used for the program described in this |
| 418 | * PMT section | 481 | * PMT section |
| 419 | */ | 482 | */ |
| @@ -492,7 +555,7 @@ struct vidtv_psi_pat_write_args { · 72 unmodified lines | |||
| 492 | * equal to the size of the PAT, since more space is needed for TS headers during TS | 555 | * equal to the size of the PAT, since more space is needed for TS headers during TS |
| 493 | * encapsulation. | 556 | * encapsulation. |
| 494 | */ | 557 | */ |
| 495 | u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args args); | 558 | u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args); |
| 496 | 559 | ||
| 497 | /** | 560 | /** |
| 498 | * struct vidtv_psi_sdt_write_args - Arguments for writing a SDT table | 561 | * struct vidtv_psi_sdt_write_args - Arguments for writing a SDT table |
| @@ -524,16 +587,18 @@ struct vidtv_psi_sdt_write_args { · 25 unmodified lines | |||
| 524 | * equal to the size of the SDT, since more space is needed for TS headers during TS | 587 | * equal to the size of the SDT, since more space is needed for TS headers during TS |
| 525 | * encapsulation. | 588 | * encapsulation. |
| 526 | */ | 589 | */ |
| 527 | u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args args); | 590 | u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args); |
| 528 | 591 | ||
| 529 | /** | 592 | /** |
| 530 | * struct vidtv_psi_pmt_write_args - Arguments for writing a PMT section | 593 | * struct vidtv_psi_pmt_write_args - Arguments for writing a PMT section |
| 531 | * @buf: The destination buffer. | 594 | * @buf: The destination buffer. |
| 532 | * @offset: The offset into the destination buffer. | 595 | * @offset: The offset into the destination buffer. |
| 533 | * @pmt: A pointer to the PMT. | 596 | * @pmt: A pointer to the PMT. |
| 597 | * @pid: Program ID | ||
| 534 | * @buf_sz: The size of the destination buffer. | 598 | * @buf_sz: The size of the destination buffer. |
| 535 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. | 599 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. |
| 536 | * | 600 | * @pcr_pid: The TS PID used for the PSI packets. All channels will share the |
| 601 | * same PCR. | ||
| 537 | */ | 602 | */ |
| 538 | struct vidtv_psi_pmt_write_args { | 603 | struct vidtv_psi_pmt_write_args { |
| 539 | char *buf; | 604 | char *buf; |
| @@ -557,7 +622,7 @@ struct vidtv_psi_pmt_write_args { · 17 unmodified lines | |||
| 557 | * equal to the size of the PMT section, since more space is needed for TS headers | 622 | * equal to the size of the PMT section, since more space is needed for TS headers |
| 558 | * during TS encapsulation. | 623 | * during TS encapsulation. |
| 559 | */ | 624 | */ |
| 560 | u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args args); | 625 | u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args); |
| 561 | 626 | ||
| 562 | /** | 627 | /** |
| 563 | * vidtv_psi_find_pmt_sec - Finds the PMT section for 'program_num' | 628 | * vidtv_psi_find_pmt_sec - Finds the PMT section for 'program_num' |
| @@ -574,4 +639,171 @@ struct vidtv_psi_table_pmt *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt ** · 10 unmodified lines | |||
| 574 | u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p); | 639 | u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p); |
| 575 | u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s); | 640 | u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s); |
| 576 | 641 | ||
| 642 | /** | ||
| 643 | * struct vidtv_psi_table_transport - A entry in the TS loop for the NIT and/or other tables. | ||
| 644 | * See ETSI 300 468 section 5.2.1 | ||
| 645 | * @transport_id: The TS ID being described | ||
| 646 | * @network_id: The network_id that contains the TS ID | ||
| 647 | * @bitfield: Contains the descriptor loop length | ||
| 648 | * @descriptor: A descriptor loop | ||
| 649 | * @next: Pointer to the next entry | ||
| 650 | * | ||
| 651 | */ | ||
| 652 | struct vidtv_psi_table_transport { | ||
| 653 | __be16 transport_id; | ||
| 654 | __be16 network_id; | ||
| 655 | __be16 bitfield; /* desc_len: 12, reserved: 4 */ | ||
| 656 | struct vidtv_psi_desc *descriptor; | ||
| 657 | struct vidtv_psi_table_transport *next; | ||
| 658 | } __packed; | ||
| 659 | |||
| 660 | /** | ||
| 661 | * struct vidtv_psi_table_nit - A Network Information Table (NIT). See ETSI 300 | ||
| 662 | * 468 section 5.2.1 | ||
| 663 | * @header: A PSI table header | ||
| 664 | * @bitfield: Contains the network descriptor length | ||
| 665 | * @descriptor: A descriptor loop describing the network | ||
| 666 | * @bitfield2: Contains the transport stream loop length | ||
| 667 | * @transport: The transport stream loop | ||
| 668 | * | ||
| 669 | */ | ||
| 670 | struct vidtv_psi_table_nit { | ||
| 671 | struct vidtv_psi_table_header header; | ||
| 672 | __be16 bitfield; /* network_desc_len: 12, reserved:4 */ | ||
| 673 | struct vidtv_psi_desc *descriptor; | ||
| 674 | __be16 bitfield2; /* ts_loop_len: 12, reserved: 4 */ | ||
| 675 | struct vidtv_psi_table_transport *transport; | ||
| 676 | } __packed; | ||
| 677 | |||
| 678 | struct vidtv_psi_table_nit | ||
| 679 | *vidtv_psi_nit_table_init(u16 network_id, | ||
| 680 | u16 transport_stream_id, | ||
| 681 | char *network_name, | ||
| 682 | struct vidtv_psi_desc_service_list_entry *service_list); | ||
| 683 | |||
| 684 | /** | ||
| 685 | * struct vidtv_psi_nit_write_args - Arguments for writing a NIT section | ||
| 686 | * @buf: The destination buffer. | ||
| 687 | * @offset: The offset into the destination buffer. | ||
| 688 | * @nit: A pointer to the NIT | ||
| 689 | * @buf_sz: The size of the destination buffer. | ||
| 690 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. | ||
| 691 | * | ||
| 692 | */ | ||
| 693 | struct vidtv_psi_nit_write_args { | ||
| 694 | char *buf; | ||
| 695 | u32 offset; | ||
| 696 | struct vidtv_psi_table_nit *nit; | ||
| 697 | u32 buf_sz; | ||
| 698 | u8 *continuity_counter; | ||
| 699 | }; | ||
| 700 | |||
| 701 | /** | ||
| 702 | * vidtv_psi_nit_write_into - Write NIT as MPEG-TS packets into a buffer. | ||
| 703 | * @args: an instance of struct vidtv_psi_nit_write_args | ||
| 704 | * | ||
| 705 | * This function writes the MPEG TS packets for a NIT table into a buffer. | ||
| 706 | * Calling code will usually generate the NIT via a call to its init function | ||
| 707 | * and thus is responsible for freeing it. | ||
| 708 | * | ||
| 709 | * Return: The number of bytes written into the buffer. This is NOT | ||
| 710 | * equal to the size of the NIT, since more space is needed for TS headers during TS | ||
| 711 | * encapsulation. | ||
| 712 | */ | ||
| 713 | u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args); | ||
| 714 | |||
| 715 | void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit); | ||
| 716 | |||
| 717 | /* | ||
| 718 | * struct vidtv_psi_desc_short_event - A short event descriptor | ||
| 719 | * see ETSI EN 300 468 v1.15.1 section 6.2.37 | ||
| 720 | */ | ||
| 721 | struct vidtv_psi_table_eit_event { | ||
| 722 | __be16 event_id; | ||
| 723 | u8 start_time[5]; | ||
| 724 | u8 duration[3]; | ||
| 725 | __be16 bitfield; /* desc_length: 12, free_CA_mode: 1, running_status: 1 */ | ||
| 726 | struct vidtv_psi_desc *descriptor; | ||
| 727 | struct vidtv_psi_table_eit_event *next; | ||
| 728 | } __packed; | ||
| 729 | |||
| 730 | /* | ||
| 731 | * struct vidtv_psi_table_eit - A Event Information Table (EIT) | ||
| 732 | * See ETSI 300 468 section 5.2.4 | ||
| 733 | */ | ||
| 734 | struct vidtv_psi_table_eit { | ||
| 735 | struct vidtv_psi_table_header header; | ||
| 736 | __be16 transport_id; | ||
| 737 | __be16 network_id; | ||
| 738 | u8 last_segment; | ||
| 739 | u8 last_table_id; | ||
| 740 | struct vidtv_psi_table_eit_event *event; | ||
| 741 | } __packed; | ||
| 742 | |||
| 743 | struct vidtv_psi_table_eit | ||
| 744 | *vidtv_psi_eit_table_init(u16 network_id, | ||
| 745 | u16 transport_stream_id, | ||
| 746 | u16 service_id); | ||
| 747 | |||
| 748 | /** | ||
| 749 | * struct vidtv_psi_eit_write_args - Arguments for writing an EIT section | ||
| 750 | * @buf: The destination buffer. | ||
| 751 | * @offset: The offset into the destination buffer. | ||
| 752 | * @eit: A pointer to the EIT | ||
| 753 | * @buf_sz: The size of the destination buffer. | ||
| 754 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. | ||
| 755 | * | ||
| 756 | */ | ||
| 757 | struct vidtv_psi_eit_write_args { | ||
| 758 | char *buf; | ||
| 759 | u32 offset; | ||
| 760 | struct vidtv_psi_table_eit *eit; | ||
| 761 | u32 buf_sz; | ||
| 762 | u8 *continuity_counter; | ||
| 763 | }; | ||
| 764 | |||
| 765 | /** | ||
| 766 | * vidtv_psi_eit_write_into - Write EIT as MPEG-TS packets into a buffer. | ||
| 767 | * @args: an instance of struct vidtv_psi_nit_write_args | ||
| 768 | * | ||
| 769 | * This function writes the MPEG TS packets for a EIT table into a buffer. | ||
| 770 | * Calling code will usually generate the EIT via a call to its init function | ||
| 771 | * and thus is responsible for freeing it. | ||
| 772 | * | ||
| 773 | * Return: The number of bytes written into the buffer. This is NOT | ||
| 774 | * equal to the size of the EIT, since more space is needed for TS headers during TS | ||
| 775 | * encapsulation. | ||
| 776 | */ | ||
| 777 | u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args); | ||
| 778 | |||
| 779 | void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit); | ||
| 780 | |||
| 781 | /** | ||
| 782 | * vidtv_psi_eit_table_update_sec_len - Recompute and update the EIT section length. | ||
| 783 | * @eit: The EIT whose length is to be updated. | ||
| 784 | * | ||
| 785 | * This will traverse the table and accumulate the length of its components, | ||
| 786 | * which is then used to replace the 'section_length' field. | ||
| 787 | * | ||
| 788 | * If section_length > EIT_MAX_SECTION_LEN, the operation fails. | ||
| 789 | */ | ||
| 790 | void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit); | ||
| 791 | |||
| 792 | /** | ||
| 793 | * vidtv_psi_eit_event_assign - Assigns the event loop to the EIT. | ||
| 794 | * @eit: The EIT to assign to. | ||
| 795 | * @e: The event loop | ||
| 796 | * | ||
| 797 | * This will free the previous event loop in the table. | ||
| 798 | * This will assign ownership of the stream loop to the table, i.e. the table | ||
| 799 | * will free this stream loop when a call to its destroy function is made. | ||
| 800 | */ | ||
| 801 | void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, | ||
| 802 | struct vidtv_psi_table_eit_event *e); | ||
| 803 | |||
| 804 | struct vidtv_psi_table_eit_event | ||
| 805 | *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id); | ||
| 806 | |||
| 807 | void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e); | ||
| 808 | |||
| 577 | #endif // VIDTV_PSI_H | 809 | #endif // VIDTV_PSI_H |
| @@ -17,23 +17,22 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ | 18 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ |
| 19 | 19 | ||
| 20 | #include <linux/types.h> | 20 | #include <linux/bug.h> |
| 21 | #include <linux/slab.h> | ||
| 22 | #include <linux/crc32.h> | 21 | #include <linux/crc32.h> |
| 23 | #include <linux/vmalloc.h> | 22 | #include <linux/fixp-arith.h> |
| 24 | #include <linux/string.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/math64.h> | ||
| 27 | #include <linux/printk.h> | 26 | #include <linux/printk.h> |
| 28 | #include <linux/ratelimit.h> | 27 | #include <linux/ratelimit.h> |
| 29 | #include <linux/fixp-arith.h> | 28 | #include <linux/slab.h> |
| 30 | 29 | #include <linux/string.h> | |
| 31 | #include <linux/math64.h> | 30 | #include <linux/types.h> |
| 32 | #include <asm/byteorder.h> | 31 | #include <linux/vmalloc.h> |
| 33 | 32 | ||
| 34 | #include "vidtv_s302m.h" | ||
| 35 | #include "vidtv_encoder.h" | ||
| 36 | #include "vidtv_common.h" | 33 | #include "vidtv_common.h" |
| 34 | #include "vidtv_encoder.h" | ||
| 35 | #include "vidtv_s302m.h" | ||
| 37 | 36 | ||
| 38 | #define S302M_SAMPLING_RATE_HZ 48000 | 37 | #define S302M_SAMPLING_RATE_HZ 48000 |
| 39 | #define PES_PRIVATE_STREAM_1 0xbd /* PES: private_stream_1 */ | 38 | #define PES_PRIVATE_STREAM_1 0xbd /* PES: private_stream_1 */ |
| @@ -79,8 +78,9 @@ struct tone_duration { · 39 unmodified lines | |||
| 79 | int duration; | 78 | int duration; |
| 80 | }; | 79 | }; |
| 81 | 80 | ||
| 82 | #define COMPASS 120 /* beats per minute (Allegro) */ | 81 | #define COMPASS 100 /* beats per minute */ |
| 83 | static const struct tone_duration beethoven_5th_symphony[] = { | 82 | static const struct tone_duration beethoven_fur_elise[] = { |
| 83 | { NOTE_SILENT, 512}, | ||
| 84 | { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, | 84 | { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, |
| 85 | { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, | 85 | { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, |
| 86 | { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, | 86 | { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, |
| @@ -121,31 +121,36 @@ static const struct tone_duration beethoven_5th_symphony[] = { · 34 unmodified lines | |||
| 121 | { NOTE_E_5, 128}, { NOTE_D_5, 128}, { NOTE_A_3, 128}, | 121 | { NOTE_E_5, 128}, { NOTE_D_5, 128}, { NOTE_A_3, 128}, |
| 122 | { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_4, 128}, | 122 | { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_4, 128}, |
| 123 | { NOTE_D_5, 128}, { NOTE_C_5, 128}, { NOTE_E_3, 128}, | 123 | { NOTE_D_5, 128}, { NOTE_C_5, 128}, { NOTE_E_3, 128}, |
| 124 | { NOTE_E_4, 128}, { NOTE_E_5, 255}, { NOTE_E_6, 128}, | 124 | { NOTE_E_4, 128}, { NOTE_E_5, 128}, { NOTE_E_5, 128}, |
| 125 | { NOTE_E_5, 128}, { NOTE_E_6, 128}, { NOTE_E_5, 255}, | 125 | { NOTE_E_6, 128}, { NOTE_E_5, 128}, { NOTE_E_6, 128}, |
| 126 | { NOTE_E_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_5, 128}, | ||
| 127 | { NOTE_E_5, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, | ||
| 126 | { NOTE_DS_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_6, 128}, | 128 | { NOTE_DS_5, 128}, { NOTE_E_5, 128}, { NOTE_DS_6, 128}, |
| 127 | { NOTE_E_6, 128}, { NOTE_DS_5, 128}, { NOTE_E_5, 128}, | ||
| 128 | { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, | ||
| 129 | { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, | 129 | { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, |
| 130 | { NOTE_B_5, 128}, { NOTE_D_6, 128}, { NOTE_C_6, 128}, | 130 | { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, |
| 131 | { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, | 131 | { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, |
| 132 | { NOTE_C_5, 128}, { NOTE_E_5, 128}, { NOTE_A_5, 128}, | 132 | { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128}, |
| 133 | { NOTE_E_3, 128}, { NOTE_E_4, 128}, { NOTE_GS_4, 128}, | 133 | { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128}, |
| 134 | { NOTE_E_5, 128}, { NOTE_GS_5, 128}, { NOTE_B_5, 128}, | 134 | { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128}, |
| 135 | { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, | 135 | { NOTE_GS_5, 128}, { NOTE_B_5, 128}, { NOTE_A_3, 128}, |
| 136 | { NOTE_E_5, 128}, { NOTE_E_6, 128}, { NOTE_DS_6, 128}, | 136 | { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_E_5, 128}, |
| 137 | { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, | 137 | { NOTE_E_6, 128}, { NOTE_DS_6, 128}, { NOTE_E_6, 128}, |
| 138 | { NOTE_B_5, 128}, { NOTE_D_6, 128}, { NOTE_C_6, 128}, | 138 | { NOTE_DS_6, 128}, { NOTE_E_6, 128}, { NOTE_B_5, 128}, |
| 139 | { NOTE_A_3, 128}, { NOTE_E_4, 128}, { NOTE_A_4, 128}, | 139 | { NOTE_D_6, 128}, { NOTE_C_6, 128}, { NOTE_A_3, 128}, |
| 140 | { NOTE_C_5, 128}, { NOTE_E_5, 128}, { NOTE_A_5, 128}, | 140 | { NOTE_E_4, 128}, { NOTE_A_4, 128}, { NOTE_C_5, 128}, |
| 141 | { NOTE_E_3, 128}, { NOTE_E_4, 128}, { NOTE_GS_4, 128}, | 141 | { NOTE_E_5, 128}, { NOTE_A_5, 128}, { NOTE_E_3, 128}, |
| 142 | { NOTE_E_5, 128}, { NOTE_C_6, 128}, { NOTE_B_5, 128}, | 142 | { NOTE_E_4, 128}, { NOTE_GS_4, 128}, { NOTE_E_5, 128}, |
| 143 | { NOTE_C_5, 255}, { NOTE_C_5, 255}, { NOTE_SILENT, 512}, | 143 | { NOTE_C_6, 128}, { NOTE_B_5, 128}, { NOTE_A_5, 512}, |
| 144 | { NOTE_SILENT, 256}, | ||
| 144 | }; | 145 | }; |
| 145 | 146 | ||
| 146 | static struct vidtv_access_unit *vidtv_s302m_access_unit_init(struct vidtv_access_unit *head) | 147 | static struct vidtv_access_unit *vidtv_s302m_access_unit_init(struct vidtv_access_unit *head) |
| 147 | { | 148 | { |
| 148 | struct vidtv_access_unit *au = kzalloc(sizeof(*au), GFP_KERNEL); | 149 | struct vidtv_access_unit *au; |
| 150 | |||
| 151 | au = kzalloc(sizeof(*au), GFP_KERNEL); | ||
| 152 | if (!au) | ||
| 153 | return NULL; | ||
| 149 | 154 | ||
| 150 | if (head) { | 155 | if (head) { |
| 151 | while (head->next) | 156 | while (head->next) |
| @@ -196,10 +201,10 @@ static void vidtv_s302m_alloc_au(struct vidtv_encoder *e) · 44 unmodified lines | |||
| 196 | static void | 201 | static void |
| 197 | vidtv_s302m_compute_sample_count_from_video(struct vidtv_encoder *e) | 202 | vidtv_s302m_compute_sample_count_from_video(struct vidtv_encoder *e) |
| 198 | { | 203 | { |
| 199 | struct vidtv_access_unit *au = e->access_units; | ||
| 200 | struct vidtv_access_unit *sync_au = e->sync->access_units; | 204 | struct vidtv_access_unit *sync_au = e->sync->access_units; |
| 201 | u32 vau_duration_usecs; | 205 | struct vidtv_access_unit *au = e->access_units; |
| 202 | u32 sample_duration_usecs; | 206 | u32 sample_duration_usecs; |
| 207 | u32 vau_duration_usecs; | ||
| 203 | u32 s; | 208 | u32 s; |
| 204 | 209 | ||
| 205 | vau_duration_usecs = USEC_PER_SEC / e->sync->sampling_rate_hz; | 210 | vau_duration_usecs = USEC_PER_SEC / e->sync->sampling_rate_hz; |
| @@ -230,36 +235,32 @@ static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e) · 24 unmodified lines | |||
| 230 | { | 235 | { |
| 231 | u16 sample; | 236 | u16 sample; |
| 232 | int pos; | 237 | int pos; |
| 238 | struct vidtv_s302m_ctx *ctx = e->ctx; | ||
| 233 | 239 | ||
| 234 | if (!e->src_buf) { | 240 | if (!e->src_buf) { |
| 235 | /* | 241 | /* |
| 236 | * Simple tone generator: play the tones at the | 242 | * Simple tone generator: play the tones at the |
| 237 | * beethoven_5th_symphony array. | 243 | * beethoven_fur_elise array. |
| 238 | */ | 244 | */ |
| 239 | if (e->last_duration <= 0) { | 245 | if (ctx->last_duration <= 0) { |
| 240 | if (e->src_buf_offset >= ARRAY_SIZE(beethoven_5th_symphony)) | 246 | if (e->src_buf_offset >= ARRAY_SIZE(beethoven_fur_elise)) |
| 241 | e->src_buf_offset = 0; | 247 | e->src_buf_offset = 0; |
| 242 | 248 | ||
| 243 | e->last_tone = beethoven_5th_symphony[e->src_buf_offset].note; | 249 | ctx->last_tone = beethoven_fur_elise[e->src_buf_offset].note; |
| 244 | e->last_duration = beethoven_5th_symphony[e->src_buf_offset].duration * S302M_SAMPLING_RATE_HZ / COMPASS / 5; | 250 | ctx->last_duration = beethoven_fur_elise[e->src_buf_offset].duration * |
| 251 | S302M_SAMPLING_RATE_HZ / COMPASS / 5; | ||
| 245 | e->src_buf_offset++; | 252 | e->src_buf_offset++; |
| 246 | e->note_offset = 0; | 253 | ctx->note_offset = 0; |
| 247 | } else { | 254 | } else { |
| 248 | e->last_duration--; | 255 | ctx->last_duration--; |
| 249 | } | 256 | } |
| 250 | 257 | ||
| 251 | /* Handle silent */ | 258 | /* Handle pause notes */ |
| 252 | if (!e->last_tone) { | 259 | if (!ctx->last_tone) |
| 253 | e->src_buf_offset = 0; | ||
| 254 | return 0x8000; | 260 | return 0x8000; |
| 255 | } | ||
| 256 | 261 | ||
| 257 | pos = (2 * PI * e->note_offset * e->last_tone / S302M_SAMPLING_RATE_HZ); | 262 | pos = (2 * PI * ctx->note_offset * ctx->last_tone) / S302M_SAMPLING_RATE_HZ; |
| 258 | 263 | ctx->note_offset++; | |
| 259 | if (pos == 360) | ||
| 260 | e->note_offset = 0; | ||
| 261 | else | ||
| 262 | e->note_offset++; | ||
| 263 | 264 | ||
| 264 | return (fixp_sin32(pos % (2 * PI)) >> 16) + 0x8000; | 265 | return (fixp_sin32(pos % (2 * PI)) >> 16) + 0x8000; |
| 265 | } | 266 | } |
| @@ -289,9 +290,9 @@ static u16 vidtv_s302m_get_sample(struct vidtv_encoder *e) · 23 unmodified lines | |||
| 289 | static u32 vidtv_s302m_write_frame(struct vidtv_encoder *e, | 290 | static u32 vidtv_s302m_write_frame(struct vidtv_encoder *e, |
| 290 | u16 sample) | 291 | u16 sample) |
| 291 | { | 292 | { |
| 292 | u32 nbytes = 0; | ||
| 293 | struct vidtv_s302m_frame_16 f = {}; | ||
| 294 | struct vidtv_s302m_ctx *ctx = e->ctx; | 293 | struct vidtv_s302m_ctx *ctx = e->ctx; |
| 294 | struct vidtv_s302m_frame_16 f = {}; | ||
| 295 | u32 nbytes = 0; | ||
| 295 | 296 | ||
| 296 | /* from ffmpeg: see s302enc.c */ | 297 | /* from ffmpeg: see s302enc.c */ |
| 297 | 298 | ||
| @@ -388,6 +389,8 @@ static void vidtv_s302m_write_frames(struct vidtv_encoder *e) · 90 unmodified lines | |||
| 388 | 389 | ||
| 389 | static void *vidtv_s302m_encode(struct vidtv_encoder *e) | 390 | static void *vidtv_s302m_encode(struct vidtv_encoder *e) |
| 390 | { | 391 | { |
| 392 | struct vidtv_s302m_ctx *ctx = e->ctx; | ||
| 393 | |||
| 391 | /* | 394 | /* |
| 392 | * According to SMPTE 302M, an audio access unit is specified as those | 395 | * According to SMPTE 302M, an audio access unit is specified as those |
| 393 | * AES3 words that are associated with a corresponding video frame. | 396 | * AES3 words that are associated with a corresponding video frame. |
| @@ -401,8 +404,6 @@ static void *vidtv_s302m_encode(struct vidtv_encoder *e) · 7 unmodified lines | |||
| 401 | * ffmpeg | 404 | * ffmpeg |
| 402 | */ | 405 | */ |
| 403 | 406 | ||
| 404 | struct vidtv_s302m_ctx *ctx = e->ctx; | ||
| 405 | |||
| 406 | vidtv_s302m_access_unit_destroy(e); | 407 | vidtv_s302m_access_unit_destroy(e); |
| 407 | vidtv_s302m_alloc_au(e); | 408 | vidtv_s302m_alloc_au(e); |
| 408 | 409 | ||
| @@ -440,8 +441,13 @@ static u32 vidtv_s302m_clear(struct vidtv_encoder *e) · 31 unmodified lines | |||
| 440 | struct vidtv_encoder | 441 | struct vidtv_encoder |
| 441 | *vidtv_s302m_encoder_init(struct vidtv_s302m_encoder_init_args args) | 442 | *vidtv_s302m_encoder_init(struct vidtv_s302m_encoder_init_args args) |
| 442 | { | 443 | { |
| 443 | struct vidtv_encoder *e = kzalloc(sizeof(*e), GFP_KERNEL); | ||
| 444 | u32 priv_sz = sizeof(struct vidtv_s302m_ctx); | 444 | u32 priv_sz = sizeof(struct vidtv_s302m_ctx); |
| 445 | struct vidtv_s302m_ctx *ctx; | ||
| 446 | struct vidtv_encoder *e; | ||
| 447 | |||
| 448 | e = kzalloc(sizeof(*e), GFP_KERNEL); | ||
| 449 | if (!e) | ||
| 450 | return NULL; | ||
| 445 | 451 | ||
| 446 | e->id = S302M; | 452 | e->id = S302M; |
| 447 | 453 | ||
| @@ -453,14 +459,19 @@ struct vidtv_encoder · 5 unmodified lines | |||
| 453 | e->encoder_buf_offset = 0; | 459 | e->encoder_buf_offset = 0; |
| 454 | 460 | ||
| 455 | e->sample_count = 0; | 461 | e->sample_count = 0; |
| 456 | e->last_duration = 0; | ||
| 457 | 462 | ||
| 458 | e->src_buf = (args.src_buf) ? args.src_buf : NULL; | 463 | e->src_buf = (args.src_buf) ? args.src_buf : NULL; |
| 459 | e->src_buf_sz = (args.src_buf) ? args.src_buf_sz : 0; | 464 | e->src_buf_sz = (args.src_buf) ? args.src_buf_sz : 0; |
| 460 | e->src_buf_offset = 0; | 465 | e->src_buf_offset = 0; |
| 461 | 466 | ||
| 462 | e->is_video_encoder = false; | 467 | e->is_video_encoder = false; |
| 463 | e->ctx = kzalloc(priv_sz, GFP_KERNEL); | 468 | |
| 469 | ctx = kzalloc(priv_sz, GFP_KERNEL); | ||
| 470 | if (!ctx) | ||
| 471 | return NULL; | ||
| 472 | |||
| 473 | e->ctx = ctx; | ||
| 474 | ctx->last_duration = 0; | ||
| 464 | 475 | ||
| 465 | e->encode = vidtv_s302m_encode; | 476 | e->encode = vidtv_s302m_encode; |
| 466 | e->clear = vidtv_s302m_clear; | 477 | e->clear = vidtv_s302m_clear; |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | |||
| 19 | #define VIDTV_S302M_H | 19 | #define VIDTV_S302M_H |
| 20 | 20 | ||
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| 22 | #include <asm/byteorder.h> | ||
| 23 | 22 | ||
| 24 | #include "vidtv_encoder.h" | 23 | #include "vidtv_encoder.h" |
| 25 | 24 | ||
| @@ -34,14 +33,20 @@ · 8 unmodified lines | |||
| 34 | * @enc: A pointer to the containing encoder structure. | 33 | * @enc: A pointer to the containing encoder structure. |
| 35 | * @frame_index: The current frame in a block | 34 | * @frame_index: The current frame in a block |
| 36 | * @au_count: The total number of access units encoded up to now | 35 | * @au_count: The total number of access units encoded up to now |
| 36 | * @last_duration: Duration of the tone currently being played | ||
| 37 | * @note_offset: Position at the music tone array | ||
| 38 | * @last_tone: Tone currently being played | ||
| 37 | */ | 39 | */ |
| 38 | struct vidtv_s302m_ctx { | 40 | struct vidtv_s302m_ctx { |
| 39 | struct vidtv_encoder *enc; | 41 | struct vidtv_encoder *enc; |
| 40 | u32 frame_index; | 42 | u32 frame_index; |
| 41 | u32 au_count; | 43 | u32 au_count; |
| 44 | int last_duration; | ||
| 45 | unsigned int note_offset; | ||
| 46 | enum musical_notes last_tone; | ||
| 42 | }; | 47 | }; |
| 43 | 48 | ||
| 44 | /** | 49 | /* |
| 45 | * struct vidtv_smpte_s302m_es - s302m MPEG Elementary Stream header. | 50 | * struct vidtv_smpte_s302m_es - s302m MPEG Elementary Stream header. |
| 46 | * | 51 | * |
| 47 | * See SMPTE 302M 2007 table 1. | 52 | * See SMPTE 302M 2007 table 1. |
| @@ -9,14 +9,13 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ | 10 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__ |
| 11 | 11 | ||
| 12 | #include <linux/math64.h> | ||
| 12 | #include <linux/printk.h> | 13 | #include <linux/printk.h> |
| 13 | #include <linux/ratelimit.h> | 14 | #include <linux/ratelimit.h> |
| 14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 15 | #include <linux/math64.h> | ||
| 16 | #include <asm/byteorder.h> | ||
| 17 | 16 | ||
| 18 | #include "vidtv_ts.h" | ||
| 19 | #include "vidtv_common.h" | 17 | #include "vidtv_common.h" |
| 18 | #include "vidtv_ts.h" | ||
| 20 | 19 | ||
| 21 | static u32 vidtv_ts_write_pcr_bits(u8 *to, u32 to_offset, u64 pcr) | 20 | static u32 vidtv_ts_write_pcr_bits(u8 *to, u32 to_offset, u64 pcr) |
| 22 | { | 21 | { |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | |||
| 11 | #define VIDTV_TS_H | 11 | #define VIDTV_TS_H |
| 12 | 12 | ||
| 13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 14 | #include <asm/byteorder.h> | ||
| 15 | 14 | ||
| 16 | #define TS_SYNC_BYTE 0x47 | 15 | #define TS_SYNC_BYTE 0x47 |
| 17 | #define TS_PACKET_LEN 188 | 16 | #define TS_PACKET_LEN 188 |
| @@ -54,7 +53,7 @@ struct vidtv_mpeg_ts { · 36 unmodified lines | |||
| 54 | * @dest_offset: The byte offset into the buffer. | 53 | * @dest_offset: The byte offset into the buffer. |
| 55 | * @pid: The TS PID for the PCR packets. | 54 | * @pid: The TS PID for the PCR packets. |
| 56 | * @buf_sz: The size of the buffer in bytes. | 55 | * @buf_sz: The size of the buffer in bytes. |
| 57 | * @countinuity_counter: The TS continuity_counter. | 56 | * @continuity_counter: The TS continuity_counter. |
| 58 | * @pcr: A sample from the system clock. | 57 | * @pcr: A sample from the system clock. |
| 59 | */ | 58 | */ |
| 60 | struct pcr_write_args { | 59 | struct pcr_write_args { |
| @@ -71,7 +70,7 @@ struct pcr_write_args { · 10 unmodified lines | |||
| 71 | * @dest_buf: The buffer to write into. | 70 | * @dest_buf: The buffer to write into. |
| 72 | * @dest_offset: The byte offset into the buffer. | 71 | * @dest_offset: The byte offset into the buffer. |
| 73 | * @buf_sz: The size of the buffer in bytes. | 72 | * @buf_sz: The size of the buffer in bytes. |
| 74 | * @countinuity_counter: The TS continuity_counter. | 73 | * @continuity_counter: The TS continuity_counter. |
| 75 | */ | 74 | */ |
| 76 | struct null_packet_write_args { | 75 | struct null_packet_write_args { |
| 77 | void *dest_buf; | 76 | void *dest_buf; |
| @@ -13,11 +13,12 @@ · 12 unmodified lines | |||
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/printk.h> | ||
| 17 | #include <linux/ratelimit.h> | ||
| 16 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 17 | #include <linux/types.h> | 19 | #include <linux/types.h> |
| 20 | |||
| 18 | #include <media/dvb_frontend.h> | 21 | #include <media/dvb_frontend.h> |
| 19 | #include <linux/printk.h> | ||
| 20 | #include <linux/ratelimit.h> | ||
| 21 | 22 | ||
| 22 | #include "vidtv_tuner.h" | 23 | #include "vidtv_tuner.h" |
| 23 | 24 | ||
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #define VIDTV_TUNER_H | 11 | #define VIDTV_TUNER_H |
| 12 | 12 | ||
| 13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 14 | |||
| 14 | #include <media/dvb_frontend.h> | 15 | #include <media/dvb_frontend.h> |
| 15 | 16 | ||
| 16 | #define NUM_VALID_TUNER_FREQS 8 | 17 | #define NUM_VALID_TUNER_FREQS 8 |
| @@ -30,7 +30,10 @@ · 29 unmodified lines | |||
| 30 | #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 | 30 | #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 |
| 31 | 31 | ||
| 32 | #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 | 32 | #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 |
| 33 | #define SDHCI_ARASAN_ITAPDLY_SEL_MASK 0xFF | ||
| 34 | |||
| 33 | #define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC | 35 | #define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC |
| 36 | #define SDHCI_ARASAN_OTAPDLY_SEL_MASK 0x3F | ||
| 34 | 37 | ||
| 35 | #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 | 38 | #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 |
| 36 | #define VENDOR_ENHANCED_STROBE BIT(0) | 39 | #define VENDOR_ENHANCED_STROBE BIT(0) |
| @@ -600,14 +603,8 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) · 563 unmodified lines | |||
| 600 | u8 tap_delay, tap_max = 0; | 603 | u8 tap_delay, tap_max = 0; |
| 601 | int ret; | 604 | int ret; |
| 602 | 605 | ||
| 603 | /* | 606 | /* This is applicable for SDHCI_SPEC_300 and above */ |
| 604 | * This is applicable for SDHCI_SPEC_300 and above | 607 | if (host->version < SDHCI_SPEC_300) |
| 605 | * ZynqMP does not set phase for <=25MHz clock. | ||
| 606 | * If degrees is zero, no need to do anything. | ||
| 607 | */ | ||
| 608 | if (host->version < SDHCI_SPEC_300 || | ||
| 609 | host->timing == MMC_TIMING_LEGACY || | ||
| 610 | host->timing == MMC_TIMING_UHS_SDR12 || !degrees) | ||
| 611 | return 0; | 608 | return 0; |
| 612 | 609 | ||
| 613 | switch (host->timing) { | 610 | switch (host->timing) { |
| @@ -638,6 +635,9 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) · 24 unmodified lines | |||
| 638 | if (ret) | 635 | if (ret) |
| 639 | pr_err("Error setting Output Tap Delay\n"); | 636 | pr_err("Error setting Output Tap Delay\n"); |
| 640 | 637 | ||
| 638 | /* Release DLL Reset */ | ||
| 639 | zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_RELEASE); | ||
| 640 | |||
| 641 | return ret; | 641 | return ret; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| @@ -668,16 +668,13 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) · 24 unmodified lines | |||
| 668 | u8 tap_delay, tap_max = 0; | 668 | u8 tap_delay, tap_max = 0; |
| 669 | int ret; | 669 | int ret; |
| 670 | 670 | ||
| 671 | /* | 671 | /* This is applicable for SDHCI_SPEC_300 and above */ |
| 672 | * This is applicable for SDHCI_SPEC_300 and above | 672 | if (host->version < SDHCI_SPEC_300) |
| 673 | * ZynqMP does not set phase for <=25MHz clock. | ||
| 674 | * If degrees is zero, no need to do anything. | ||
| 675 | */ | ||
| 676 | if (host->version < SDHCI_SPEC_300 || | ||
| 677 | host->timing == MMC_TIMING_LEGACY || | ||
| 678 | host->timing == MMC_TIMING_UHS_SDR12 || !degrees) | ||
| 679 | return 0; | 673 | return 0; |
| 680 | 674 | ||
| 675 | /* Assert DLL Reset */ | ||
| 676 | zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_ASSERT); | ||
| 677 | |||
| 681 | switch (host->timing) { | 678 | switch (host->timing) { |
| 682 | case MMC_TIMING_MMC_HS: | 679 | case MMC_TIMING_MMC_HS: |
| 683 | case MMC_TIMING_SD_HS: | 680 | case MMC_TIMING_SD_HS: |
| @@ -733,14 +730,8 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) · 49 unmodified lines | |||
| 733 | struct sdhci_host *host = sdhci_arasan->host; | 730 | struct sdhci_host *host = sdhci_arasan->host; |
| 734 | u8 tap_delay, tap_max = 0; | 731 | u8 tap_delay, tap_max = 0; |
| 735 | 732 | ||
| 736 | /* | 733 | /* This is applicable for SDHCI_SPEC_300 and above */ |
| 737 | * This is applicable for SDHCI_SPEC_300 and above | 734 | if (host->version < SDHCI_SPEC_300) |
| 738 | * Versal does not set phase for <=25MHz clock. | ||
| 739 | * If degrees is zero, no need to do anything. | ||
| 740 | */ | ||
| 741 | if (host->version < SDHCI_SPEC_300 || | ||
| 742 | host->timing == MMC_TIMING_LEGACY || | ||
| 743 | host->timing == MMC_TIMING_UHS_SDR12 || !degrees) | ||
| 744 | return 0; | 735 | return 0; |
| 745 | 736 | ||
| 746 | switch (host->timing) { | 737 | switch (host->timing) { |
| @@ -773,6 +764,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) · 26 unmodified lines | |||
| 773 | regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); | 764 | regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); |
| 774 | regval |= SDHCI_OTAPDLY_ENABLE; | 765 | regval |= SDHCI_OTAPDLY_ENABLE; |
| 775 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); | 766 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); |
| 767 | regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK; | ||
| 776 | regval |= tap_delay; | 768 | regval |= tap_delay; |
| 777 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); | 769 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); |
| 778 | } | 770 | } |
| @@ -804,14 +796,8 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) · 25 unmodified lines | |||
| 804 | struct sdhci_host *host = sdhci_arasan->host; | 796 | struct sdhci_host *host = sdhci_arasan->host; |
| 805 | u8 tap_delay, tap_max = 0; | 797 | u8 tap_delay, tap_max = 0; |
| 806 | 798 | ||
| 807 | /* | 799 | /* This is applicable for SDHCI_SPEC_300 and above */ |
| 808 | * This is applicable for SDHCI_SPEC_300 and above | 800 | if (host->version < SDHCI_SPEC_300) |
| 809 | * Versal does not set phase for <=25MHz clock. | ||
| 810 | * If degrees is zero, no need to do anything. | ||
| 811 | */ | ||
| 812 | if (host->version < SDHCI_SPEC_300 || | ||
| 813 | host->timing == MMC_TIMING_LEGACY || | ||
| 814 | host->timing == MMC_TIMING_UHS_SDR12 || !degrees) | ||
| 815 | return 0; | 801 | return 0; |
| 816 | 802 | ||
| 817 | switch (host->timing) { | 803 | switch (host->timing) { |
| @@ -846,6 +832,7 @@ static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) · 28 unmodified lines | |||
| 846 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | 832 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); |
| 847 | regval |= SDHCI_ITAPDLY_ENABLE; | 833 | regval |= SDHCI_ITAPDLY_ENABLE; |
| 848 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | 834 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); |
| 835 | regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK; | ||
| 849 | regval |= tap_delay; | 836 | regval |= tap_delay; |
| 850 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | 837 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); |
| 851 | regval &= ~SDHCI_ITAPDLY_CHGWIN; | 838 | regval &= ~SDHCI_ITAPDLY_CHGWIN; |
| @@ -665,6 +665,15 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, · 664 unmodified lines | |||
| 665 | } | 665 | } |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | static void sdhci_intel_set_uhs_signaling(struct sdhci_host *host, | ||
| 669 | unsigned int timing) | ||
| 670 | { | ||
| 671 | /* Set UHS timing to SDR25 for High Speed mode */ | ||
| 672 | if (timing == MMC_TIMING_MMC_HS || timing == MMC_TIMING_SD_HS) | ||
| 673 | timing = MMC_TIMING_UHS_SDR25; | ||
| 674 | sdhci_set_uhs_signaling(host, timing); | ||
| 675 | } | ||
| 676 | |||
| 668 | #define INTEL_HS400_ES_REG 0x78 | 677 | #define INTEL_HS400_ES_REG 0x78 |
| 669 | #define INTEL_HS400_ES_BIT BIT(0) | 678 | #define INTEL_HS400_ES_BIT BIT(0) |
| 670 | 679 | ||
| @@ -721,7 +730,7 @@ static const struct sdhci_ops sdhci_intel_byt_ops = { · 50 unmodified lines | |||
| 721 | .enable_dma = sdhci_pci_enable_dma, | 730 | .enable_dma = sdhci_pci_enable_dma, |
| 722 | .set_bus_width = sdhci_set_bus_width, | 731 | .set_bus_width = sdhci_set_bus_width, |
| 723 | .reset = sdhci_reset, | 732 | .reset = sdhci_reset, |
| 724 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 733 | .set_uhs_signaling = sdhci_intel_set_uhs_signaling, |
| 725 | .hw_reset = sdhci_pci_hw_reset, | 734 | .hw_reset = sdhci_pci_hw_reset, |
| 726 | }; | 735 | }; |
| 727 | 736 | ||
| @@ -731,7 +740,7 @@ static const struct sdhci_ops sdhci_intel_glk_ops = { · 3 unmodified lines | |||
| 731 | .enable_dma = sdhci_pci_enable_dma, | 740 | .enable_dma = sdhci_pci_enable_dma, |
| 732 | .set_bus_width = sdhci_set_bus_width, | 741 | .set_bus_width = sdhci_set_bus_width, |
| 733 | .reset = sdhci_cqhci_reset, | 742 | .reset = sdhci_cqhci_reset, |
| 734 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 743 | .set_uhs_signaling = sdhci_intel_set_uhs_signaling, |
| 735 | .hw_reset = sdhci_pci_hw_reset, | 744 | .hw_reset = sdhci_pci_hw_reset, |
| 736 | .irq = sdhci_cqhci_irq, | 745 | .irq = sdhci_cqhci_irq, |
| 737 | }; | 746 | }; |
| @@ -215,8 +215,17 @@ static int gpio_nand_setup_interface(struct nand_chip *this, int csline, · 214 unmodified lines | |||
| 215 | return 0; | 215 | return 0; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | static int gpio_nand_attach_chip(struct nand_chip *chip) | ||
| 219 | { | ||
| 220 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 221 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 222 | |||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 218 | static const struct nand_controller_ops gpio_nand_ops = { | 226 | static const struct nand_controller_ops gpio_nand_ops = { |
| 219 | .exec_op = gpio_nand_exec_op, | 227 | .exec_op = gpio_nand_exec_op, |
| 228 | .attach_chip = gpio_nand_attach_chip, | ||
| 220 | .setup_interface = gpio_nand_setup_interface, | 229 | .setup_interface = gpio_nand_setup_interface, |
| 221 | }; | 230 | }; |
| 222 | 231 | ||
| @@ -260,9 +269,6 @@ static int gpio_nand_probe(struct platform_device *pdev) · 37 unmodified lines | |||
| 260 | return err; | 269 | return err; |
| 261 | } | 270 | } |
| 262 | 271 | ||
| 263 | this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 264 | this->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 265 | |||
| 266 | platform_set_drvdata(pdev, priv); | 272 | platform_set_drvdata(pdev, priv); |
| 267 | 273 | ||
| 268 | /* Set chip enabled but write protected */ | 274 | /* Set chip enabled but write protected */ |
| @@ -236,8 +236,17 @@ static int au1550nd_exec_op(struct nand_chip *this, · 235 unmodified lines | |||
| 236 | return ret; | 236 | return ret; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | static int au1550nd_attach_chip(struct nand_chip *chip) | ||
| 240 | { | ||
| 241 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 242 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 243 | |||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 239 | static const struct nand_controller_ops au1550nd_ops = { | 247 | static const struct nand_controller_ops au1550nd_ops = { |
| 240 | .exec_op = au1550nd_exec_op, | 248 | .exec_op = au1550nd_exec_op, |
| 249 | .attach_chip = au1550nd_attach_chip, | ||
| 241 | }; | 250 | }; |
| 242 | 251 | ||
| 243 | static int au1550nd_probe(struct platform_device *pdev) | 252 | static int au1550nd_probe(struct platform_device *pdev) |
| @@ -294,8 +303,6 @@ static int au1550nd_probe(struct platform_device *pdev) · 50 unmodified lines | |||
| 294 | nand_controller_init(&ctx->controller); | 303 | nand_controller_init(&ctx->controller); |
| 295 | ctx->controller.ops = &au1550nd_ops; | 304 | ctx->controller.ops = &au1550nd_ops; |
| 296 | this->controller = &ctx->controller; | 305 | this->controller = &ctx->controller; |
| 297 | this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 298 | this->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 299 | 306 | ||
| 300 | if (pd->devwidth) | 307 | if (pd->devwidth) |
| 301 | this->options |= NAND_BUSWIDTH_16; | 308 | this->options |= NAND_BUSWIDTH_16; |
| @@ -243,8 +243,24 @@ static int cs_calculate_ecc(struct nand_chip *this, const u_char *dat, · 242 unmodified lines | |||
| 243 | 243 | ||
| 244 | static struct cs553x_nand_controller *controllers[4]; | 244 | static struct cs553x_nand_controller *controllers[4]; |
| 245 | 245 | ||
| 246 | static int cs553x_attach_chip(struct nand_chip *chip) | ||
| 247 | { | ||
| 248 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 249 | return 0; | ||
| 250 | |||
| 251 | chip->ecc.size = 256; | ||
| 252 | chip->ecc.bytes = 3; | ||
| 253 | chip->ecc.hwctl = cs_enable_hwecc; | ||
| 254 | chip->ecc.calculate = cs_calculate_ecc; | ||
| 255 | chip->ecc.correct = nand_correct_data; | ||
| 256 | chip->ecc.strength = 1; | ||
| 257 | |||
| 258 | return 0; | ||
| 259 | } | ||
| 260 | |||
| 246 | static const struct nand_controller_ops cs553x_nand_controller_ops = { | 261 | static const struct nand_controller_ops cs553x_nand_controller_ops = { |
| 247 | .exec_op = cs553x_exec_op, | 262 | .exec_op = cs553x_exec_op, |
| 263 | .attach_chip = cs553x_attach_chip, | ||
| 248 | }; | 264 | }; |
| 249 | 265 | ||
| 250 | static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | 266 | static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) |
| @@ -286,14 +302,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) · 35 unmodified lines | |||
| 286 | goto out_mtd; | 302 | goto out_mtd; |
| 287 | } | 303 | } |
| 288 | 304 | ||
| 289 | this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 290 | this->ecc.size = 256; | ||
| 291 | this->ecc.bytes = 3; | ||
| 292 | this->ecc.hwctl = cs_enable_hwecc; | ||
| 293 | this->ecc.calculate = cs_calculate_ecc; | ||
| 294 | this->ecc.correct = nand_correct_data; | ||
| 295 | this->ecc.strength = 1; | ||
| 296 | |||
| 297 | /* Enable the following for a flash based bad block table */ | 305 | /* Enable the following for a flash based bad block table */ |
| 298 | this->bbt_options = NAND_BBT_USE_FLASH; | 306 | this->bbt_options = NAND_BBT_USE_FLASH; |
| 299 | 307 | ||
| @@ -585,6 +585,10 @@ static int davinci_nand_attach_chip(struct nand_chip *chip) · 584 unmodified lines | |||
| 585 | if (IS_ERR(pdata)) | 585 | if (IS_ERR(pdata)) |
| 586 | return PTR_ERR(pdata); | 586 | return PTR_ERR(pdata); |
| 587 | 587 | ||
| 588 | /* Use board-specific ECC config */ | ||
| 589 | info->chip.ecc.engine_type = pdata->engine_type; | ||
| 590 | info->chip.ecc.placement = pdata->ecc_placement; | ||
| 591 | |||
| 588 | switch (info->chip.ecc.engine_type) { | 592 | switch (info->chip.ecc.engine_type) { |
| 589 | case NAND_ECC_ENGINE_TYPE_NONE: | 593 | case NAND_ECC_ENGINE_TYPE_NONE: |
| 590 | pdata->ecc_bits = 0; | 594 | pdata->ecc_bits = 0; |
| @@ -850,10 +854,6 @@ static int nand_davinci_probe(struct platform_device *pdev) · 259 unmodified lines | |||
| 850 | info->mask_ale = pdata->mask_ale ? : MASK_ALE; | 854 | info->mask_ale = pdata->mask_ale ? : MASK_ALE; |
| 851 | info->mask_cle = pdata->mask_cle ? : MASK_CLE; | 855 | info->mask_cle = pdata->mask_cle ? : MASK_CLE; |
| 852 | 856 | ||
| 853 | /* Use board-specific ECC config */ | ||
| 854 | info->chip.ecc.engine_type = pdata->engine_type; | ||
| 855 | info->chip.ecc.placement = pdata->ecc_placement; | ||
| 856 | |||
| 857 | spin_lock_irq(&davinci_nand_lock); | 857 | spin_lock_irq(&davinci_nand_lock); |
| 858 | 858 | ||
| 859 | /* put CSxNAND into NAND mode */ | 859 | /* put CSxNAND into NAND mode */ |
| @@ -1269,12 +1269,31 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd) · 1268 unmodified lines | |||
| 1269 | return 1; | 1269 | return 1; |
| 1270 | } | 1270 | } |
| 1271 | 1271 | ||
| 1272 | static int doc200x_attach_chip(struct nand_chip *chip) | ||
| 1273 | { | ||
| 1274 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 1275 | return 0; | ||
| 1276 | |||
| 1277 | chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED; | ||
| 1278 | chip->ecc.size = 512; | ||
| 1279 | chip->ecc.bytes = 6; | ||
| 1280 | chip->ecc.strength = 2; | ||
| 1281 | chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; | ||
| 1282 | chip->ecc.hwctl = doc200x_enable_hwecc; | ||
| 1283 | chip->ecc.calculate = doc200x_calculate_ecc; | ||
| 1284 | chip->ecc.correct = doc200x_correct_data; | ||
| 1285 | |||
| 1286 | return 0; | ||
| 1287 | } | ||
| 1288 | |||
| 1272 | static const struct nand_controller_ops doc200x_ops = { | 1289 | static const struct nand_controller_ops doc200x_ops = { |
| 1273 | .exec_op = doc200x_exec_op, | 1290 | .exec_op = doc200x_exec_op, |
| 1291 | .attach_chip = doc200x_attach_chip, | ||
| 1274 | }; | 1292 | }; |
| 1275 | 1293 | ||
| 1276 | static const struct nand_controller_ops doc2001plus_ops = { | 1294 | static const struct nand_controller_ops doc2001plus_ops = { |
| 1277 | .exec_op = doc2001plus_exec_op, | 1295 | .exec_op = doc2001plus_exec_op, |
| 1296 | .attach_chip = doc200x_attach_chip, | ||
| 1278 | }; | 1297 | }; |
| 1279 | 1298 | ||
| 1280 | static int __init doc_probe(unsigned long physadr) | 1299 | static int __init doc_probe(unsigned long physadr) |
| @@ -1452,16 +1471,6 @@ static int __init doc_probe(unsigned long physadr) · 171 unmodified lines | |||
| 1452 | 1471 | ||
| 1453 | nand->controller = &doc->base; | 1472 | nand->controller = &doc->base; |
| 1454 | nand_set_controller_data(nand, doc); | 1473 | nand_set_controller_data(nand, doc); |
| 1455 | nand->ecc.hwctl = doc200x_enable_hwecc; | ||
| 1456 | nand->ecc.calculate = doc200x_calculate_ecc; | ||
| 1457 | nand->ecc.correct = doc200x_correct_data; | ||
| 1458 | |||
| 1459 | nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 1460 | nand->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED; | ||
| 1461 | nand->ecc.size = 512; | ||
| 1462 | nand->ecc.bytes = 6; | ||
| 1463 | nand->ecc.strength = 2; | ||
| 1464 | nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; | ||
| 1465 | nand->bbt_options = NAND_BBT_USE_FLASH; | 1474 | nand->bbt_options = NAND_BBT_USE_FLASH; |
| 1466 | /* Skip the automatic BBT scan so we can run it manually */ | 1475 | /* Skip the automatic BBT scan so we can run it manually */ |
| 1467 | nand->options |= NAND_SKIP_BBTSCAN | NAND_NO_BBM_QUIRK; | 1476 | nand->options |= NAND_SKIP_BBTSCAN | NAND_NO_BBM_QUIRK; |
| @@ -880,6 +880,20 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand) · 879 unmodified lines | |||
| 880 | struct mtd_info *mtd = nand_to_mtd(nand); | 880 | struct mtd_info *mtd = nand_to_mtd(nand); |
| 881 | struct fsmc_nand_data *host = nand_to_fsmc(nand); | 881 | struct fsmc_nand_data *host = nand_to_fsmc(nand); |
| 882 | 882 | ||
| 883 | if (nand->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) | ||
| 884 | nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 885 | |||
| 886 | if (!nand->ecc.size) | ||
| 887 | nand->ecc.size = 512; | ||
| 888 | |||
| 889 | if (AMBA_REV_BITS(host->pid) >= 8) { | ||
| 890 | nand->ecc.read_page = fsmc_read_page_hwecc; | ||
| 891 | nand->ecc.calculate = fsmc_read_hwecc_ecc4; | ||
| 892 | nand->ecc.correct = fsmc_bch8_correct_data; | ||
| 893 | nand->ecc.bytes = 13; | ||
| 894 | nand->ecc.strength = 8; | ||
| 895 | } | ||
| 896 | |||
| 883 | if (AMBA_REV_BITS(host->pid) >= 8) { | 897 | if (AMBA_REV_BITS(host->pid) >= 8) { |
| 884 | switch (mtd->oobsize) { | 898 | switch (mtd->oobsize) { |
| 885 | case 16: | 899 | case 16: |
| @@ -905,6 +919,7 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand) · 19 unmodified lines | |||
| 905 | dev_info(host->dev, "Using 1-bit HW ECC scheme\n"); | 919 | dev_info(host->dev, "Using 1-bit HW ECC scheme\n"); |
| 906 | nand->ecc.calculate = fsmc_read_hwecc_ecc1; | 920 | nand->ecc.calculate = fsmc_read_hwecc_ecc1; |
| 907 | nand->ecc.correct = nand_correct_data; | 921 | nand->ecc.correct = nand_correct_data; |
| 922 | nand->ecc.hwctl = fsmc_enable_hwecc; | ||
| 908 | nand->ecc.bytes = 3; | 923 | nand->ecc.bytes = 3; |
| 909 | nand->ecc.strength = 1; | 924 | nand->ecc.strength = 1; |
| 910 | nand->ecc.options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; | 925 | nand->ecc.options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; |
| @@ -1055,13 +1070,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) · 144 unmodified lines | |||
| 1055 | 1070 | ||
| 1056 | mtd->dev.parent = &pdev->dev; | 1071 | mtd->dev.parent = &pdev->dev; |
| 1057 | 1072 | ||
| 1058 | /* | ||
| 1059 | * Setup default ECC mode. nand_dt_init() called from nand_scan_ident() | ||
| 1060 | * can overwrite this value if the DT provides a different value. | ||
| 1061 | */ | ||
| 1062 | nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 1063 | nand->ecc.hwctl = fsmc_enable_hwecc; | ||
| 1064 | nand->ecc.size = 512; | ||
| 1065 | nand->badblockbits = 7; | 1073 | nand->badblockbits = 7; |
| 1066 | 1074 | ||
| 1067 | if (host->mode == USE_DMA_ACCESS) { | 1075 | if (host->mode == USE_DMA_ACCESS) { |
| @@ -1084,14 +1092,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 1084 | nand->options |= NAND_KEEP_TIMINGS; | 1092 | nand->options |= NAND_KEEP_TIMINGS; |
| 1085 | } | 1093 | } |
| 1086 | 1094 | ||
| 1087 | if (AMBA_REV_BITS(host->pid) >= 8) { | ||
| 1088 | nand->ecc.read_page = fsmc_read_page_hwecc; | ||
| 1089 | nand->ecc.calculate = fsmc_read_hwecc_ecc4; | ||
| 1090 | nand->ecc.correct = fsmc_bch8_correct_data; | ||
| 1091 | nand->ecc.bytes = 13; | ||
| 1092 | nand->ecc.strength = 8; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | nand_controller_init(&host->base); | 1095 | nand_controller_init(&host->base); |
| 1096 | host->base.ops = &fsmc_nand_controller_ops; | 1096 | host->base.ops = &fsmc_nand_controller_ops; |
| 1097 | nand->controller = &host->base; | 1097 | nand->controller = &host->base; |
| @@ -161,8 +161,17 @@ static int gpio_nand_exec_op(struct nand_chip *chip, · 160 unmodified lines | |||
| 161 | return ret; | 161 | return ret; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static int gpio_nand_attach_chip(struct nand_chip *chip) | ||
| 165 | { | ||
| 166 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 167 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 168 | |||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 164 | static const struct nand_controller_ops gpio_nand_ops = { | 172 | static const struct nand_controller_ops gpio_nand_ops = { |
| 165 | .exec_op = gpio_nand_exec_op, | 173 | .exec_op = gpio_nand_exec_op, |
| 174 | .attach_chip = gpio_nand_attach_chip, | ||
| 166 | }; | 175 | }; |
| 167 | 176 | ||
| 168 | #ifdef CONFIG_OF | 177 | #ifdef CONFIG_OF |
| @@ -342,8 +351,6 @@ static int gpio_nand_probe(struct platform_device *pdev) · 173 unmodified lines | |||
| 342 | gpiomtd->base.ops = &gpio_nand_ops; | 351 | gpiomtd->base.ops = &gpio_nand_ops; |
| 343 | 352 | ||
| 344 | nand_set_flash_node(chip, pdev->dev.of_node); | 353 | nand_set_flash_node(chip, pdev->dev.of_node); |
| 345 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 346 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 347 | chip->options = gpiomtd->plat.options; | 354 | chip->options = gpiomtd->plat.options; |
| 348 | chip->controller = &gpiomtd->base; | 355 | chip->controller = &gpiomtd->base; |
| 349 | 356 | ||
| @@ -648,6 +648,9 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip) · 647 unmodified lines | |||
| 648 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); | 648 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
| 649 | struct device *dev = &host->pdev->dev; | 649 | struct device *dev = &host->pdev->dev; |
| 650 | 650 | ||
| 651 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 652 | return 0; | ||
| 653 | |||
| 651 | host->dma_buf = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL); | 654 | host->dma_buf = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL); |
| 652 | if (!host->dma_buf) | 655 | if (!host->dma_buf) |
| 653 | return -ENOMEM; | 656 | return -ENOMEM; |
| @@ -656,8 +659,17 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip) · 2 unmodified lines | |||
| 656 | if (!host->dummy_buf) | 659 | if (!host->dummy_buf) |
| 657 | return -ENOMEM; | 660 | return -ENOMEM; |
| 658 | 661 | ||
| 659 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 660 | chip->ecc.size = 512; | 662 | chip->ecc.size = 512; |
| 663 | chip->ecc.hwctl = lpc32xx_ecc_enable; | ||
| 664 | chip->ecc.read_page_raw = lpc32xx_read_page; | ||
| 665 | chip->ecc.read_page = lpc32xx_read_page; | ||
| 666 | chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel; | ||
| 667 | chip->ecc.write_page = lpc32xx_write_page_lowlevel; | ||
| 668 | chip->ecc.write_oob = lpc32xx_write_oob; | ||
| 669 | chip->ecc.read_oob = lpc32xx_read_oob; | ||
| 670 | chip->ecc.strength = 4; | ||
| 671 | chip->ecc.bytes = 10; | ||
| 672 | |||
| 661 | mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops); | 673 | mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops); |
| 662 | host->mlcsubpages = mtd->writesize / 512; | 674 | host->mlcsubpages = mtd->writesize / 512; |
| 663 | 675 | ||
| @@ -741,15 +753,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) · 77 unmodified lines | |||
| 741 | platform_set_drvdata(pdev, host); | 753 | platform_set_drvdata(pdev, host); |
| 742 | 754 | ||
| 743 | /* Initialize function pointers */ | 755 | /* Initialize function pointers */ |
| 744 | nand_chip->ecc.hwctl = lpc32xx_ecc_enable; | ||
| 745 | nand_chip->ecc.read_page_raw = lpc32xx_read_page; | ||
| 746 | nand_chip->ecc.read_page = lpc32xx_read_page; | ||
| 747 | nand_chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel; | ||
| 748 | nand_chip->ecc.write_page = lpc32xx_write_page_lowlevel; | ||
| 749 | nand_chip->ecc.write_oob = lpc32xx_write_oob; | ||
| 750 | nand_chip->ecc.read_oob = lpc32xx_read_oob; | ||
| 751 | nand_chip->ecc.strength = 4; | ||
| 752 | nand_chip->ecc.bytes = 10; | ||
| 753 | nand_chip->legacy.waitfunc = lpc32xx_waitfunc; | 756 | nand_chip->legacy.waitfunc = lpc32xx_waitfunc; |
| 754 | 757 | ||
| 755 | nand_chip->options = NAND_NO_SUBPAGE_WRITE; | 758 | nand_chip->options = NAND_NO_SUBPAGE_WRITE; |
| @@ -775,6 +775,9 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip) · 774 unmodified lines | |||
| 775 | struct mtd_info *mtd = nand_to_mtd(chip); | 775 | struct mtd_info *mtd = nand_to_mtd(chip); |
| 776 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); | 776 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
| 777 | 777 | ||
| 778 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 779 | return 0; | ||
| 780 | |||
| 778 | /* OOB and ECC CPU and DMA work areas */ | 781 | /* OOB and ECC CPU and DMA work areas */ |
| 779 | host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); | 782 | host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); |
| 780 | 783 | ||
| @@ -786,11 +789,22 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip) · 5 unmodified lines | |||
| 786 | if (mtd->writesize <= 512) | 789 | if (mtd->writesize <= 512) |
| 787 | mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops); | 790 | mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops); |
| 788 | 791 | ||
| 792 | chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED; | ||
| 789 | /* These sizes remain the same regardless of page size */ | 793 | /* These sizes remain the same regardless of page size */ |
| 790 | chip->ecc.size = 256; | 794 | chip->ecc.size = 256; |
| 795 | chip->ecc.strength = 1; | ||
| 791 | chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES; | 796 | chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES; |
| 792 | chip->ecc.prepad = 0; | 797 | chip->ecc.prepad = 0; |
| 793 | chip->ecc.postpad = 0; | 798 | chip->ecc.postpad = 0; |
| 799 | chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome; | ||
| 800 | chip->ecc.read_page = lpc32xx_nand_read_page_syndrome; | ||
| 801 | chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome; | ||
| 802 | chip->ecc.write_page = lpc32xx_nand_write_page_syndrome; | ||
| 803 | chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome; | ||
| 804 | chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome; | ||
| 805 | chip->ecc.calculate = lpc32xx_nand_ecc_calculate; | ||
| 806 | chip->ecc.correct = nand_correct_data; | ||
| 807 | chip->ecc.hwctl = lpc32xx_nand_ecc_enable; | ||
| 794 | 808 | ||
| 795 | /* | 809 | /* |
| 796 | * Use a custom BBT marker setup for small page FLASH that | 810 | * Use a custom BBT marker setup for small page FLASH that |
| @@ -881,21 +895,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) · 84 unmodified lines | |||
| 881 | platform_set_drvdata(pdev, host); | 895 | platform_set_drvdata(pdev, host); |
| 882 | 896 | ||
| 883 | /* NAND callbacks for LPC32xx SLC hardware */ | 897 | /* NAND callbacks for LPC32xx SLC hardware */ |
| 884 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 885 | chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED; | ||
| 886 | chip->legacy.read_byte = lpc32xx_nand_read_byte; | 898 | chip->legacy.read_byte = lpc32xx_nand_read_byte; |
| 887 | chip->legacy.read_buf = lpc32xx_nand_read_buf; | 899 | chip->legacy.read_buf = lpc32xx_nand_read_buf; |
| 888 | chip->legacy.write_buf = lpc32xx_nand_write_buf; | 900 | chip->legacy.write_buf = lpc32xx_nand_write_buf; |
| 889 | chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome; | ||
| 890 | chip->ecc.read_page = lpc32xx_nand_read_page_syndrome; | ||
| 891 | chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome; | ||
| 892 | chip->ecc.write_page = lpc32xx_nand_write_page_syndrome; | ||
| 893 | chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome; | ||
| 894 | chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome; | ||
| 895 | chip->ecc.calculate = lpc32xx_nand_ecc_calculate; | ||
| 896 | chip->ecc.correct = nand_correct_data; | ||
| 897 | chip->ecc.strength = 1; | ||
| 898 | chip->ecc.hwctl = lpc32xx_nand_ecc_enable; | ||
| 899 | 901 | ||
| 900 | /* | 902 | /* |
| 901 | * Allocate a large enough buffer for a single huge page plus | 903 | * Allocate a large enough buffer for a single huge page plus |
| @@ -104,6 +104,7 @@ · 103 unmodified lines | |||
| 104 | #define NFC_TIMEOUT (HZ / 10) /* 1/10 s */ | 104 | #define NFC_TIMEOUT (HZ / 10) /* 1/10 s */ |
| 105 | 105 | ||
| 106 | struct mpc5121_nfc_prv { | 106 | struct mpc5121_nfc_prv { |
| 107 | struct nand_controller controller; | ||
| 107 | struct nand_chip chip; | 108 | struct nand_chip chip; |
| 108 | int irq; | 109 | int irq; |
| 109 | void __iomem *regs; | 110 | void __iomem *regs; |
| @@ -602,6 +603,18 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) · 492 unmodified lines | |||
| 602 | iounmap(prv->csreg); | 603 | iounmap(prv->csreg); |
| 603 | } | 604 | } |
| 604 | 605 | ||
| 606 | static int mpc5121_nfc_attach_chip(struct nand_chip *chip) | ||
| 607 | { | ||
| 608 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 609 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 610 | |||
| 611 | return 0; | ||
| 612 | } | ||
| 613 | |||
| 614 | static const struct nand_controller_ops mpc5121_nfc_ops = { | ||
| 615 | .attach_chip = mpc5121_nfc_attach_chip, | ||
| 616 | }; | ||
| 617 | |||
| 605 | static int mpc5121_nfc_probe(struct platform_device *op) | 618 | static int mpc5121_nfc_probe(struct platform_device *op) |
| 606 | { | 619 | { |
| 607 | struct device_node *dn = op->dev.of_node; | 620 | struct device_node *dn = op->dev.of_node; |
| @@ -634,6 +647,10 @@ static int mpc5121_nfc_probe(struct platform_device *op) · 26 unmodified lines | |||
| 634 | chip = &prv->chip; | 647 | chip = &prv->chip; |
| 635 | mtd = nand_to_mtd(chip); | 648 | mtd = nand_to_mtd(chip); |
| 636 | 649 | ||
| 650 | nand_controller_init(&prv->controller); | ||
| 651 | prv->controller.ops = &mpc5121_nfc_ops; | ||
| 652 | chip->controller = &prv->controller; | ||
| 653 | |||
| 637 | mtd->dev.parent = dev; | 654 | mtd->dev.parent = dev; |
| 638 | nand_set_controller_data(chip, prv); | 655 | nand_set_controller_data(chip, prv); |
| 639 | nand_set_flash_node(chip, dn); | 656 | nand_set_flash_node(chip, dn); |
| @@ -688,8 +705,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) · 48 unmodified lines | |||
| 688 | chip->legacy.set_features = nand_get_set_features_notsupp; | 705 | chip->legacy.set_features = nand_get_set_features_notsupp; |
| 689 | chip->legacy.get_features = nand_get_set_features_notsupp; | 706 | chip->legacy.get_features = nand_get_set_features_notsupp; |
| 690 | chip->bbt_options = NAND_BBT_USE_FLASH; | 707 | chip->bbt_options = NAND_BBT_USE_FLASH; |
| 691 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 692 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 693 | 708 | ||
| 694 | /* Support external chip-select logic on ADS5121 board */ | 709 | /* Support external chip-select logic on ADS5121 board */ |
| 695 | if (of_machine_is_compatible("fsl,mpc5121ads")) { | 710 | if (of_machine_is_compatible("fsl,mpc5121ads")) { |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | #include <linux/platform_data/mtd-orion_nand.h> | 22 | #include <linux/platform_data/mtd-orion_nand.h> |
| 23 | 23 | ||
| 24 | struct orion_nand_info { | 24 | struct orion_nand_info { |
| 25 | struct nand_controller controller; | ||
| 25 | struct nand_chip chip; | 26 | struct nand_chip chip; |
| 26 | struct clk *clk; | 27 | struct clk *clk; |
| 27 | }; | 28 | }; |
| @@ -82,6 +83,18 @@ static void orion_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int len) · 54 unmodified lines | |||
| 82 | buf[i++] = readb(io_base); | 83 | buf[i++] = readb(io_base); |
| 83 | } | 84 | } |
| 84 | 85 | ||
| 86 | static int orion_nand_attach_chip(struct nand_chip *chip) | ||
| 87 | { | ||
| 88 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 89 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 90 | |||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static const struct nand_controller_ops orion_nand_ops = { | ||
| 95 | .attach_chip = orion_nand_attach_chip, | ||
| 96 | }; | ||
| 97 | |||
| 85 | static int __init orion_nand_probe(struct platform_device *pdev) | 98 | static int __init orion_nand_probe(struct platform_device *pdev) |
| 86 | { | 99 | { |
| 87 | struct orion_nand_info *info; | 100 | struct orion_nand_info *info; |
| @@ -101,6 +114,10 @@ static int __init orion_nand_probe(struct platform_device *pdev) · 13 unmodified lines | |||
| 101 | nc = &info->chip; | 114 | nc = &info->chip; |
| 102 | mtd = nand_to_mtd(nc); | 115 | mtd = nand_to_mtd(nc); |
| 103 | 116 | ||
| 117 | nand_controller_init(&info->controller); | ||
| 118 | info->controller.ops = &orion_nand_ops; | ||
| 119 | nc->controller = &info->controller; | ||
| 120 | |||
| 104 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 121 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 105 | io_base = devm_ioremap_resource(&pdev->dev, res); | 122 | io_base = devm_ioremap_resource(&pdev->dev, res); |
| 106 | 123 | ||
| @@ -139,8 +156,6 @@ static int __init orion_nand_probe(struct platform_device *pdev) · 32 unmodified lines | |||
| 139 | nc->legacy.IO_ADDR_R = nc->legacy.IO_ADDR_W = io_base; | 156 | nc->legacy.IO_ADDR_R = nc->legacy.IO_ADDR_W = io_base; |
| 140 | nc->legacy.cmd_ctrl = orion_nand_cmd_ctrl; | 157 | nc->legacy.cmd_ctrl = orion_nand_cmd_ctrl; |
| 141 | nc->legacy.read_buf = orion_nand_read_buf; | 158 | nc->legacy.read_buf = orion_nand_read_buf; |
| 142 | nc->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 143 | nc->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 144 | 159 | ||
| 145 | if (board->chip_delay) | 160 | if (board->chip_delay) |
| 146 | nc->legacy.chip_delay = board->chip_delay; | 161 | nc->legacy.chip_delay = board->chip_delay; |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | static unsigned int lpcctl; | 30 | static unsigned int lpcctl; |
| 31 | static struct mtd_info *pasemi_nand_mtd; | 31 | static struct mtd_info *pasemi_nand_mtd; |
| 32 | static struct nand_controller controller; | ||
| 32 | static const char driver_name[] = "pasemi-nand"; | 33 | static const char driver_name[] = "pasemi-nand"; |
| 33 | 34 | ||
| 34 | static void pasemi_read_buf(struct nand_chip *chip, u_char *buf, int len) | 35 | static void pasemi_read_buf(struct nand_chip *chip, u_char *buf, int len) |
| @@ -73,6 +74,18 @@ static int pasemi_device_ready(struct nand_chip *chip) · 38 unmodified lines | |||
| 73 | return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR); | 74 | return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR); |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 77 | static int pasemi_attach_chip(struct nand_chip *chip) | ||
| 78 | { | ||
| 79 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 80 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 81 | |||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | static const struct nand_controller_ops pasemi_ops = { | ||
| 86 | .attach_chip = pasemi_attach_chip, | ||
| 87 | }; | ||
| 88 | |||
| 76 | static int pasemi_nand_probe(struct platform_device *ofdev) | 89 | static int pasemi_nand_probe(struct platform_device *ofdev) |
| 77 | { | 90 | { |
| 78 | struct device *dev = &ofdev->dev; | 91 | struct device *dev = &ofdev->dev; |
| @@ -100,6 +113,10 @@ static int pasemi_nand_probe(struct platform_device *ofdev) · 21 unmodified lines | |||
| 100 | goto out; | 113 | goto out; |
| 101 | } | 114 | } |
| 102 | 115 | ||
| 116 | controller.ops = &pasemi_ops; | ||
| 117 | nand_controller_init(&controller); | ||
| 118 | chip->controller = &controller; | ||
| 119 | |||
| 103 | pasemi_nand_mtd = nand_to_mtd(chip); | 120 | pasemi_nand_mtd = nand_to_mtd(chip); |
| 104 | 121 | ||
| 105 | /* Link the private data with the MTD structure */ | 122 | /* Link the private data with the MTD structure */ |
| @@ -132,8 +149,6 @@ static int pasemi_nand_probe(struct platform_device *ofdev) · 26 unmodified lines | |||
| 132 | chip->legacy.read_buf = pasemi_read_buf; | 149 | chip->legacy.read_buf = pasemi_read_buf; |
| 133 | chip->legacy.write_buf = pasemi_write_buf; | 150 | chip->legacy.write_buf = pasemi_write_buf; |
| 134 | chip->legacy.chip_delay = 0; | 151 | chip->legacy.chip_delay = 0; |
| 135 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 136 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 137 | 152 | ||
| 138 | /* Enable the following for a flash based bad block table */ | 153 | /* Enable the following for a flash based bad block table */ |
| 139 | chip->bbt_options = NAND_BBT_USE_FLASH; | 154 | chip->bbt_options = NAND_BBT_USE_FLASH; |
| @@ -14,10 +14,23 @@ · 13 unmodified lines | |||
| 14 | #include <linux/mtd/platnand.h> | 14 | #include <linux/mtd/platnand.h> |
| 15 | 15 | ||
| 16 | struct plat_nand_data { | 16 | struct plat_nand_data { |
| 17 | struct nand_controller controller; | ||
| 17 | struct nand_chip chip; | 18 | struct nand_chip chip; |
| 18 | void __iomem *io_base; | 19 | void __iomem *io_base; |
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 22 | static int plat_nand_attach_chip(struct nand_chip *chip) | ||
| 23 | { | ||
| 24 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 25 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 26 | |||
| 27 | return 0; | ||
| 28 | } | ||
| 29 | |||
| 30 | static const struct nand_controller_ops plat_nand_ops = { | ||
| 31 | .attach_chip = plat_nand_attach_chip, | ||
| 32 | }; | ||
| 33 | |||
| 21 | /* | 34 | /* |
| 22 | * Probe for the NAND device. | 35 | * Probe for the NAND device. |
| 23 | */ | 36 | */ |
| @@ -46,6 +59,10 @@ static int plat_nand_probe(struct platform_device *pdev) · 22 unmodified lines | |||
| 46 | if (!data) | 59 | if (!data) |
| 47 | return -ENOMEM; | 60 | return -ENOMEM; |
| 48 | 61 | ||
| 62 | data->controller.ops = &plat_nand_ops; | ||
| 63 | nand_controller_init(&data->controller); | ||
| 64 | data->chip.controller = &data->controller; | ||
| 65 | |||
| 49 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 66 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 50 | data->io_base = devm_ioremap_resource(&pdev->dev, res); | 67 | data->io_base = devm_ioremap_resource(&pdev->dev, res); |
| 51 | if (IS_ERR(data->io_base)) | 68 | if (IS_ERR(data->io_base)) |
| @@ -66,9 +83,6 @@ static int plat_nand_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 66 | data->chip.options |= pdata->chip.options; | 83 | data->chip.options |= pdata->chip.options; |
| 67 | data->chip.bbt_options |= pdata->chip.bbt_options; | 84 | data->chip.bbt_options |= pdata->chip.bbt_options; |
| 68 | 85 | ||
| 69 | data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 70 | data->chip.ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 71 | |||
| 72 | platform_set_drvdata(pdev, data); | 86 | platform_set_drvdata(pdev, data); |
| 73 | 87 | ||
| 74 | /* Handle any platform specific setup */ | 88 | /* Handle any platform specific setup */ |
| @@ -817,6 +817,29 @@ out: · 816 unmodified lines | |||
| 817 | return ret; | 817 | return ret; |
| 818 | } | 818 | } |
| 819 | 819 | ||
| 820 | static int r852_attach_chip(struct nand_chip *chip) | ||
| 821 | { | ||
| 822 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 823 | return 0; | ||
| 824 | |||
| 825 | chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED; | ||
| 826 | chip->ecc.size = R852_DMA_LEN; | ||
| 827 | chip->ecc.bytes = SM_OOB_SIZE; | ||
| 828 | chip->ecc.strength = 2; | ||
| 829 | chip->ecc.hwctl = r852_ecc_hwctl; | ||
| 830 | chip->ecc.calculate = r852_ecc_calculate; | ||
| 831 | chip->ecc.correct = r852_ecc_correct; | ||
| 832 | |||
| 833 | /* TODO: hack */ | ||
| 834 | chip->ecc.read_oob = r852_read_oob; | ||
| 835 | |||
| 836 | return 0; | ||
| 837 | } | ||
| 838 | |||
| 839 | static const struct nand_controller_ops r852_ops = { | ||
| 840 | .attach_chip = r852_attach_chip, | ||
| 841 | }; | ||
| 842 | |||
| 820 | static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | 843 | static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) |
| 821 | { | 844 | { |
| 822 | int error; | 845 | int error; |
| @@ -858,19 +881,6 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) · 35 unmodified lines | |||
| 858 | chip->legacy.read_buf = r852_read_buf; | 881 | chip->legacy.read_buf = r852_read_buf; |
| 859 | chip->legacy.write_buf = r852_write_buf; | 882 | chip->legacy.write_buf = r852_write_buf; |
| 860 | 883 | ||
| 861 | /* ecc */ | ||
| 862 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 863 | chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED; | ||
| 864 | chip->ecc.size = R852_DMA_LEN; | ||
| 865 | chip->ecc.bytes = SM_OOB_SIZE; | ||
| 866 | chip->ecc.strength = 2; | ||
| 867 | chip->ecc.hwctl = r852_ecc_hwctl; | ||
| 868 | chip->ecc.calculate = r852_ecc_calculate; | ||
| 869 | chip->ecc.correct = r852_ecc_correct; | ||
| 870 | |||
| 871 | /* TODO: hack */ | ||
| 872 | chip->ecc.read_oob = r852_read_oob; | ||
| 873 | |||
| 874 | /* init our device structure */ | 884 | /* init our device structure */ |
| 875 | dev = kzalloc(sizeof(struct r852_device), GFP_KERNEL); | 885 | dev = kzalloc(sizeof(struct r852_device), GFP_KERNEL); |
| 876 | 886 | ||
| @@ -882,6 +892,10 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) · 5 unmodified lines | |||
| 882 | dev->pci_dev = pci_dev; | 892 | dev->pci_dev = pci_dev; |
| 883 | pci_set_drvdata(pci_dev, dev); | 893 | pci_set_drvdata(pci_dev, dev); |
| 884 | 894 | ||
| 895 | nand_controller_init(&dev->controller); | ||
| 896 | dev->controller.ops = &r852_ops; | ||
| 897 | chip->controller = &dev->controller; | ||
| 898 | |||
| 885 | dev->bounce_buffer = dma_alloc_coherent(&pci_dev->dev, R852_DMA_LEN, | 899 | dev->bounce_buffer = dma_alloc_coherent(&pci_dev->dev, R852_DMA_LEN, |
| 886 | &dev->phys_bounce_buffer, GFP_KERNEL); | 900 | &dev->phys_bounce_buffer, GFP_KERNEL); |
| 887 | 901 | ||
| @@ -104,6 +104,7 @@ · 103 unmodified lines | |||
| 104 | #define DMA_MEMORY 1 | 104 | #define DMA_MEMORY 1 |
| 105 | 105 | ||
| 106 | struct r852_device { | 106 | struct r852_device { |
| 107 | struct nand_controller controller; | ||
| 107 | void __iomem *mmio; /* mmio */ | 108 | void __iomem *mmio; /* mmio */ |
| 108 | struct nand_chip *chip; /* nand chip backpointer */ | 109 | struct nand_chip *chip; /* nand chip backpointer */ |
| 109 | struct pci_dev *pci_dev; /* pci backpointer */ | 110 | struct pci_dev *pci_dev; /* pci backpointer */ |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | 21 | ||
| 22 | struct sharpsl_nand { | 22 | struct sharpsl_nand { |
| 23 | struct nand_controller controller; | ||
| 23 | struct nand_chip chip; | 24 | struct nand_chip chip; |
| 24 | 25 | ||
| 25 | void __iomem *io; | 26 | void __iomem *io; |
| @@ -96,6 +97,25 @@ static int sharpsl_nand_calculate_ecc(struct nand_chip *chip, · 70 unmodified lines | |||
| 96 | return readb(sharpsl->io + ECCCNTR) != 0; | 97 | return readb(sharpsl->io + ECCCNTR) != 0; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | static int sharpsl_attach_chip(struct nand_chip *chip) | ||
| 101 | { | ||
| 102 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 103 | return 0; | ||
| 104 | |||
| 105 | chip->ecc.size = 256; | ||
| 106 | chip->ecc.bytes = 3; | ||
| 107 | chip->ecc.strength = 1; | ||
| 108 | chip->ecc.hwctl = sharpsl_nand_enable_hwecc; | ||
| 109 | chip->ecc.calculate = sharpsl_nand_calculate_ecc; | ||
| 110 | chip->ecc.correct = nand_correct_data; | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | static const struct nand_controller_ops sharpsl_ops = { | ||
| 116 | .attach_chip = sharpsl_attach_chip, | ||
| 117 | }; | ||
| 118 | |||
| 99 | /* | 119 | /* |
| 100 | * Main initialization routine | 120 | * Main initialization routine |
| 101 | */ | 121 | */ |
| @@ -136,6 +156,10 @@ static int sharpsl_nand_probe(struct platform_device *pdev) · 34 unmodified lines | |||
| 136 | /* Get pointer to private data */ | 156 | /* Get pointer to private data */ |
| 137 | this = (struct nand_chip *)(&sharpsl->chip); | 157 | this = (struct nand_chip *)(&sharpsl->chip); |
| 138 | 158 | ||
| 159 | nand_controller_init(&sharpsl->controller); | ||
| 160 | sharpsl->controller.ops = &sharpsl_ops; | ||
| 161 | this->controller = &sharpsl->controller; | ||
| 162 | |||
| 139 | /* Link the private data with the MTD structure */ | 163 | /* Link the private data with the MTD structure */ |
| 140 | mtd = nand_to_mtd(this); | 164 | mtd = nand_to_mtd(this); |
| 141 | mtd->dev.parent = &pdev->dev; | 165 | mtd->dev.parent = &pdev->dev; |
| @@ -156,15 +180,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 156 | this->legacy.dev_ready = sharpsl_nand_dev_ready; | 180 | this->legacy.dev_ready = sharpsl_nand_dev_ready; |
| 157 | /* 15 us command delay time */ | 181 | /* 15 us command delay time */ |
| 158 | this->legacy.chip_delay = 15; | 182 | this->legacy.chip_delay = 15; |
| 159 | /* set eccmode using hardware ECC */ | ||
| 160 | this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 161 | this->ecc.size = 256; | ||
| 162 | this->ecc.bytes = 3; | ||
| 163 | this->ecc.strength = 1; | ||
| 164 | this->badblock_pattern = data->badblock_pattern; | 183 | this->badblock_pattern = data->badblock_pattern; |
| 165 | this->ecc.hwctl = sharpsl_nand_enable_hwecc; | ||
| 166 | this->ecc.calculate = sharpsl_nand_calculate_ecc; | ||
| 167 | this->ecc.correct = nand_correct_data; | ||
| 168 | 184 | ||
| 169 | /* Scan to find existence of the device */ | 185 | /* Scan to find existence of the device */ |
| 170 | err = nand_scan(this, 1); | 186 | err = nand_scan(this, 1); |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | #define FPGA_NAND_DATA_SHIFT 16 | 22 | #define FPGA_NAND_DATA_SHIFT 16 |
| 23 | 23 | ||
| 24 | struct socrates_nand_host { | 24 | struct socrates_nand_host { |
| 25 | struct nand_controller controller; | ||
| 25 | struct nand_chip nand_chip; | 26 | struct nand_chip nand_chip; |
| 26 | void __iomem *io_base; | 27 | void __iomem *io_base; |
| 27 | struct device *dev; | 28 | struct device *dev; |
| @@ -116,6 +117,18 @@ static int socrates_nand_device_ready(struct nand_chip *nand_chip) · 88 unmodified lines | |||
| 116 | return 1; | 117 | return 1; |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 120 | static int socrates_attach_chip(struct nand_chip *chip) | ||
| 121 | { | ||
| 122 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 123 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static const struct nand_controller_ops socrates_ops = { | ||
| 129 | .attach_chip = socrates_attach_chip, | ||
| 130 | }; | ||
| 131 | |||
| 119 | /* | 132 | /* |
| 120 | * Probe for the NAND device. | 133 | * Probe for the NAND device. |
| 121 | */ | 134 | */ |
| @@ -141,6 +154,10 @@ static int socrates_nand_probe(struct platform_device *ofdev) · 19 unmodified lines | |||
| 141 | mtd = nand_to_mtd(nand_chip); | 154 | mtd = nand_to_mtd(nand_chip); |
| 142 | host->dev = &ofdev->dev; | 155 | host->dev = &ofdev->dev; |
| 143 | 156 | ||
| 157 | nand_controller_init(&host->controller); | ||
| 158 | host->controller.ops = &socrates_ops; | ||
| 159 | nand_chip->controller = &host->controller; | ||
| 160 | |||
| 144 | /* link the private data structures */ | 161 | /* link the private data structures */ |
| 145 | nand_set_controller_data(nand_chip, host); | 162 | nand_set_controller_data(nand_chip, host); |
| 146 | nand_set_flash_node(nand_chip, ofdev->dev.of_node); | 163 | nand_set_flash_node(nand_chip, ofdev->dev.of_node); |
| @@ -153,10 +170,6 @@ static int socrates_nand_probe(struct platform_device *ofdev) · 6 unmodified lines | |||
| 153 | nand_chip->legacy.read_buf = socrates_nand_read_buf; | 170 | nand_chip->legacy.read_buf = socrates_nand_read_buf; |
| 154 | nand_chip->legacy.dev_ready = socrates_nand_device_ready; | 171 | nand_chip->legacy.dev_ready = socrates_nand_device_ready; |
| 155 | 172 | ||
| 156 | /* enable ECC */ | ||
| 157 | nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 158 | nand_chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 159 | |||
| 160 | /* TODO: I have no idea what real delay is. */ | 173 | /* TODO: I have no idea what real delay is. */ |
| 161 | nand_chip->legacy.chip_delay = 20; /* 20us command delay time */ | 174 | nand_chip->legacy.chip_delay = 20; /* 20us command delay time */ |
| 162 | 175 | ||
| @@ -103,6 +103,7 @@ · 102 unmodified lines | |||
| 103 | /*--------------------------------------------------------------------------*/ | 103 | /*--------------------------------------------------------------------------*/ |
| 104 | 104 | ||
| 105 | struct tmio_nand { | 105 | struct tmio_nand { |
| 106 | struct nand_controller controller; | ||
| 106 | struct nand_chip chip; | 107 | struct nand_chip chip; |
| 107 | struct completion comp; | 108 | struct completion comp; |
| 108 | 109 | ||
| @@ -355,6 +356,25 @@ static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio) · 246 unmodified lines | |||
| 355 | cell->disable(dev); | 356 | cell->disable(dev); |
| 356 | } | 357 | } |
| 357 | 358 | ||
| 359 | static int tmio_attach_chip(struct nand_chip *chip) | ||
| 360 | { | ||
| 361 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 362 | return 0; | ||
| 363 | |||
| 364 | chip->ecc.size = 512; | ||
| 365 | chip->ecc.bytes = 6; | ||
| 366 | chip->ecc.strength = 2; | ||
| 367 | chip->ecc.hwctl = tmio_nand_enable_hwecc; | ||
| 368 | chip->ecc.calculate = tmio_nand_calculate_ecc; | ||
| 369 | chip->ecc.correct = tmio_nand_correct_data; | ||
| 370 | |||
| 371 | return 0; | ||
| 372 | } | ||
| 373 | |||
| 374 | static const struct nand_controller_ops tmio_ops = { | ||
| 375 | .attach_chip = tmio_attach_chip, | ||
| 376 | }; | ||
| 377 | |||
| 358 | static int tmio_probe(struct platform_device *dev) | 378 | static int tmio_probe(struct platform_device *dev) |
| 359 | { | 379 | { |
| 360 | struct tmio_nand_data *data = dev_get_platdata(&dev->dev); | 380 | struct tmio_nand_data *data = dev_get_platdata(&dev->dev); |
| @@ -385,6 +405,10 @@ static int tmio_probe(struct platform_device *dev) · 24 unmodified lines | |||
| 385 | mtd->name = "tmio-nand"; | 405 | mtd->name = "tmio-nand"; |
| 386 | mtd->dev.parent = &dev->dev; | 406 | mtd->dev.parent = &dev->dev; |
| 387 | 407 | ||
| 408 | nand_controller_init(&tmio->controller); | ||
| 409 | tmio->controller.ops = &tmio_ops; | ||
| 410 | nand_chip->controller = &tmio->controller; | ||
| 411 | |||
| 388 | tmio->ccr = devm_ioremap(&dev->dev, ccr->start, resource_size(ccr)); | 412 | tmio->ccr = devm_ioremap(&dev->dev, ccr->start, resource_size(ccr)); |
| 389 | if (!tmio->ccr) | 413 | if (!tmio->ccr) |
| 390 | return -EIO; | 414 | return -EIO; |
| @@ -409,15 +433,6 @@ static int tmio_probe(struct platform_device *dev) · 18 unmodified lines | |||
| 409 | nand_chip->legacy.write_buf = tmio_nand_write_buf; | 433 | nand_chip->legacy.write_buf = tmio_nand_write_buf; |
| 410 | nand_chip->legacy.read_buf = tmio_nand_read_buf; | 434 | nand_chip->legacy.read_buf = tmio_nand_read_buf; |
| 411 | 435 | ||
| 412 | /* set eccmode using hardware ECC */ | ||
| 413 | nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 414 | nand_chip->ecc.size = 512; | ||
| 415 | nand_chip->ecc.bytes = 6; | ||
| 416 | nand_chip->ecc.strength = 2; | ||
| 417 | nand_chip->ecc.hwctl = tmio_nand_enable_hwecc; | ||
| 418 | nand_chip->ecc.calculate = tmio_nand_calculate_ecc; | ||
| 419 | nand_chip->ecc.correct = tmio_nand_correct_data; | ||
| 420 | |||
| 421 | if (data) | 436 | if (data) |
| 422 | nand_chip->badblock_pattern = data->badblock_pattern; | 437 | nand_chip->badblock_pattern = data->badblock_pattern; |
| 423 | 438 | ||
| @@ -253,6 +253,11 @@ static int txx9ndfmc_attach_chip(struct nand_chip *chip) · 252 unmodified lines | |||
| 253 | { | 253 | { |
| 254 | struct mtd_info *mtd = nand_to_mtd(chip); | 254 | struct mtd_info *mtd = nand_to_mtd(chip); |
| 255 | 255 | ||
| 256 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) | ||
| 257 | return 0; | ||
| 258 | |||
| 259 | chip->ecc.strength = 1; | ||
| 260 | |||
| 256 | if (mtd->writesize >= 512) { | 261 | if (mtd->writesize >= 512) { |
| 257 | chip->ecc.size = 512; | 262 | chip->ecc.size = 512; |
| 258 | chip->ecc.bytes = 6; | 263 | chip->ecc.bytes = 6; |
| @@ -261,6 +266,10 @@ static int txx9ndfmc_attach_chip(struct nand_chip *chip) · 2 unmodified lines | |||
| 261 | chip->ecc.bytes = 3; | 266 | chip->ecc.bytes = 3; |
| 262 | } | 267 | } |
| 263 | 268 | ||
| 269 | chip->ecc.calculate = txx9ndfmc_calculate_ecc; | ||
| 270 | chip->ecc.correct = txx9ndfmc_correct_data; | ||
| 271 | chip->ecc.hwctl = txx9ndfmc_enable_hwecc; | ||
| 272 | |||
| 264 | return 0; | 273 | return 0; |
| 265 | } | 274 | } |
| 266 | 275 | ||
| @@ -326,11 +335,6 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) · 59 unmodified lines | |||
| 326 | chip->legacy.write_buf = txx9ndfmc_write_buf; | 335 | chip->legacy.write_buf = txx9ndfmc_write_buf; |
| 327 | chip->legacy.cmd_ctrl = txx9ndfmc_cmd_ctrl; | 336 | chip->legacy.cmd_ctrl = txx9ndfmc_cmd_ctrl; |
| 328 | chip->legacy.dev_ready = txx9ndfmc_dev_ready; | 337 | chip->legacy.dev_ready = txx9ndfmc_dev_ready; |
| 329 | chip->ecc.calculate = txx9ndfmc_calculate_ecc; | ||
| 330 | chip->ecc.correct = txx9ndfmc_correct_data; | ||
| 331 | chip->ecc.hwctl = txx9ndfmc_enable_hwecc; | ||
| 332 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | ||
| 333 | chip->ecc.strength = 1; | ||
| 334 | chip->legacy.chip_delay = 100; | 338 | chip->legacy.chip_delay = 100; |
| 335 | chip->controller = &drvdata->controller; | 339 | chip->controller = &drvdata->controller; |
| 336 | 340 | ||
| @@ -62,6 +62,7 @@ · 61 unmodified lines | |||
| 62 | #define NAND_CON_NANDM 1 | 62 | #define NAND_CON_NANDM 1 |
| 63 | 63 | ||
| 64 | struct xway_nand_data { | 64 | struct xway_nand_data { |
| 65 | struct nand_controller controller; | ||
| 65 | struct nand_chip chip; | 66 | struct nand_chip chip; |
| 66 | unsigned long csflags; | 67 | unsigned long csflags; |
| 67 | void __iomem *nandaddr; | 68 | void __iomem *nandaddr; |
| @@ -145,6 +146,18 @@ static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len) · 77 unmodified lines | |||
| 145 | xway_writeb(nand_to_mtd(chip), NAND_WRITE_DATA, buf[i]); | 146 | xway_writeb(nand_to_mtd(chip), NAND_WRITE_DATA, buf[i]); |
| 146 | } | 147 | } |
| 147 | 148 | ||
| 149 | static int xway_attach_chip(struct nand_chip *chip) | ||
| 150 | { | ||
| 151 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | ||
| 152 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; | ||
| 153 | |||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | |||
| 157 | static const struct nand_controller_ops xway_nand_ops = { | ||
| 158 | .attach_chip = xway_attach_chip, | ||
| 159 | }; | ||
| 160 | |||
| 148 | /* | 161 | /* |
| 149 | * Probe for the NAND device. | 162 | * Probe for the NAND device. |
| 150 | */ | 163 | */ |
| @@ -180,8 +193,9 @@ static int xway_nand_probe(struct platform_device *pdev) · 29 unmodified lines | |||
| 180 | data->chip.legacy.read_byte = xway_read_byte; | 193 | data->chip.legacy.read_byte = xway_read_byte; |
| 181 | data->chip.legacy.chip_delay = 30; | 194 | data->chip.legacy.chip_delay = 30; |
| 182 | 195 | ||
| 183 | data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; | 196 | nand_controller_init(&data->controller); |
| 184 | data->chip.ecc.algo = NAND_ECC_ALGO_HAMMING; | 197 | data->controller.ops = &xway_nand_ops; |
| 198 | data->chip.controller = &data->controller; | ||
| 185 | 199 | ||
| 186 | platform_set_drvdata(pdev, data); | 200 | platform_set_drvdata(pdev, data); |
| 187 | nand_set_controller_data(&data->chip, data); | 201 | nand_set_controller_data(&data->chip, data); |
| @@ -1459,7 +1459,39 @@ static void bond_upper_dev_unlink(struct bonding *bond, struct slave *slave) · 1458 unmodified lines | |||
| 1459 | slave->dev->flags &= ~IFF_SLAVE; | 1459 | slave->dev->flags &= ~IFF_SLAVE; |
| 1460 | } | 1460 | } |
| 1461 | 1461 | ||
| 1462 | static struct slave *bond_alloc_slave(struct bonding *bond) | 1462 | static void slave_kobj_release(struct kobject *kobj) |
| 1463 | { | ||
| 1464 | struct slave *slave = to_slave(kobj); | ||
| 1465 | struct bonding *bond = bond_get_bond_by_slave(slave); | ||
| 1466 | |||
| 1467 | cancel_delayed_work_sync(&slave->notify_work); | ||
| 1468 | if (BOND_MODE(bond) == BOND_MODE_8023AD) | ||
| 1469 | kfree(SLAVE_AD_INFO(slave)); | ||
| 1470 | |||
| 1471 | kfree(slave); | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | static struct kobj_type slave_ktype = { | ||
| 1475 | .release = slave_kobj_release, | ||
| 1476 | #ifdef CONFIG_SYSFS | ||
| 1477 | .sysfs_ops = &slave_sysfs_ops, | ||
| 1478 | #endif | ||
| 1479 | }; | ||
| 1480 | |||
| 1481 | static int bond_kobj_init(struct slave *slave) | ||
| 1482 | { | ||
| 1483 | int err; | ||
| 1484 | |||
| 1485 | err = kobject_init_and_add(&slave->kobj, &slave_ktype, | ||
| 1486 | &(slave->dev->dev.kobj), "bonding_slave"); | ||
| 1487 | if (err) | ||
| 1488 | kobject_put(&slave->kobj); | ||
| 1489 | |||
| 1490 | return err; | ||
| 1491 | } | ||
| 1492 | |||
| 1493 | static struct slave *bond_alloc_slave(struct bonding *bond, | ||
| 1494 | struct net_device *slave_dev) | ||
| 1463 | { | 1495 | { |
| 1464 | struct slave *slave = NULL; | 1496 | struct slave *slave = NULL; |
| 1465 | 1497 | ||
| @@ -1467,11 +1499,17 @@ static struct slave *bond_alloc_slave(struct bonding *bond) · 1 unmodified line | |||
| 1467 | if (!slave) | 1499 | if (!slave) |
| 1468 | return NULL; | 1500 | return NULL; |
| 1469 | 1501 | ||
| 1502 | slave->bond = bond; | ||
| 1503 | slave->dev = slave_dev; | ||
| 1504 | |||
| 1505 | if (bond_kobj_init(slave)) | ||
| 1506 | return NULL; | ||
| 1507 | |||
| 1470 | if (BOND_MODE(bond) == BOND_MODE_8023AD) { | 1508 | if (BOND_MODE(bond) == BOND_MODE_8023AD) { |
| 1471 | SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info), | 1509 | SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info), |
| 1472 | GFP_KERNEL); | 1510 | GFP_KERNEL); |
| 1473 | if (!SLAVE_AD_INFO(slave)) { | 1511 | if (!SLAVE_AD_INFO(slave)) { |
| 1474 | kfree(slave); | 1512 | kobject_put(&slave->kobj); |
| 1475 | return NULL; | 1513 | return NULL; |
| 1476 | } | 1514 | } |
| 1477 | } | 1515 | } |
| @@ -1480,17 +1518,6 @@ static struct slave *bond_alloc_slave(struct bonding *bond) · 2 unmodified lines | |||
| 1480 | return slave; | 1518 | return slave; |
| 1481 | } | 1519 | } |
| 1482 | 1520 | ||
| 1483 | static void bond_free_slave(struct slave *slave) | ||
| 1484 | { | ||
| 1485 | struct bonding *bond = bond_get_bond_by_slave(slave); | ||
| 1486 | |||
| 1487 | cancel_delayed_work_sync(&slave->notify_work); | ||
| 1488 | if (BOND_MODE(bond) == BOND_MODE_8023AD) | ||
| 1489 | kfree(SLAVE_AD_INFO(slave)); | ||
| 1490 | |||
| 1491 | kfree(slave); | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | static void bond_fill_ifbond(struct bonding *bond, struct ifbond *info) | 1521 | static void bond_fill_ifbond(struct bonding *bond, struct ifbond *info) |
| 1495 | { | 1522 | { |
| 1496 | info->bond_mode = BOND_MODE(bond); | 1523 | info->bond_mode = BOND_MODE(bond); |
| @@ -1677,14 +1704,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, · 180 unmodified lines | |||
| 1677 | goto err_undo_flags; | 1704 | goto err_undo_flags; |
| 1678 | } | 1705 | } |
| 1679 | 1706 | ||
| 1680 | new_slave = bond_alloc_slave(bond); | 1707 | new_slave = bond_alloc_slave(bond, slave_dev); |
| 1681 | if (!new_slave) { | 1708 | if (!new_slave) { |
| 1682 | res = -ENOMEM; | 1709 | res = -ENOMEM; |
| 1683 | goto err_undo_flags; | 1710 | goto err_undo_flags; |
| 1684 | } | 1711 | } |
| 1685 | 1712 | ||
| 1686 | new_slave->bond = bond; | ||
| 1687 | new_slave->dev = slave_dev; | ||
| 1688 | /* Set the new_slave's queue_id to be zero. Queue ID mapping | 1713 | /* Set the new_slave's queue_id to be zero. Queue ID mapping |
| 1689 | * is set via sysfs or module option if desired. | 1714 | * is set via sysfs or module option if desired. |
| 1690 | */ | 1715 | */ |
| @@ -2006,7 +2031,7 @@ err_restore_mtu: · 315 unmodified lines | |||
| 2006 | dev_set_mtu(slave_dev, new_slave->original_mtu); | 2031 | dev_set_mtu(slave_dev, new_slave->original_mtu); |
| 2007 | 2032 | ||
| 2008 | err_free: | 2033 | err_free: |
| 2009 | bond_free_slave(new_slave); | 2034 | kobject_put(&new_slave->kobj); |
| 2010 | 2035 | ||
| 2011 | err_undo_flags: | 2036 | err_undo_flags: |
| 2012 | /* Enslave of first slave has failed and we need to fix master's mac */ | 2037 | /* Enslave of first slave has failed and we need to fix master's mac */ |
| @@ -2186,7 +2211,7 @@ static int __bond_release_one(struct net_device *bond_dev, · 173 unmodified lines | |||
| 2186 | if (!netif_is_bond_master(slave_dev)) | 2211 | if (!netif_is_bond_master(slave_dev)) |
| 2187 | slave_dev->priv_flags &= ~IFF_BONDING; | 2212 | slave_dev->priv_flags &= ~IFF_BONDING; |
| 2188 | 2213 | ||
| 2189 | bond_free_slave(slave); | 2214 | kobject_put(&slave->kobj); |
| 2190 | 2215 | ||
| 2191 | return 0; | 2216 | return 0; |
| 2192 | } | 2217 | } |
| @@ -121,7 +121,6 @@ static const struct slave_attribute *slave_attrs[] = { · 120 unmodified lines | |||
| 121 | }; | 121 | }; |
| 122 | 122 | ||
| 123 | #define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr) | 123 | #define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr) |
| 124 | #define to_slave(obj) container_of(obj, struct slave, kobj) | ||
| 125 | 124 | ||
| 126 | static ssize_t slave_show(struct kobject *kobj, | 125 | static ssize_t slave_show(struct kobject *kobj, |
| 127 | struct attribute *attr, char *buf) | 126 | struct attribute *attr, char *buf) |
| @@ -132,28 +131,15 @@ static ssize_t slave_show(struct kobject *kobj, · 4 unmodified lines | |||
| 132 | return slave_attr->show(slave, buf); | 131 | return slave_attr->show(slave, buf); |
| 133 | } | 132 | } |
| 134 | 133 | ||
| 135 | static const struct sysfs_ops slave_sysfs_ops = { | 134 | const struct sysfs_ops slave_sysfs_ops = { |
| 136 | .show = slave_show, | 135 | .show = slave_show, |
| 137 | }; | 136 | }; |
| 138 | 137 | ||
| 139 | static struct kobj_type slave_ktype = { | ||
| 140 | #ifdef CONFIG_SYSFS | ||
| 141 | .sysfs_ops = &slave_sysfs_ops, | ||
| 142 | #endif | ||
| 143 | }; | ||
| 144 | |||
| 145 | int bond_sysfs_slave_add(struct slave *slave) | 138 | int bond_sysfs_slave_add(struct slave *slave) |
| 146 | { | 139 | { |
| 147 | const struct slave_attribute **a; | 140 | const struct slave_attribute **a; |
| 148 | int err; | 141 | int err; |
| 149 | 142 | ||
| 150 | err = kobject_init_and_add(&slave->kobj, &slave_ktype, | ||
| 151 | &(slave->dev->dev.kobj), "bonding_slave"); | ||
| 152 | if (err) { | ||
| 153 | kobject_put(&slave->kobj); | ||
| 154 | return err; | ||
| 155 | } | ||
| 156 | |||
| 157 | for (a = slave_attrs; *a; ++a) { | 143 | for (a = slave_attrs; *a; ++a) { |
| 158 | err = sysfs_create_file(&slave->kobj, &((*a)->attr)); | 144 | err = sysfs_create_file(&slave->kobj, &((*a)->attr)); |
| 159 | if (err) { | 145 | if (err) { |
| @@ -171,6 +157,4 @@ void bond_sysfs_slave_del(struct slave *slave) · 11 unmodified lines | |||
| 171 | 157 | ||
| 172 | for (a = slave_attrs; *a; ++a) | 158 | for (a = slave_attrs; *a; ++a) |
| 173 | sysfs_remove_file(&slave->kobj, &((*a)->attr)); | 159 | sysfs_remove_file(&slave->kobj, &((*a)->attr)); |
| 174 | |||
| 175 | kobject_put(&slave->kobj); | ||
| 176 | } | 160 | } |
| @@ -1033,7 +1033,7 @@ static const struct can_bittiming_const m_can_bittiming_const_31X = { · 1032 unmodified lines | |||
| 1033 | .name = KBUILD_MODNAME, | 1033 | .name = KBUILD_MODNAME, |
| 1034 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | 1034 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ |
| 1035 | .tseg1_max = 256, | 1035 | .tseg1_max = 256, |
| 1036 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | 1036 | .tseg2_min = 2, /* Time segment 2 = phase_seg2 */ |
| 1037 | .tseg2_max = 128, | 1037 | .tseg2_max = 128, |
| 1038 | .sjw_max = 128, | 1038 | .sjw_max = 128, |
| 1039 | .brp_min = 1, | 1039 | .brp_min = 1, |
| @@ -1385,6 +1385,8 @@ static int m_can_dev_setup(struct m_can_classdev *m_can_dev) · 345 unmodified lines | |||
| 1385 | &m_can_data_bittiming_const_31X; | 1385 | &m_can_data_bittiming_const_31X; |
| 1386 | break; | 1386 | break; |
| 1387 | case 32: | 1387 | case 32: |
| 1388 | case 33: | ||
| 1389 | /* Support both MCAN version v3.2.x and v3.3.0 */ | ||
| 1388 | m_can_dev->can.bittiming_const = m_can_dev->bit_timing ? | 1390 | m_can_dev->can.bittiming_const = m_can_dev->bit_timing ? |
| 1389 | m_can_dev->bit_timing : &m_can_bittiming_const_31X; | 1391 | m_can_dev->bit_timing : &m_can_bittiming_const_31X; |
| 1390 | 1392 | ||
| @@ -1653,7 +1655,7 @@ static int m_can_open(struct net_device *dev) · 262 unmodified lines | |||
| 1653 | INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); | 1655 | INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); |
| 1654 | 1656 | ||
| 1655 | err = request_threaded_irq(dev->irq, NULL, m_can_isr, | 1657 | err = request_threaded_irq(dev->irq, NULL, m_can_isr, |
| 1656 | IRQF_ONESHOT | IRQF_TRIGGER_FALLING, | 1658 | IRQF_ONESHOT, |
| 1657 | dev->name, dev); | 1659 | dev->name, dev); |
| 1658 | } else { | 1660 | } else { |
| 1659 | err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, | 1661 | err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, |
| @@ -2735,6 +2735,10 @@ static int mcp251xfd_probe(struct spi_device *spi) · 2734 unmodified lines | |||
| 2735 | u32 freq; | 2735 | u32 freq; |
| 2736 | int err; | 2736 | int err; |
| 2737 | 2737 | ||
| 2738 | if (!spi->irq) | ||
| 2739 | return dev_err_probe(&spi->dev, -ENXIO, | ||
| 2740 | "No IRQ specified (maybe node \"interrupts-extended\" in DT missing)!\n"); | ||
| 2741 | |||
| 2738 | rx_int = devm_gpiod_get_optional(&spi->dev, "microchip,rx-int", | 2742 | rx_int = devm_gpiod_get_optional(&spi->dev, "microchip,rx-int", |
| 2739 | GPIOD_IN); | 2743 | GPIOD_IN); |
| 2740 | if (PTR_ERR(rx_int) == -EPROBE_DEFER) | 2744 | if (PTR_ERR(rx_int) == -EPROBE_DEFER) |
| @@ -64,21 +64,27 @@ enum gs_can_identify_mode { · 63 unmodified lines | |||
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | /* data types passed between host and device */ | 66 | /* data types passed between host and device */ |
| 67 | |||
| 68 | /* The firmware on the original USB2CAN by Geschwister Schneider | ||
| 69 | * Technologie Entwicklungs- und Vertriebs UG exchanges all data | ||
| 70 | * between the host and the device in host byte order. This is done | ||
| 71 | * with the struct gs_host_config::byte_order member, which is sent | ||
| 72 | * first to indicate the desired byte order. | ||
| 73 | * | ||
| 74 | * The widely used open source firmware candleLight doesn't support | ||
| 75 | * this feature and exchanges the data in little endian byte order. | ||
| 76 | */ | ||
| 67 | struct gs_host_config { | 77 | struct gs_host_config { |
| 68 | u32 byte_order; | 78 | __le32 byte_order; |
| 69 | } __packed; | 79 | } __packed; |
| 70 | /* All data exchanged between host and device is exchanged in host byte order, | ||
| 71 | * thanks to the struct gs_host_config byte_order member, which is sent first | ||
| 72 | * to indicate the desired byte order. | ||
| 73 | */ | ||
| 74 | 80 | ||
| 75 | struct gs_device_config { | 81 | struct gs_device_config { |
| 76 | u8 reserved1; | 82 | u8 reserved1; |
| 77 | u8 reserved2; | 83 | u8 reserved2; |
| 78 | u8 reserved3; | 84 | u8 reserved3; |
| 79 | u8 icount; | 85 | u8 icount; |
| 80 | u32 sw_version; | 86 | __le32 sw_version; |
| 81 | u32 hw_version; | 87 | __le32 hw_version; |
| 82 | } __packed; | 88 | } __packed; |
| 83 | 89 | ||
| 84 | #define GS_CAN_MODE_NORMAL 0 | 90 | #define GS_CAN_MODE_NORMAL 0 |
| @@ -88,26 +94,26 @@ struct gs_device_config { · 3 unmodified lines | |||
| 88 | #define GS_CAN_MODE_ONE_SHOT BIT(3) | 94 | #define GS_CAN_MODE_ONE_SHOT BIT(3) |
| 89 | 95 | ||
| 90 | struct gs_device_mode { | 96 | struct gs_device_mode { |
| 91 | u32 mode; | 97 | __le32 mode; |
| 92 | u32 flags; | 98 | __le32 flags; |
| 93 | } __packed; | 99 | } __packed; |
| 94 | 100 | ||
| 95 | struct gs_device_state { | 101 | struct gs_device_state { |
| 96 | u32 state; | 102 | __le32 state; |
| 97 | u32 rxerr; | 103 | __le32 rxerr; |
| 98 | u32 txerr; | 104 | __le32 txerr; |
| 99 | } __packed; | 105 | } __packed; |
| 100 | 106 | ||
| 101 | struct gs_device_bittiming { | 107 | struct gs_device_bittiming { |
| 102 | u32 prop_seg; | 108 | __le32 prop_seg; |
| 103 | u32 phase_seg1; | 109 | __le32 phase_seg1; |
| 104 | u32 phase_seg2; | 110 | __le32 phase_seg2; |
| 105 | u32 sjw; | 111 | __le32 sjw; |
| 106 | u32 brp; | 112 | __le32 brp; |
| 107 | } __packed; | 113 | } __packed; |
| 108 | 114 | ||
| 109 | struct gs_identify_mode { | 115 | struct gs_identify_mode { |
| 110 | u32 mode; | 116 | __le32 mode; |
| 111 | } __packed; | 117 | } __packed; |
| 112 | 118 | ||
| 113 | #define GS_CAN_FEATURE_LISTEN_ONLY BIT(0) | 119 | #define GS_CAN_FEATURE_LISTEN_ONLY BIT(0) |
| @@ -118,23 +124,23 @@ struct gs_identify_mode { · 4 unmodified lines | |||
| 118 | #define GS_CAN_FEATURE_IDENTIFY BIT(5) | 124 | #define GS_CAN_FEATURE_IDENTIFY BIT(5) |
| 119 | 125 | ||
| 120 | struct gs_device_bt_const { | 126 | struct gs_device_bt_const { |
| 121 | u32 feature; | 127 | __le32 feature; |
| 122 | u32 fclk_can; | 128 | __le32 fclk_can; |
| 123 | u32 tseg1_min; | 129 | __le32 tseg1_min; |
| 124 | u32 tseg1_max; | 130 | __le32 tseg1_max; |
| 125 | u32 tseg2_min; | 131 | __le32 tseg2_min; |
| 126 | u32 tseg2_max; | 132 | __le32 tseg2_max; |
| 127 | u32 sjw_max; | 133 | __le32 sjw_max; |
| 128 | u32 brp_min; | 134 | __le32 brp_min; |
| 129 | u32 brp_max; | 135 | __le32 brp_max; |
| 130 | u32 brp_inc; | 136 | __le32 brp_inc; |
| 131 | } __packed; | 137 | } __packed; |
| 132 | 138 | ||
| 133 | #define GS_CAN_FLAG_OVERFLOW 1 | 139 | #define GS_CAN_FLAG_OVERFLOW 1 |
| 134 | 140 | ||
| 135 | struct gs_host_frame { | 141 | struct gs_host_frame { |
| 136 | u32 echo_id; | 142 | u32 echo_id; |
| 137 | u32 can_id; | 143 | __le32 can_id; |
| 138 | 144 | ||
| 139 | u8 can_dlc; | 145 | u8 can_dlc; |
| 140 | u8 channel; | 146 | u8 channel; |
| @@ -330,13 +336,13 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) · 189 unmodified lines | |||
| 330 | if (!skb) | 336 | if (!skb) |
| 331 | return; | 337 | return; |
| 332 | 338 | ||
| 333 | cf->can_id = hf->can_id; | 339 | cf->can_id = le32_to_cpu(hf->can_id); |
| 334 | 340 | ||
| 335 | can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode); | 341 | can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode); |
| 336 | memcpy(cf->data, hf->data, 8); | 342 | memcpy(cf->data, hf->data, 8); |
| 337 | 343 | ||
| 338 | /* ERROR frames tell us information about the controller */ | 344 | /* ERROR frames tell us information about the controller */ |
| 339 | if (hf->can_id & CAN_ERR_FLAG) | 345 | if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG) |
| 340 | gs_update_state(dev, cf); | 346 | gs_update_state(dev, cf); |
| 341 | 347 | ||
| 342 | netdev->stats.rx_packets++; | 348 | netdev->stats.rx_packets++; |
| @@ -419,11 +425,11 @@ static int gs_usb_set_bittiming(struct net_device *netdev) · 76 unmodified lines | |||
| 419 | if (!dbt) | 425 | if (!dbt) |
| 420 | return -ENOMEM; | 426 | return -ENOMEM; |
| 421 | 427 | ||
| 422 | dbt->prop_seg = bt->prop_seg; | 428 | dbt->prop_seg = cpu_to_le32(bt->prop_seg); |
| 423 | dbt->phase_seg1 = bt->phase_seg1; | 429 | dbt->phase_seg1 = cpu_to_le32(bt->phase_seg1); |
| 424 | dbt->phase_seg2 = bt->phase_seg2; | 430 | dbt->phase_seg2 = cpu_to_le32(bt->phase_seg2); |
| 425 | dbt->sjw = bt->sjw; | 431 | dbt->sjw = cpu_to_le32(bt->sjw); |
| 426 | dbt->brp = bt->brp; | 432 | dbt->brp = cpu_to_le32(bt->brp); |
| 427 | 433 | ||
| 428 | /* request bit timings */ | 434 | /* request bit timings */ |
| 429 | rc = usb_control_msg(interface_to_usbdev(intf), | 435 | rc = usb_control_msg(interface_to_usbdev(intf), |
| @@ -504,7 +510,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, · 74 unmodified lines | |||
| 504 | 510 | ||
| 505 | cf = (struct can_frame *)skb->data; | 511 | cf = (struct can_frame *)skb->data; |
| 506 | 512 | ||
| 507 | hf->can_id = cf->can_id; | 513 | hf->can_id = cpu_to_le32(cf->can_id); |
| 508 | hf->can_dlc = can_get_cc_dlc(cf, dev->can.ctrlmode); | 514 | hf->can_dlc = can_get_cc_dlc(cf, dev->can.ctrlmode); |
| 509 | 515 | ||
| 510 | memcpy(hf->data, cf->data, cf->len); | 516 | memcpy(hf->data, cf->data, cf->len); |
| @@ -575,6 +581,7 @@ static int gs_can_open(struct net_device *netdev) · 64 unmodified lines | |||
| 575 | int rc, i; | 581 | int rc, i; |
| 576 | struct gs_device_mode *dm; | 582 | struct gs_device_mode *dm; |
| 577 | u32 ctrlmode; | 583 | u32 ctrlmode; |
| 584 | u32 flags = 0; | ||
| 578 | 585 | ||
| 579 | rc = open_candev(netdev); | 586 | rc = open_candev(netdev); |
| 580 | if (rc) | 587 | if (rc) |
| @@ -642,24 +649,24 @@ static int gs_can_open(struct net_device *netdev) · 61 unmodified lines | |||
| 642 | 649 | ||
| 643 | /* flags */ | 650 | /* flags */ |
| 644 | ctrlmode = dev->can.ctrlmode; | 651 | ctrlmode = dev->can.ctrlmode; |
| 645 | dm->flags = 0; | ||
| 646 | 652 | ||
| 647 | if (ctrlmode & CAN_CTRLMODE_LOOPBACK) | 653 | if (ctrlmode & CAN_CTRLMODE_LOOPBACK) |
| 648 | dm->flags |= GS_CAN_MODE_LOOP_BACK; | 654 | flags |= GS_CAN_MODE_LOOP_BACK; |
| 649 | else if (ctrlmode & CAN_CTRLMODE_LISTENONLY) | 655 | else if (ctrlmode & CAN_CTRLMODE_LISTENONLY) |
| 650 | dm->flags |= GS_CAN_MODE_LISTEN_ONLY; | 656 | flags |= GS_CAN_MODE_LISTEN_ONLY; |
| 651 | 657 | ||
| 652 | /* Controller is not allowed to retry TX | 658 | /* Controller is not allowed to retry TX |
| 653 | * this mode is unavailable on atmels uc3c hardware | 659 | * this mode is unavailable on atmels uc3c hardware |
| 654 | */ | 660 | */ |
| 655 | if (ctrlmode & CAN_CTRLMODE_ONE_SHOT) | 661 | if (ctrlmode & CAN_CTRLMODE_ONE_SHOT) |
| 656 | dm->flags |= GS_CAN_MODE_ONE_SHOT; | 662 | flags |= GS_CAN_MODE_ONE_SHOT; |
| 657 | 663 | ||
| 658 | if (ctrlmode & CAN_CTRLMODE_3_SAMPLES) | 664 | if (ctrlmode & CAN_CTRLMODE_3_SAMPLES) |
| 659 | dm->flags |= GS_CAN_MODE_TRIPLE_SAMPLE; | 665 | flags |= GS_CAN_MODE_TRIPLE_SAMPLE; |
| 660 | 666 | ||
| 661 | /* finally start device */ | 667 | /* finally start device */ |
| 662 | dm->mode = GS_CAN_MODE_START; | 668 | dm->mode = cpu_to_le32(GS_CAN_MODE_START); |
| 669 | dm->flags = cpu_to_le32(flags); | ||
| 663 | rc = usb_control_msg(interface_to_usbdev(dev->iface), | 670 | rc = usb_control_msg(interface_to_usbdev(dev->iface), |
| 664 | usb_sndctrlpipe(interface_to_usbdev(dev->iface), 0), | 671 | usb_sndctrlpipe(interface_to_usbdev(dev->iface), 0), |
| 665 | GS_USB_BREQ_MODE, | 672 | GS_USB_BREQ_MODE, |
| @@ -739,9 +746,9 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify) · 73 unmodified lines | |||
| 739 | return -ENOMEM; | 746 | return -ENOMEM; |
| 740 | 747 | ||
| 741 | if (do_identify) | 748 | if (do_identify) |
| 742 | imode->mode = GS_CAN_IDENTIFY_ON; | 749 | imode->mode = cpu_to_le32(GS_CAN_IDENTIFY_ON); |
| 743 | else | 750 | else |
| 744 | imode->mode = GS_CAN_IDENTIFY_OFF; | 751 | imode->mode = cpu_to_le32(GS_CAN_IDENTIFY_OFF); |
| 745 | 752 | ||
| 746 | rc = usb_control_msg(interface_to_usbdev(dev->iface), | 753 | rc = usb_control_msg(interface_to_usbdev(dev->iface), |
| 747 | usb_sndctrlpipe(interface_to_usbdev(dev->iface), | 754 | usb_sndctrlpipe(interface_to_usbdev(dev->iface), |
| @@ -792,6 +799,7 @@ static struct gs_can *gs_make_candev(unsigned int channel, · 44 unmodified lines | |||
| 792 | struct net_device *netdev; | 799 | struct net_device *netdev; |
| 793 | int rc; | 800 | int rc; |
| 794 | struct gs_device_bt_const *bt_const; | 801 | struct gs_device_bt_const *bt_const; |
| 802 | u32 feature; | ||
| 795 | 803 | ||
| 796 | bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL); | 804 | bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL); |
| 797 | if (!bt_const) | 805 | if (!bt_const) |
| @@ -832,14 +840,14 @@ static struct gs_can *gs_make_candev(unsigned int channel, · 34 unmodified lines | |||
| 832 | 840 | ||
| 833 | /* dev setup */ | 841 | /* dev setup */ |
| 834 | strcpy(dev->bt_const.name, "gs_usb"); | 842 | strcpy(dev->bt_const.name, "gs_usb"); |
| 835 | dev->bt_const.tseg1_min = bt_const->tseg1_min; | 843 | dev->bt_const.tseg1_min = le32_to_cpu(bt_const->tseg1_min); |
| 836 | dev->bt_const.tseg1_max = bt_const->tseg1_max; | 844 | dev->bt_const.tseg1_max = le32_to_cpu(bt_const->tseg1_max); |
| 837 | dev->bt_const.tseg2_min = bt_const->tseg2_min; | 845 | dev->bt_const.tseg2_min = le32_to_cpu(bt_const->tseg2_min); |
| 838 | dev->bt_const.tseg2_max = bt_const->tseg2_max; | 846 | dev->bt_const.tseg2_max = le32_to_cpu(bt_const->tseg2_max); |
| 839 | dev->bt_const.sjw_max = bt_const->sjw_max; | 847 | dev->bt_const.sjw_max = le32_to_cpu(bt_const->sjw_max); |
| 840 | dev->bt_const.brp_min = bt_const->brp_min; | 848 | dev->bt_const.brp_min = le32_to_cpu(bt_const->brp_min); |
| 841 | dev->bt_const.brp_max = bt_const->brp_max; | 849 | dev->bt_const.brp_max = le32_to_cpu(bt_const->brp_max); |
| 842 | dev->bt_const.brp_inc = bt_const->brp_inc; | 850 | dev->bt_const.brp_inc = le32_to_cpu(bt_const->brp_inc); |
| 843 | 851 | ||
| 844 | dev->udev = interface_to_usbdev(intf); | 852 | dev->udev = interface_to_usbdev(intf); |
| 845 | dev->iface = intf; | 853 | dev->iface = intf; |
| @@ -856,28 +864,29 @@ static struct gs_can *gs_make_candev(unsigned int channel, · 10 unmodified lines | |||
| 856 | 864 | ||
| 857 | /* can setup */ | 865 | /* can setup */ |
| 858 | dev->can.state = CAN_STATE_STOPPED; | 866 | dev->can.state = CAN_STATE_STOPPED; |
| 859 | dev->can.clock.freq = bt_const->fclk_can; | 867 | dev->can.clock.freq = le32_to_cpu(bt_const->fclk_can); |
| 860 | dev->can.bittiming_const = &dev->bt_const; | 868 | dev->can.bittiming_const = &dev->bt_const; |
| 861 | dev->can.do_set_bittiming = gs_usb_set_bittiming; | 869 | dev->can.do_set_bittiming = gs_usb_set_bittiming; |
| 862 | 870 | ||
| 863 | dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC; | 871 | dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC; |
| 864 | 872 | ||
| 865 | if (bt_const->feature & GS_CAN_FEATURE_LISTEN_ONLY) | 873 | feature = le32_to_cpu(bt_const->feature); |
| 874 | if (feature & GS_CAN_FEATURE_LISTEN_ONLY) | ||
| 866 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; | 875 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; |
| 867 | 876 | ||
| 868 | if (bt_const->feature & GS_CAN_FEATURE_LOOP_BACK) | 877 | if (feature & GS_CAN_FEATURE_LOOP_BACK) |
| 869 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_LOOPBACK; | 878 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_LOOPBACK; |
| 870 | 879 | ||
| 871 | if (bt_const->feature & GS_CAN_FEATURE_TRIPLE_SAMPLE) | 880 | if (feature & GS_CAN_FEATURE_TRIPLE_SAMPLE) |
| 872 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; | 881 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; |
| 873 | 882 | ||
| 874 | if (bt_const->feature & GS_CAN_FEATURE_ONE_SHOT) | 883 | if (feature & GS_CAN_FEATURE_ONE_SHOT) |
| 875 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT; | 884 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT; |
| 876 | 885 | ||
| 877 | SET_NETDEV_DEV(netdev, &intf->dev); | 886 | SET_NETDEV_DEV(netdev, &intf->dev); |
| 878 | 887 | ||
| 879 | if (dconf->sw_version > 1) | 888 | if (le32_to_cpu(dconf->sw_version) > 1) |
| 880 | if (bt_const->feature & GS_CAN_FEATURE_IDENTIFY) | 889 | if (feature & GS_CAN_FEATURE_IDENTIFY) |
| 881 | netdev->ethtool_ops = &gs_usb_ethtool_ops; | 890 | netdev->ethtool_ops = &gs_usb_ethtool_ops; |
| 882 | 891 | ||
| 883 | kfree(bt_const); | 892 | kfree(bt_const); |
| @@ -912,7 +921,7 @@ static int gs_usb_probe(struct usb_interface *intf, · 28 unmodified lines | |||
| 912 | if (!hconf) | 921 | if (!hconf) |
| 913 | return -ENOMEM; | 922 | return -ENOMEM; |
| 914 | 923 | ||
| 915 | hconf->byte_order = 0x0000beef; | 924 | hconf->byte_order = cpu_to_le32(0x0000beef); |
| 916 | 925 | ||
| 917 | /* send host config */ | 926 | /* send host config */ |
| 918 | rc = usb_control_msg(interface_to_usbdev(intf), | 927 | rc = usb_control_msg(interface_to_usbdev(intf), |
| @@ -516,6 +516,7 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq, · 515 unmodified lines | |||
| 516 | { | 516 | { |
| 517 | struct ena_com_rx_buf_info *ena_buf = &ena_rx_ctx->ena_bufs[0]; | 517 | struct ena_com_rx_buf_info *ena_buf = &ena_rx_ctx->ena_bufs[0]; |
| 518 | struct ena_eth_io_rx_cdesc_base *cdesc = NULL; | 518 | struct ena_eth_io_rx_cdesc_base *cdesc = NULL; |
| 519 | u16 q_depth = io_cq->q_depth; | ||
| 519 | u16 cdesc_idx = 0; | 520 | u16 cdesc_idx = 0; |
| 520 | u16 nb_hw_desc; | 521 | u16 nb_hw_desc; |
| 521 | u16 i = 0; | 522 | u16 i = 0; |
| @@ -543,6 +544,8 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq, · 21 unmodified lines | |||
| 543 | do { | 544 | do { |
| 544 | ena_buf[i].len = cdesc->length; | 545 | ena_buf[i].len = cdesc->length; |
| 545 | ena_buf[i].req_id = cdesc->req_id; | 546 | ena_buf[i].req_id = cdesc->req_id; |
| 547 | if (unlikely(ena_buf[i].req_id >= q_depth)) | ||
| 548 | return -EIO; | ||
| 546 | 549 | ||
| 547 | if (++i >= nb_hw_desc) | 550 | if (++i >= nb_hw_desc) |
| 548 | break; | 551 | break; |
| @@ -789,24 +789,6 @@ static void ena_free_all_io_tx_resources(struct ena_adapter *adapter) · 788 unmodified lines | |||
| 789 | adapter->num_io_queues); | 789 | adapter->num_io_queues); |
| 790 | } | 790 | } |
| 791 | 791 | ||
| 792 | static int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id) | ||
| 793 | { | ||
| 794 | if (likely(req_id < rx_ring->ring_size)) | ||
| 795 | return 0; | ||
| 796 | |||
| 797 | netif_err(rx_ring->adapter, rx_err, rx_ring->netdev, | ||
| 798 | "Invalid rx req_id: %hu\n", req_id); | ||
| 799 | |||
| 800 | u64_stats_update_begin(&rx_ring->syncp); | ||
| 801 | rx_ring->rx_stats.bad_req_id++; | ||
| 802 | u64_stats_update_end(&rx_ring->syncp); | ||
| 803 | |||
| 804 | /* Trigger device reset */ | ||
| 805 | rx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID; | ||
| 806 | set_bit(ENA_FLAG_TRIGGER_RESET, &rx_ring->adapter->flags); | ||
| 807 | return -EFAULT; | ||
| 808 | } | ||
| 809 | |||
| 810 | /* ena_setup_rx_resources - allocate I/O Rx resources (Descriptors) | 792 | /* ena_setup_rx_resources - allocate I/O Rx resources (Descriptors) |
| 811 | * @adapter: network interface device structure | 793 | * @adapter: network interface device structure |
| 812 | * @qid: queue index | 794 | * @qid: queue index |
| @@ -926,10 +908,14 @@ static void ena_free_all_io_rx_resources(struct ena_adapter *adapter) · 113 unmodified lines | |||
| 926 | static int ena_alloc_rx_page(struct ena_ring *rx_ring, | 908 | static int ena_alloc_rx_page(struct ena_ring *rx_ring, |
| 927 | struct ena_rx_buffer *rx_info, gfp_t gfp) | 909 | struct ena_rx_buffer *rx_info, gfp_t gfp) |
| 928 | { | 910 | { |
| 911 | int headroom = rx_ring->rx_headroom; | ||
| 929 | struct ena_com_buf *ena_buf; | 912 | struct ena_com_buf *ena_buf; |
| 930 | struct page *page; | 913 | struct page *page; |
| 931 | dma_addr_t dma; | 914 | dma_addr_t dma; |
| 932 | 915 | ||
| 916 | /* restore page offset value in case it has been changed by device */ | ||
| 917 | rx_info->page_offset = headroom; | ||
| 918 | |||
| 933 | /* if previous allocated page is not used */ | 919 | /* if previous allocated page is not used */ |
| 934 | if (unlikely(rx_info->page)) | 920 | if (unlikely(rx_info->page)) |
| 935 | return 0; | 921 | return 0; |
| @@ -959,10 +945,9 @@ static int ena_alloc_rx_page(struct ena_ring *rx_ring, · 23 unmodified lines | |||
| 959 | "Allocate page %p, rx_info %p\n", page, rx_info); | 945 | "Allocate page %p, rx_info %p\n", page, rx_info); |
| 960 | 946 | ||
| 961 | rx_info->page = page; | 947 | rx_info->page = page; |
| 962 | rx_info->page_offset = 0; | ||
| 963 | ena_buf = &rx_info->ena_buf; | 948 | ena_buf = &rx_info->ena_buf; |
| 964 | ena_buf->paddr = dma + rx_ring->rx_headroom; | 949 | ena_buf->paddr = dma + headroom; |
| 965 | ena_buf->len = ENA_PAGE_SIZE - rx_ring->rx_headroom; | 950 | ena_buf->len = ENA_PAGE_SIZE - headroom; |
| 966 | 951 | ||
| 967 | return 0; | 952 | return 0; |
| 968 | } | 953 | } |
| @@ -1356,15 +1341,10 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, · 387 unmodified lines | |||
| 1356 | struct ena_rx_buffer *rx_info; | 1341 | struct ena_rx_buffer *rx_info; |
| 1357 | u16 len, req_id, buf = 0; | 1342 | u16 len, req_id, buf = 0; |
| 1358 | void *va; | 1343 | void *va; |
| 1359 | int rc; | ||
| 1360 | 1344 | ||
| 1361 | len = ena_bufs[buf].len; | 1345 | len = ena_bufs[buf].len; |
| 1362 | req_id = ena_bufs[buf].req_id; | 1346 | req_id = ena_bufs[buf].req_id; |
| 1363 | 1347 | ||
| 1364 | rc = validate_rx_req_id(rx_ring, req_id); | ||
| 1365 | if (unlikely(rc < 0)) | ||
| 1366 | return NULL; | ||
| 1367 | |||
| 1368 | rx_info = &rx_ring->rx_buffer_info[req_id]; | 1348 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1369 | 1349 | ||
| 1370 | if (unlikely(!rx_info->page)) { | 1350 | if (unlikely(!rx_info->page)) { |
| @@ -1379,7 +1359,8 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, · 8 unmodified lines | |||
| 1379 | 1359 | ||
| 1380 | /* save virt address of first buffer */ | 1360 | /* save virt address of first buffer */ |
| 1381 | va = page_address(rx_info->page) + rx_info->page_offset; | 1361 | va = page_address(rx_info->page) + rx_info->page_offset; |
| 1382 | prefetch(va + NET_IP_ALIGN); | 1362 | |
| 1363 | prefetch(va); | ||
| 1383 | 1364 | ||
| 1384 | if (len <= rx_ring->rx_copybreak) { | 1365 | if (len <= rx_ring->rx_copybreak) { |
| 1385 | skb = ena_alloc_skb(rx_ring, false); | 1366 | skb = ena_alloc_skb(rx_ring, false); |
| @@ -1420,8 +1401,6 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, · 34 unmodified lines | |||
| 1420 | 1401 | ||
| 1421 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page, | 1402 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page, |
| 1422 | rx_info->page_offset, len, ENA_PAGE_SIZE); | 1403 | rx_info->page_offset, len, ENA_PAGE_SIZE); |
| 1423 | /* The offset is non zero only for the first buffer */ | ||
| 1424 | rx_info->page_offset = 0; | ||
| 1425 | 1404 | ||
| 1426 | netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, | 1405 | netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, |
| 1427 | "RX skb updated. len %d. data_len %d\n", | 1406 | "RX skb updated. len %d. data_len %d\n", |
| @@ -1440,10 +1419,6 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, · 12 unmodified lines | |||
| 1440 | len = ena_bufs[buf].len; | 1419 | len = ena_bufs[buf].len; |
| 1441 | req_id = ena_bufs[buf].req_id; | 1420 | req_id = ena_bufs[buf].req_id; |
| 1442 | 1421 | ||
| 1443 | rc = validate_rx_req_id(rx_ring, req_id); | ||
| 1444 | if (unlikely(rc < 0)) | ||
| 1445 | return NULL; | ||
| 1446 | |||
| 1447 | rx_info = &rx_ring->rx_buffer_info[req_id]; | 1422 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1448 | } while (1); | 1423 | } while (1); |
| 1449 | 1424 | ||
| @@ -1544,8 +1519,7 @@ static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp) · 94 unmodified lines | |||
| 1544 | int ret; | 1519 | int ret; |
| 1545 | 1520 | ||
| 1546 | rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; | 1521 | rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; |
| 1547 | xdp->data = page_address(rx_info->page) + | 1522 | xdp->data = page_address(rx_info->page) + rx_info->page_offset; |
| 1548 | rx_info->page_offset + rx_ring->rx_headroom; | ||
| 1549 | xdp_set_data_meta_invalid(xdp); | 1523 | xdp_set_data_meta_invalid(xdp); |
| 1550 | xdp->data_hard_start = page_address(rx_info->page); | 1524 | xdp->data_hard_start = page_address(rx_info->page); |
| 1551 | xdp->data_end = xdp->data + rx_ring->ena_bufs[0].len; | 1525 | xdp->data_end = xdp->data + rx_ring->ena_bufs[0].len; |
| @@ -1612,8 +1586,9 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, · 60 unmodified lines | |||
| 1612 | if (unlikely(ena_rx_ctx.descs == 0)) | 1586 | if (unlikely(ena_rx_ctx.descs == 0)) |
| 1613 | break; | 1587 | break; |
| 1614 | 1588 | ||
| 1589 | /* First descriptor might have an offset set by the device */ | ||
| 1615 | rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; | 1590 | rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; |
| 1616 | rx_info->page_offset = ena_rx_ctx.pkt_offset; | 1591 | rx_info->page_offset += ena_rx_ctx.pkt_offset; |
| 1617 | 1592 | ||
| 1618 | netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, | 1593 | netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, |
| 1619 | "rx_poll: q %d got packet from ena. descs #: %d l3 proto %d l4 proto %d hash: %x\n", | 1594 | "rx_poll: q %d got packet from ena. descs #: %d l3 proto %d l4 proto %d hash: %x\n", |
| @@ -1697,12 +1672,18 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, · 77 unmodified lines | |||
| 1697 | error: | 1672 | error: |
| 1698 | adapter = netdev_priv(rx_ring->netdev); | 1673 | adapter = netdev_priv(rx_ring->netdev); |
| 1699 | 1674 | ||
| 1700 | u64_stats_update_begin(&rx_ring->syncp); | 1675 | if (rc == -ENOSPC) { |
| 1701 | rx_ring->rx_stats.bad_desc_num++; | 1676 | u64_stats_update_begin(&rx_ring->syncp); |
| 1702 | u64_stats_update_end(&rx_ring->syncp); | 1677 | rx_ring->rx_stats.bad_desc_num++; |
| 1678 | u64_stats_update_end(&rx_ring->syncp); | ||
| 1679 | adapter->reset_reason = ENA_REGS_RESET_TOO_MANY_RX_DESCS; | ||
| 1680 | } else { | ||
| 1681 | u64_stats_update_begin(&rx_ring->syncp); | ||
| 1682 | rx_ring->rx_stats.bad_req_id++; | ||
| 1683 | u64_stats_update_end(&rx_ring->syncp); | ||
| 1684 | adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID; | ||
| 1685 | } | ||
| 1703 | 1686 | ||
| 1704 | /* Too many desc from the device. Trigger reset */ | ||
| 1705 | adapter->reset_reason = ENA_REGS_RESET_TOO_MANY_RX_DESCS; | ||
| 1706 | set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); | 1687 | set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); |
| 1707 | 1688 | ||
| 1708 | return 0; | 1689 | return 0; |
| @@ -3388,16 +3369,9 @@ static int ena_device_init(struct ena_com_dev *ena_dev, struct pci_dev *pdev, · 1679 unmodified lines | |||
| 3388 | goto err_mmio_read_less; | 3369 | goto err_mmio_read_less; |
| 3389 | } | 3370 | } |
| 3390 | 3371 | ||
| 3391 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_width)); | 3372 | rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_width)); |
| 3392 | if (rc) { | 3373 | if (rc) { |
| 3393 | dev_err(dev, "pci_set_dma_mask failed 0x%x\n", rc); | 3374 | dev_err(dev, "dma_set_mask_and_coherent failed %d\n", rc); |
| 3394 | goto err_mmio_read_less; | ||
| 3395 | } | ||
| 3396 | |||
| 3397 | rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(dma_width)); | ||
| 3398 | if (rc) { | ||
| 3399 | dev_err(dev, "err_pci_set_consistent_dma_mask failed 0x%x\n", | ||
| 3400 | rc); | ||
| 3401 | goto err_mmio_read_less; | 3375 | goto err_mmio_read_less; |
| 3402 | } | 3376 | } |
| 3403 | 3377 | ||
| @@ -4167,6 +4141,12 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 763 unmodified lines | |||
| 4167 | return rc; | 4141 | return rc; |
| 4168 | } | 4142 | } |
| 4169 | 4143 | ||
| 4144 | rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(ENA_MAX_PHYS_ADDR_SIZE_BITS)); | ||
| 4145 | if (rc) { | ||
| 4146 | dev_err(&pdev->dev, "dma_set_mask_and_coherent failed %d\n", rc); | ||
| 4147 | goto err_disable_device; | ||
| 4148 | } | ||
| 4149 | |||
| 4170 | pci_set_master(pdev); | 4150 | pci_set_master(pdev); |
| 4171 | 4151 | ||
| 4172 | ena_dev = vzalloc(sizeof(*ena_dev)); | 4152 | ena_dev = vzalloc(sizeof(*ena_dev)); |
| @@ -413,85 +413,63 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 412 unmodified lines | |||
| 413 | buff->rxdata.pg_off, | 413 | buff->rxdata.pg_off, |
| 414 | buff->len, DMA_FROM_DEVICE); | 414 | buff->len, DMA_FROM_DEVICE); |
| 415 | 415 | ||
| 416 | /* for single fragment packets use build_skb() */ | 416 | skb = napi_alloc_skb(napi, AQ_CFG_RX_HDR_SIZE); |
| 417 | if (buff->is_eop && | 417 | if (unlikely(!skb)) { |
| 418 | buff->len <= AQ_CFG_RX_FRAME_MAX - AQ_SKB_ALIGN) { | 418 | u64_stats_update_begin(&self->stats.rx.syncp); |
| 419 | skb = build_skb(aq_buf_vaddr(&buff->rxdata), | 419 | self->stats.rx.skb_alloc_fails++; |
| 420 | u64_stats_update_end(&self->stats.rx.syncp); | ||
| 421 | err = -ENOMEM; | ||
| 422 | goto err_exit; | ||
| 423 | } | ||
| 424 | if (is_ptp_ring) | ||
| 425 | buff->len -= | ||
| 426 | aq_ptp_extract_ts(self->aq_nic, skb, | ||
| 427 | aq_buf_vaddr(&buff->rxdata), | ||
| 428 | buff->len); | ||
| 429 | |||
| 430 | hdr_len = buff->len; | ||
| 431 | if (hdr_len > AQ_CFG_RX_HDR_SIZE) | ||
| 432 | hdr_len = eth_get_headlen(skb->dev, | ||
| 433 | aq_buf_vaddr(&buff->rxdata), | ||
| 434 | AQ_CFG_RX_HDR_SIZE); | ||
| 435 | |||
| 436 | memcpy(__skb_put(skb, hdr_len), aq_buf_vaddr(&buff->rxdata), | ||
| 437 | ALIGN(hdr_len, sizeof(long))); | ||
| 438 | |||
| 439 | if (buff->len - hdr_len > 0) { | ||
| 440 | skb_add_rx_frag(skb, 0, buff->rxdata.page, | ||
| 441 | buff->rxdata.pg_off + hdr_len, | ||
| 442 | buff->len - hdr_len, | ||
| 420 | AQ_CFG_RX_FRAME_MAX); | 443 | AQ_CFG_RX_FRAME_MAX); |
| 421 | if (unlikely(!skb)) { | ||
| 422 | u64_stats_update_begin(&self->stats.rx.syncp); | ||
| 423 | self->stats.rx.skb_alloc_fails++; | ||
| 424 | u64_stats_update_end(&self->stats.rx.syncp); | ||
| 425 | err = -ENOMEM; | ||
| 426 | goto err_exit; | ||
| 427 | } | ||
| 428 | if (is_ptp_ring) | ||
| 429 | buff->len -= | ||
| 430 | aq_ptp_extract_ts(self->aq_nic, skb, | ||
| 431 | aq_buf_vaddr(&buff->rxdata), | ||
| 432 | buff->len); | ||
| 433 | skb_put(skb, buff->len); | ||
| 434 | page_ref_inc(buff->rxdata.page); | 444 | page_ref_inc(buff->rxdata.page); |
| 435 | } else { | 445 | } |
| 436 | skb = napi_alloc_skb(napi, AQ_CFG_RX_HDR_SIZE); | ||
| 437 | if (unlikely(!skb)) { | ||
| 438 | u64_stats_update_begin(&self->stats.rx.syncp); | ||
| 439 | self->stats.rx.skb_alloc_fails++; | ||
| 440 | u64_stats_update_end(&self->stats.rx.syncp); | ||
| 441 | err = -ENOMEM; | ||
| 442 | goto err_exit; | ||
| 443 | } | ||
| 444 | if (is_ptp_ring) | ||
| 445 | buff->len -= | ||
| 446 | aq_ptp_extract_ts(self->aq_nic, skb, | ||
| 447 | aq_buf_vaddr(&buff->rxdata), | ||
| 448 | buff->len); | ||
| 449 | |||
| 450 | hdr_len = buff->len; | ||
| 451 | if (hdr_len > AQ_CFG_RX_HDR_SIZE) | ||
| 452 | hdr_len = eth_get_headlen(skb->dev, | ||
| 453 | aq_buf_vaddr(&buff->rxdata), | ||
| 454 | AQ_CFG_RX_HDR_SIZE); | ||
| 455 | |||
| 456 | memcpy(__skb_put(skb, hdr_len), aq_buf_vaddr(&buff->rxdata), | ||
| 457 | ALIGN(hdr_len, sizeof(long))); | ||
| 458 | |||
| 459 | if (buff->len - hdr_len > 0) { | ||
| 460 | skb_add_rx_frag(skb, 0, buff->rxdata.page, | ||
| 461 | buff->rxdata.pg_off + hdr_len, | ||
| 462 | buff->len - hdr_len, | ||
| 463 | AQ_CFG_RX_FRAME_MAX); | ||
| 464 | page_ref_inc(buff->rxdata.page); | ||
| 465 | } | ||
| 466 | 446 | ||
| 467 | if (!buff->is_eop) { | 447 | if (!buff->is_eop) { |
| 468 | buff_ = buff; | 448 | buff_ = buff; |
| 469 | i = 1U; | 449 | i = 1U; |
| 470 | do { | 450 | do { |
| 471 | next_ = buff_->next, | 451 | next_ = buff_->next; |
| 472 | buff_ = &self->buff_ring[next_]; | 452 | buff_ = &self->buff_ring[next_]; |
| 473 | 453 | ||
| 474 | dma_sync_single_range_for_cpu( | 454 | dma_sync_single_range_for_cpu(aq_nic_get_dev(self->aq_nic), |
| 475 | aq_nic_get_dev(self->aq_nic), | 455 | buff_->rxdata.daddr, |
| 476 | buff_->rxdata.daddr, | 456 | buff_->rxdata.pg_off, |
| 477 | buff_->rxdata.pg_off, | 457 | buff_->len, |
| 478 | buff_->len, | 458 | DMA_FROM_DEVICE); |
| 479 | DMA_FROM_DEVICE); | 459 | skb_add_rx_frag(skb, i++, |
| 480 | skb_add_rx_frag(skb, i++, | 460 | buff_->rxdata.page, |
| 481 | buff_->rxdata.page, | 461 | buff_->rxdata.pg_off, |
| 482 | buff_->rxdata.pg_off, | 462 | buff_->len, |
| 483 | buff_->len, | 463 | AQ_CFG_RX_FRAME_MAX); |
| 484 | AQ_CFG_RX_FRAME_MAX); | 464 | page_ref_inc(buff_->rxdata.page); |
| 485 | page_ref_inc(buff_->rxdata.page); | 465 | buff_->is_cleaned = 1; |
| 486 | buff_->is_cleaned = 1; | ||
| 487 | |||
| 488 | buff->is_ip_cso &= buff_->is_ip_cso; | ||
| 489 | buff->is_udp_cso &= buff_->is_udp_cso; | ||
| 490 | buff->is_tcp_cso &= buff_->is_tcp_cso; | ||
| 491 | buff->is_cso_err |= buff_->is_cso_err; | ||
| 492 | 466 | ||
| 493 | } while (!buff_->is_eop); | 467 | buff->is_ip_cso &= buff_->is_ip_cso; |
| 494 | } | 468 | buff->is_udp_cso &= buff_->is_udp_cso; |
| 469 | buff->is_tcp_cso &= buff_->is_tcp_cso; | ||
| 470 | buff->is_cso_err |= buff_->is_cso_err; | ||
| 471 | |||
| 472 | } while (!buff_->is_eop); | ||
| 495 | } | 473 | } |
| 496 | 474 | ||
| 497 | if (buff->is_vlan) | 475 | if (buff->is_vlan) |
| @@ -11590,7 +11590,8 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) · 11589 unmodified lines | |||
| 11590 | if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) != 0 && | 11590 | if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) != 0 && |
| 11591 | dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) { | 11591 | dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) { |
| 11592 | dev_err(&pdev->dev, "System does not support DMA, aborting\n"); | 11592 | dev_err(&pdev->dev, "System does not support DMA, aborting\n"); |
| 11593 | goto init_err_disable; | 11593 | rc = -EIO; |
| 11594 | goto init_err_release; | ||
| 11594 | } | 11595 | } |
| 11595 | 11596 | ||
| 11596 | pci_set_master(pdev); | 11597 | pci_set_master(pdev); |
| @@ -12674,6 +12675,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 1077 unmodified lines | |||
| 12674 | create_singlethread_workqueue("bnxt_pf_wq"); | 12675 | create_singlethread_workqueue("bnxt_pf_wq"); |
| 12675 | if (!bnxt_pf_wq) { | 12676 | if (!bnxt_pf_wq) { |
| 12676 | dev_err(&pdev->dev, "Unable to create workqueue.\n"); | 12677 | dev_err(&pdev->dev, "Unable to create workqueue.\n"); |
| 12678 | rc = -ENOMEM; | ||
| 12677 | goto init_err_pci_clean; | 12679 | goto init_err_pci_clean; |
| 12678 | } | 12680 | } |
| 12679 | } | 12681 | } |
| @@ -68,7 +68,7 @@ config CHELSIO_T3 · 67 unmodified lines | |||
| 68 | 68 | ||
| 69 | config CHELSIO_T4 | 69 | config CHELSIO_T4 |
| 70 | tristate "Chelsio Communications T4/T5/T6 Ethernet support" | 70 | tristate "Chelsio Communications T4/T5/T6 Ethernet support" |
| 71 | depends on PCI && (IPV6 || IPV6=n) | 71 | depends on PCI && (IPV6 || IPV6=n) && (TLS || TLS=n) |
| 72 | select FW_LOADER | 72 | select FW_LOADER |
| 73 | select MDIO | 73 | select MDIO |
| 74 | select ZLIB_DEFLATE | 74 | select ZLIB_DEFLATE |
| @@ -880,7 +880,8 @@ int set_filter_wr(struct adapter *adapter, int fidx) · 879 unmodified lines | |||
| 880 | FW_FILTER_WR_OVLAN_VLD_V(f->fs.val.ovlan_vld) | | 880 | FW_FILTER_WR_OVLAN_VLD_V(f->fs.val.ovlan_vld) | |
| 881 | FW_FILTER_WR_IVLAN_VLDM_V(f->fs.mask.ivlan_vld) | | 881 | FW_FILTER_WR_IVLAN_VLDM_V(f->fs.mask.ivlan_vld) | |
| 882 | FW_FILTER_WR_OVLAN_VLDM_V(f->fs.mask.ovlan_vld)); | 882 | FW_FILTER_WR_OVLAN_VLDM_V(f->fs.mask.ovlan_vld)); |
| 883 | fwr->smac_sel = f->smt->idx; | 883 | if (f->fs.newsmac) |
| 884 | fwr->smac_sel = f->smt->idx; | ||
| 884 | fwr->rx_chan_rx_rpl_iq = | 885 | fwr->rx_chan_rx_rpl_iq = |
| 885 | htons(FW_FILTER_WR_RX_CHAN_V(0) | | 886 | htons(FW_FILTER_WR_RX_CHAN_V(0) | |
| 886 | FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id)); | 887 | FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id)); |
| @@ -544,7 +544,9 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk, · 543 unmodified lines | |||
| 544 | /* need to wait for hw response, can't free tx_info yet. */ | 544 | /* need to wait for hw response, can't free tx_info yet. */ |
| 545 | if (tx_info->open_state == CH_KTLS_OPEN_PENDING) | 545 | if (tx_info->open_state == CH_KTLS_OPEN_PENDING) |
| 546 | tx_info->pending_close = true; | 546 | tx_info->pending_close = true; |
| 547 | /* free the lock after the cleanup */ | 547 | else |
| 548 | spin_unlock_bh(&tx_info->lock); | ||
| 549 | /* if in pending close, free the lock after the cleanup */ | ||
| 548 | goto put_module; | 550 | goto put_module; |
| 549 | } | 551 | } |
| 550 | spin_unlock_bh(&tx_info->lock); | 552 | spin_unlock_bh(&tx_info->lock); |
| @@ -4,6 +4,8 @@ config FSL_DPAA2_ETH · 3 unmodified lines | |||
| 4 | depends on FSL_MC_BUS && FSL_MC_DPIO | 4 | depends on FSL_MC_BUS && FSL_MC_DPIO |
| 5 | select PHYLINK | 5 | select PHYLINK |
| 6 | select PCS_LYNX | 6 | select PCS_LYNX |
| 7 | select FSL_XGMAC_MDIO | ||
| 8 | select NET_DEVLINK | ||
| 7 | help | 9 | help |
| 8 | This is the DPAA2 Ethernet driver supporting Freescale SoCs | 10 | This is the DPAA2 Ethernet driver supporting Freescale SoCs |
| 9 | with DPAA2 (DataPath Acceleration Architecture v2). | 11 | with DPAA2 (DataPath Acceleration Architecture v2). |
| @@ -92,18 +92,8 @@ static int enetc_setup_taprio(struct net_device *ndev, · 91 unmodified lines | |||
| 92 | gcl_config->atc = 0xff; | 92 | gcl_config->atc = 0xff; |
| 93 | gcl_config->acl_len = cpu_to_le16(gcl_len); | 93 | gcl_config->acl_len = cpu_to_le16(gcl_len); |
| 94 | 94 | ||
| 95 | if (!admin_conf->base_time) { | 95 | gcl_data->btl = cpu_to_le32(lower_32_bits(admin_conf->base_time)); |
| 96 | gcl_data->btl = | 96 | gcl_data->bth = cpu_to_le32(upper_32_bits(admin_conf->base_time)); |
| 97 | cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR0)); | ||
| 98 | gcl_data->bth = | ||
| 99 | cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR1)); | ||
| 100 | } else { | ||
| 101 | gcl_data->btl = | ||
| 102 | cpu_to_le32(lower_32_bits(admin_conf->base_time)); | ||
| 103 | gcl_data->bth = | ||
| 104 | cpu_to_le32(upper_32_bits(admin_conf->base_time)); | ||
| 105 | } | ||
| 106 | |||
| 107 | gcl_data->ct = cpu_to_le32(admin_conf->cycle_time); | 97 | gcl_data->ct = cpu_to_le32(admin_conf->cycle_time); |
| 108 | gcl_data->cte = cpu_to_le32(admin_conf->cycle_time_extension); | 98 | gcl_data->cte = cpu_to_le32(admin_conf->cycle_time_extension); |
| 109 | 99 | ||
| @@ -2156,8 +2156,11 @@ static int do_reset(struct ibmvnic_adapter *adapter, · 2155 unmodified lines | |||
| 2156 | for (i = 0; i < adapter->req_rx_queues; i++) | 2156 | for (i = 0; i < adapter->req_rx_queues; i++) |
| 2157 | napi_schedule(&adapter->napi[i]); | 2157 | napi_schedule(&adapter->napi[i]); |
| 2158 | 2158 | ||
| 2159 | if (adapter->reset_reason != VNIC_RESET_FAILOVER) | 2159 | if (adapter->reset_reason == VNIC_RESET_FAILOVER || |
| 2160 | adapter->reset_reason == VNIC_RESET_MOBILITY) { | ||
| 2160 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); | 2161 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); |
| 2162 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev); | ||
| 2163 | } | ||
| 2161 | 2164 | ||
| 2162 | rc = 0; | 2165 | rc = 0; |
| 2163 | 2166 | ||
| @@ -2227,6 +2230,9 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter, · 63 unmodified lines | |||
| 2227 | if (rc) | 2230 | if (rc) |
| 2228 | return IBMVNIC_OPEN_FAILED; | 2231 | return IBMVNIC_OPEN_FAILED; |
| 2229 | 2232 | ||
| 2233 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); | ||
| 2234 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev); | ||
| 2235 | |||
| 2230 | return 0; | 2236 | return 0; |
| 2231 | } | 2237 | } |
| 2232 | 2238 | ||
| @@ -2291,7 +2297,6 @@ static void __ibmvnic_reset(struct work_struct *work) · 58 unmodified lines | |||
| 2291 | 2297 | ||
| 2292 | if (!saved_state) { | 2298 | if (!saved_state) { |
| 2293 | reset_state = adapter->state; | 2299 | reset_state = adapter->state; |
| 2294 | adapter->state = VNIC_RESETTING; | ||
| 2295 | saved_state = true; | 2300 | saved_state = true; |
| 2296 | } | 2301 | } |
| 2297 | spin_unlock_irqrestore(&adapter->state_lock, flags); | 2302 | spin_unlock_irqrestore(&adapter->state_lock, flags); |
| @@ -2432,6 +2437,12 @@ static void ibmvnic_tx_timeout(struct net_device *dev, unsigned int txqueue) · 134 unmodified lines | |||
| 2432 | { | 2437 | { |
| 2433 | struct ibmvnic_adapter *adapter = netdev_priv(dev); | 2438 | struct ibmvnic_adapter *adapter = netdev_priv(dev); |
| 2434 | 2439 | ||
| 2440 | if (test_bit(0, &adapter->resetting)) { | ||
| 2441 | netdev_err(adapter->netdev, | ||
| 2442 | "Adapter is resetting, skip timeout reset\n"); | ||
| 2443 | return; | ||
| 2444 | } | ||
| 2445 | |||
| 2435 | ibmvnic_reset(adapter, VNIC_RESET_TIMEOUT); | 2446 | ibmvnic_reset(adapter, VNIC_RESET_TIMEOUT); |
| 2436 | } | 2447 | } |
| 2437 | 2448 | ||
| @@ -2963,6 +2974,9 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter) · 525 unmodified lines | |||
| 2963 | { | 2974 | { |
| 2964 | int i, rc; | 2975 | int i, rc; |
| 2965 | 2976 | ||
| 2977 | if (!adapter->tx_scrq || !adapter->rx_scrq) | ||
| 2978 | return -EINVAL; | ||
| 2979 | |||
| 2966 | for (i = 0; i < adapter->req_tx_queues; i++) { | 2980 | for (i = 0; i < adapter->req_tx_queues; i++) { |
| 2967 | netdev_dbg(adapter->netdev, "Re-setting tx_scrq[%d]\n", i); | 2981 | netdev_dbg(adapter->netdev, "Re-setting tx_scrq[%d]\n", i); |
| 2968 | rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]); | 2982 | rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]); |
| @@ -5044,6 +5058,9 @@ static int ibmvnic_reset_crq(struct ibmvnic_adapter *adapter) · 2075 unmodified lines | |||
| 5044 | } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); | 5058 | } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); |
| 5045 | 5059 | ||
| 5046 | /* Clean out the queue */ | 5060 | /* Clean out the queue */ |
| 5061 | if (!crq->msgs) | ||
| 5062 | return -EINVAL; | ||
| 5063 | |||
| 5047 | memset(crq->msgs, 0, PAGE_SIZE); | 5064 | memset(crq->msgs, 0, PAGE_SIZE); |
| 5048 | crq->cur = 0; | 5065 | crq->cur = 0; |
| 5049 | crq->active = false; | 5066 | crq->active = false; |
| @@ -5348,7 +5365,7 @@ static int ibmvnic_remove(struct vio_dev *dev) · 298 unmodified lines | |||
| 5348 | unsigned long flags; | 5365 | unsigned long flags; |
| 5349 | 5366 | ||
| 5350 | spin_lock_irqsave(&adapter->state_lock, flags); | 5367 | spin_lock_irqsave(&adapter->state_lock, flags); |
| 5351 | if (adapter->state == VNIC_RESETTING) { | 5368 | if (test_bit(0, &adapter->resetting)) { |
| 5352 | spin_unlock_irqrestore(&adapter->state_lock, flags); | 5369 | spin_unlock_irqrestore(&adapter->state_lock, flags); |
| 5353 | return -EBUSY; | 5370 | return -EBUSY; |
| 5354 | } | 5371 | } |
| @@ -943,8 +943,7 @@ enum vnic_state {VNIC_PROBING = 1, · 942 unmodified lines | |||
| 943 | VNIC_CLOSING, | 943 | VNIC_CLOSING, |
| 944 | VNIC_CLOSED, | 944 | VNIC_CLOSED, |
| 945 | VNIC_REMOVING, | 945 | VNIC_REMOVING, |
| 946 | VNIC_REMOVED, | 946 | VNIC_REMOVED}; |
| 947 | VNIC_RESETTING}; | ||
| 948 | 947 | ||
| 949 | enum ibmvnic_reset_reason {VNIC_RESET_FAILOVER = 1, | 948 | enum ibmvnic_reset_reason {VNIC_RESET_FAILOVER = 1, |
| 950 | VNIC_RESET_MOBILITY, | 949 | VNIC_RESET_MOBILITY, |
| @@ -140,6 +140,7 @@ enum i40e_state_t { · 139 unmodified lines | |||
| 140 | __I40E_CLIENT_RESET, | 140 | __I40E_CLIENT_RESET, |
| 141 | __I40E_VIRTCHNL_OP_PENDING, | 141 | __I40E_VIRTCHNL_OP_PENDING, |
| 142 | __I40E_RECOVERY_MODE, | 142 | __I40E_RECOVERY_MODE, |
| 143 | __I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */ | ||
| 143 | /* This must be last as it determines the size of the BITMAP */ | 144 | /* This must be last as it determines the size of the BITMAP */ |
| 144 | __I40E_STATE_SIZE__, | 145 | __I40E_STATE_SIZE__, |
| 145 | }; | 146 | }; |
| @@ -4010,8 +4010,16 @@ static irqreturn_t i40e_intr(int irq, void *data) · 4009 unmodified lines | |||
| 4010 | } | 4010 | } |
| 4011 | 4011 | ||
| 4012 | if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { | 4012 | if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { |
| 4013 | ena_mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; | 4013 | /* disable any further VFLR event notifications */ |
| 4014 | set_bit(__I40E_VFLR_EVENT_PENDING, pf->state); | 4014 | if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state)) { |
| 4015 | u32 reg = rd32(hw, I40E_PFINT_ICR0_ENA); | ||
| 4016 | |||
| 4017 | reg &= ~I40E_PFINT_ICR0_VFLR_MASK; | ||
| 4018 | wr32(hw, I40E_PFINT_ICR0_ENA, reg); | ||
| 4019 | } else { | ||
| 4020 | ena_mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; | ||
| 4021 | set_bit(__I40E_VFLR_EVENT_PENDING, pf->state); | ||
| 4022 | } | ||
| 4015 | } | 4023 | } |
| 4016 | 4024 | ||
| 4017 | if (icr0 & I40E_PFINT_ICR0_GRST_MASK) { | 4025 | if (icr0 & I40E_PFINT_ICR0_GRST_MASK) { |
| @@ -15311,6 +15319,11 @@ static void i40e_remove(struct pci_dev *pdev) · 11293 unmodified lines | |||
| 15311 | while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state)) | 15319 | while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state)) |
| 15312 | usleep_range(1000, 2000); | 15320 | usleep_range(1000, 2000); |
| 15313 | 15321 | ||
| 15322 | if (pf->flags & I40E_FLAG_SRIOV_ENABLED) { | ||
| 15323 | set_bit(__I40E_VF_RESETS_DISABLED, pf->state); | ||
| 15324 | i40e_free_vfs(pf); | ||
| 15325 | pf->flags &= ~I40E_FLAG_SRIOV_ENABLED; | ||
| 15326 | } | ||
| 15314 | /* no more scheduling of any task */ | 15327 | /* no more scheduling of any task */ |
| 15315 | set_bit(__I40E_SUSPENDED, pf->state); | 15328 | set_bit(__I40E_SUSPENDED, pf->state); |
| 15316 | set_bit(__I40E_DOWN, pf->state); | 15329 | set_bit(__I40E_DOWN, pf->state); |
| @@ -15337,11 +15350,6 @@ static void i40e_remove(struct pci_dev *pdev) · 20 unmodified lines | |||
| 15337 | */ | 15350 | */ |
| 15338 | i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false); | 15351 | i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false); |
| 15339 | 15352 | ||
| 15340 | if (pf->flags & I40E_FLAG_SRIOV_ENABLED) { | ||
| 15341 | i40e_free_vfs(pf); | ||
| 15342 | pf->flags &= ~I40E_FLAG_SRIOV_ENABLED; | ||
| 15343 | } | ||
| 15344 | |||
| 15345 | i40e_fdir_teardown(pf); | 15353 | i40e_fdir_teardown(pf); |
| 15346 | 15354 | ||
| 15347 | /* If there is a switch structure or any orphans, remove them. | 15355 | /* If there is a switch structure or any orphans, remove them. |
| @@ -1403,7 +1403,8 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf) · 1402 unmodified lines | |||
| 1403 | * @vf: pointer to the VF structure | 1403 | * @vf: pointer to the VF structure |
| 1404 | * @flr: VFLR was issued or not | 1404 | * @flr: VFLR was issued or not |
| 1405 | * | 1405 | * |
| 1406 | * Returns true if the VF is reset, false otherwise. | 1406 | * Returns true if the VF is in reset, resets successfully, or resets |
| 1407 | * are disabled and false otherwise. | ||
| 1407 | **/ | 1408 | **/ |
| 1408 | bool i40e_reset_vf(struct i40e_vf *vf, bool flr) | 1409 | bool i40e_reset_vf(struct i40e_vf *vf, bool flr) |
| 1409 | { | 1410 | { |
| @@ -1413,11 +1414,14 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr) · 3 unmodified lines | |||
| 1413 | u32 reg; | 1414 | u32 reg; |
| 1414 | int i; | 1415 | int i; |
| 1415 | 1416 | ||
| 1417 | if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state)) | ||
| 1418 | return true; | ||
| 1419 | |||
| 1416 | /* If the VFs have been disabled, this means something else is | 1420 | /* If the VFs have been disabled, this means something else is |
| 1417 | * resetting the VF, so we shouldn't continue. | 1421 | * resetting the VF, so we shouldn't continue. |
| 1418 | */ | 1422 | */ |
| 1419 | if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) | 1423 | if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) |
| 1420 | return false; | 1424 | return true; |
| 1421 | 1425 | ||
| 1422 | i40e_trigger_vf_reset(vf, flr); | 1426 | i40e_trigger_vf_reset(vf, flr); |
| 1423 | 1427 | ||
| @@ -1581,6 +1585,15 @@ void i40e_free_vfs(struct i40e_pf *pf) · 157 unmodified lines | |||
| 1581 | 1585 | ||
| 1582 | i40e_notify_client_of_vf_enable(pf, 0); | 1586 | i40e_notify_client_of_vf_enable(pf, 0); |
| 1583 | 1587 | ||
| 1588 | /* Disable IOV before freeing resources. This lets any VF drivers | ||
| 1589 | * running in the host get themselves cleaned up before we yank | ||
| 1590 | * the carpet out from underneath their feet. | ||
| 1591 | */ | ||
| 1592 | if (!pci_vfs_assigned(pf->pdev)) | ||
| 1593 | pci_disable_sriov(pf->pdev); | ||
| 1594 | else | ||
| 1595 | dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n"); | ||
| 1596 | |||
| 1584 | /* Amortize wait time by stopping all VFs at the same time */ | 1597 | /* Amortize wait time by stopping all VFs at the same time */ |
| 1585 | for (i = 0; i < pf->num_alloc_vfs; i++) { | 1598 | for (i = 0; i < pf->num_alloc_vfs; i++) { |
| 1586 | if (test_bit(I40E_VF_STATE_INIT, &pf->vf[i].vf_states)) | 1599 | if (test_bit(I40E_VF_STATE_INIT, &pf->vf[i].vf_states)) |
| @@ -1596,15 +1609,6 @@ void i40e_free_vfs(struct i40e_pf *pf) · 9 unmodified lines | |||
| 1596 | i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[i].lan_vsi_idx]); | 1609 | i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[i].lan_vsi_idx]); |
| 1597 | } | 1610 | } |
| 1598 | 1611 | ||
| 1599 | /* Disable IOV before freeing resources. This lets any VF drivers | ||
| 1600 | * running in the host get themselves cleaned up before we yank | ||
| 1601 | * the carpet out from underneath their feet. | ||
| 1602 | */ | ||
| 1603 | if (!pci_vfs_assigned(pf->pdev)) | ||
| 1604 | pci_disable_sriov(pf->pdev); | ||
| 1605 | else | ||
| 1606 | dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n"); | ||
| 1607 | |||
| 1608 | /* free up VF resources */ | 1612 | /* free up VF resources */ |
| 1609 | tmp = pf->num_alloc_vfs; | 1613 | tmp = pf->num_alloc_vfs; |
| 1610 | pf->num_alloc_vfs = 0; | 1614 | pf->num_alloc_vfs = 0; |
| @@ -1193,7 +1193,6 @@ const struct stmmac_ops dwmac4_ops = { · 1192 unmodified lines | |||
| 1193 | .pcs_get_adv_lp = dwmac4_get_adv_lp, | 1193 | .pcs_get_adv_lp = dwmac4_get_adv_lp, |
| 1194 | .debug = dwmac4_debug, | 1194 | .debug = dwmac4_debug, |
| 1195 | .set_filter = dwmac4_set_filter, | 1195 | .set_filter = dwmac4_set_filter, |
| 1196 | .flex_pps_config = dwmac5_flex_pps_config, | ||
| 1197 | .set_mac_loopback = dwmac4_set_mac_loopback, | 1196 | .set_mac_loopback = dwmac4_set_mac_loopback, |
| 1198 | .update_vlan_hash = dwmac4_update_vlan_hash, | 1197 | .update_vlan_hash = dwmac4_update_vlan_hash, |
| 1199 | .sarc_configure = dwmac4_sarc_configure, | 1198 | .sarc_configure = dwmac4_sarc_configure, |
| @@ -1236,6 +1235,7 @@ const struct stmmac_ops dwmac410_ops = { · 36 unmodified lines | |||
| 1236 | .pcs_get_adv_lp = dwmac4_get_adv_lp, | 1235 | .pcs_get_adv_lp = dwmac4_get_adv_lp, |
| 1237 | .debug = dwmac4_debug, | 1236 | .debug = dwmac4_debug, |
| 1238 | .set_filter = dwmac4_set_filter, | 1237 | .set_filter = dwmac4_set_filter, |
| 1238 | .flex_pps_config = dwmac5_flex_pps_config, | ||
| 1239 | .set_mac_loopback = dwmac4_set_mac_loopback, | 1239 | .set_mac_loopback = dwmac4_set_mac_loopback, |
| 1240 | .update_vlan_hash = dwmac4_update_vlan_hash, | 1240 | .update_vlan_hash = dwmac4_update_vlan_hash, |
| 1241 | .sarc_configure = dwmac4_sarc_configure, | 1241 | .sarc_configure = dwmac4_sarc_configure, |
| @@ -1921,12 +1921,15 @@ static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from) · 1920 unmodified lines | |||
| 1921 | struct tun_file *tfile = file->private_data; | 1921 | struct tun_file *tfile = file->private_data; |
| 1922 | struct tun_struct *tun = tun_get(tfile); | 1922 | struct tun_struct *tun = tun_get(tfile); |
| 1923 | ssize_t result; | 1923 | ssize_t result; |
| 1924 | int noblock = 0; | ||
| 1924 | 1925 | ||
| 1925 | if (!tun) | 1926 | if (!tun) |
| 1926 | return -EBADFD; | 1927 | return -EBADFD; |
| 1927 | 1928 | ||
| 1928 | result = tun_get_user(tun, tfile, NULL, from, | 1929 | if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) |
| 1929 | file->f_flags & O_NONBLOCK, false); | 1930 | noblock = 1; |
| 1931 | |||
| 1932 | result = tun_get_user(tun, tfile, NULL, from, noblock, false); | ||
| 1930 | 1933 | ||
| 1931 | tun_put(tun); | 1934 | tun_put(tun); |
| 1932 | return result; | 1935 | return result; |
| @@ -2137,10 +2140,15 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) · 204 unmodified lines | |||
| 2137 | struct tun_file *tfile = file->private_data; | 2140 | struct tun_file *tfile = file->private_data; |
| 2138 | struct tun_struct *tun = tun_get(tfile); | 2141 | struct tun_struct *tun = tun_get(tfile); |
| 2139 | ssize_t len = iov_iter_count(to), ret; | 2142 | ssize_t len = iov_iter_count(to), ret; |
| 2143 | int noblock = 0; | ||
| 2140 | 2144 | ||
| 2141 | if (!tun) | 2145 | if (!tun) |
| 2142 | return -EBADFD; | 2146 | return -EBADFD; |
| 2143 | ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); | 2147 | |
| 2148 | if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) | ||
| 2149 | noblock = 1; | ||
| 2150 | |||
| 2151 | ret = tun_do_read(tun, tfile, to, noblock, NULL); | ||
| 2144 | ret = min_t(ssize_t, ret, len); | 2152 | ret = min_t(ssize_t, ret, len); |
| 2145 | if (ret > 0) | 2153 | if (ret > 0) |
| 2146 | iocb->ki_pos = ret; | 2154 | iocb->ki_pos = ret; |
| @@ -59,7 +59,7 @@ · 58 unmodified lines | |||
| 59 | #define IPHETH_USBINTF_SUBCLASS 253 | 59 | #define IPHETH_USBINTF_SUBCLASS 253 |
| 60 | #define IPHETH_USBINTF_PROTO 1 | 60 | #define IPHETH_USBINTF_PROTO 1 |
| 61 | 61 | ||
| 62 | #define IPHETH_BUF_SIZE 1516 | 62 | #define IPHETH_BUF_SIZE 1514 |
| 63 | #define IPHETH_IP_ALIGN 2 /* padding at front of URB */ | 63 | #define IPHETH_IP_ALIGN 2 /* padding at front of URB */ |
| 64 | #define IPHETH_TX_TIMEOUT (5 * HZ) | 64 | #define IPHETH_TX_TIMEOUT (5 * HZ) |
| 65 | 65 | ||
| @@ -5,10 +5,9 @@ · 4 unmodified lines | |||
| 5 | * | 5 | * |
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | ||
| 9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 8 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 9 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 - 2019 Intel Corporation | 10 | * Copyright(c) 2012-2014, 2018 - 2020 Intel Corporation |
| 12 | * | 11 | * |
| 13 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
| 14 | * it under the terms of version 2 of the GNU General Public License as | 13 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -28,10 +27,9 @@ · 13 unmodified lines | |||
| 28 | * | 27 | * |
| 29 | * BSD LICENSE | 28 | * BSD LICENSE |
| 30 | * | 29 | * |
| 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | ||
| 32 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 30 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
| 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 31 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 34 | * Copyright(c) 2018 - 2019 Intel Corporation | 32 | * Copyright(c) 2012-2014, 2018 - 2020 Intel Corporation |
| 35 | * All rights reserved. | 33 | * All rights reserved. |
| 36 | * | 34 | * |
| 37 | * Redistribution and use in source and binary forms, with or without | 35 | * Redistribution and use in source and binary forms, with or without |
| @@ -128,7 +126,9 @@ enum iwl_sta_flags { · 90 unmodified lines | |||
| 128 | STA_FLG_MAX_AGG_SIZE_256K = (5 << STA_FLG_MAX_AGG_SIZE_SHIFT), | 126 | STA_FLG_MAX_AGG_SIZE_256K = (5 << STA_FLG_MAX_AGG_SIZE_SHIFT), |
| 129 | STA_FLG_MAX_AGG_SIZE_512K = (6 << STA_FLG_MAX_AGG_SIZE_SHIFT), | 127 | STA_FLG_MAX_AGG_SIZE_512K = (6 << STA_FLG_MAX_AGG_SIZE_SHIFT), |
| 130 | STA_FLG_MAX_AGG_SIZE_1024K = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT), | 128 | STA_FLG_MAX_AGG_SIZE_1024K = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT), |
| 131 | STA_FLG_MAX_AGG_SIZE_MSK = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT), | 129 | STA_FLG_MAX_AGG_SIZE_2M = (8 << STA_FLG_MAX_AGG_SIZE_SHIFT), |
| 130 | STA_FLG_MAX_AGG_SIZE_4M = (9 << STA_FLG_MAX_AGG_SIZE_SHIFT), | ||
| 131 | STA_FLG_MAX_AGG_SIZE_MSK = (0xf << STA_FLG_MAX_AGG_SIZE_SHIFT), | ||
| 132 | 132 | ||
| 133 | STA_FLG_AGG_MPDU_DENS_SHIFT = 23, | 133 | STA_FLG_AGG_MPDU_DENS_SHIFT = 23, |
| 134 | STA_FLG_AGG_MPDU_DENS_2US = (4 << STA_FLG_AGG_MPDU_DENS_SHIFT), | 134 | STA_FLG_AGG_MPDU_DENS_2US = (4 << STA_FLG_AGG_MPDU_DENS_SHIFT), |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 - 2019 Intel Corporation | 11 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 12 | * | 12 | * |
| 13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 14 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -31,7 +31,7 @@ · 16 unmodified lines | |||
| 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 34 | * Copyright(c) 2018 - 2019 Intel Corporation | 34 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 35 | * All rights reserved. | 35 | * All rights reserved. |
| 36 | * | 36 | * |
| 37 | * Redistribution and use in source and binary forms, with or without | 37 | * Redistribution and use in source and binary forms, with or without |
| @@ -421,12 +421,14 @@ struct iwl_hs20_roc_res { · 383 unmodified lines | |||
| 421 | * able to run the GO Negotiation. Will not be fragmented and not | 421 | * able to run the GO Negotiation. Will not be fragmented and not |
| 422 | * repetitive. Valid only on the P2P Device MAC. Only the duration will | 422 | * repetitive. Valid only on the P2P Device MAC. Only the duration will |
| 423 | * be taken into account. | 423 | * be taken into account. |
| 424 | * @SESSION_PROTECT_CONF_MAX_ID: not used | ||
| 424 | */ | 425 | */ |
| 425 | enum iwl_mvm_session_prot_conf_id { | 426 | enum iwl_mvm_session_prot_conf_id { |
| 426 | SESSION_PROTECT_CONF_ASSOC, | 427 | SESSION_PROTECT_CONF_ASSOC, |
| 427 | SESSION_PROTECT_CONF_GO_CLIENT_ASSOC, | 428 | SESSION_PROTECT_CONF_GO_CLIENT_ASSOC, |
| 428 | SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV, | 429 | SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV, |
| 429 | SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION, | 430 | SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION, |
| 431 | SESSION_PROTECT_CONF_MAX_ID, | ||
| 430 | }; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */ | 432 | }; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */ |
| 431 | 433 | ||
| 432 | /** | 434 | /** |
| @@ -459,7 +461,7 @@ struct iwl_mvm_session_prot_cmd { · 26 unmodified lines | |||
| 459 | * @mac_id: the mac id for which the session protection started / ended | 461 | * @mac_id: the mac id for which the session protection started / ended |
| 460 | * @status: 1 means success, 0 means failure | 462 | * @status: 1 means success, 0 means failure |
| 461 | * @start: 1 means the session protection started, 0 means it ended | 463 | * @start: 1 means the session protection started, 0 means it ended |
| 462 | * @conf_id: the configuration id of the session that started / eneded | 464 | * @conf_id: see &enum iwl_mvm_session_prot_conf_id |
| 463 | * | 465 | * |
| 464 | * Note that any session protection will always get two notifications: start | 466 | * Note that any session protection will always get two notifications: start |
| 465 | * and end even the firmware could not schedule it. | 467 | * and end even the firmware could not schedule it. |
| @@ -147,6 +147,16 @@ · 146 unmodified lines | |||
| 147 | #define CSR_MAC_SHADOW_REG_CTL2 (CSR_BASE + 0x0AC) | 147 | #define CSR_MAC_SHADOW_REG_CTL2 (CSR_BASE + 0x0AC) |
| 148 | #define CSR_MAC_SHADOW_REG_CTL2_RX_WAKE 0xFFFF | 148 | #define CSR_MAC_SHADOW_REG_CTL2_RX_WAKE 0xFFFF |
| 149 | 149 | ||
| 150 | /* LTR control (since IWL_DEVICE_FAMILY_22000) */ | ||
| 151 | #define CSR_LTR_LONG_VAL_AD (CSR_BASE + 0x0D4) | ||
| 152 | #define CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ 0x80000000 | ||
| 153 | #define CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE 0x1c000000 | ||
| 154 | #define CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL 0x03ff0000 | ||
| 155 | #define CSR_LTR_LONG_VAL_AD_SNOOP_REQ 0x00008000 | ||
| 156 | #define CSR_LTR_LONG_VAL_AD_SNOOP_SCALE 0x00001c00 | ||
| 157 | #define CSR_LTR_LONG_VAL_AD_SNOOP_VAL 0x000003ff | ||
| 158 | #define CSR_LTR_LONG_VAL_AD_SCALE_USEC 2 | ||
| 159 | |||
| 150 | /* GIO Chicken Bits (PCI Express bus link power management) */ | 160 | /* GIO Chicken Bits (PCI Express bus link power management) */ |
| 151 | #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) | 161 | #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) |
| 152 | 162 | ||
| @@ -3080,7 +3080,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, · 3079 unmodified lines | |||
| 3080 | 3080 | ||
| 3081 | /* this would be a mac80211 bug ... but don't crash */ | 3081 | /* this would be a mac80211 bug ... but don't crash */ |
| 3082 | if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) | 3082 | if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) |
| 3083 | return -EINVAL; | 3083 | return test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) ? 0 : -EINVAL; |
| 3084 | 3084 | ||
| 3085 | /* | 3085 | /* |
| 3086 | * If we are in a STA removal flow and in DQA mode: | 3086 | * If we are in a STA removal flow and in DQA mode: |
| @@ -3127,6 +3127,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, · 40 unmodified lines | |||
| 3127 | goto out_unlock; | 3127 | goto out_unlock; |
| 3128 | } | 3128 | } |
| 3129 | 3129 | ||
| 3130 | if (vif->type == NL80211_IFTYPE_STATION) | ||
| 3131 | vif->bss_conf.he_support = sta->he_cap.has_he; | ||
| 3132 | |||
| 3130 | if (sta->tdls && | 3133 | if (sta->tdls && |
| 3131 | (vif->p2p || | 3134 | (vif->p2p || |
| 3132 | iwl_mvm_tdls_sta_count(mvm, NULL) == | 3135 | iwl_mvm_tdls_sta_count(mvm, NULL) == |
| @@ -196,6 +196,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, · 195 unmodified lines | |||
| 196 | mpdu_dens = sta->ht_cap.ampdu_density; | 196 | mpdu_dens = sta->ht_cap.ampdu_density; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | |||
| 199 | if (sta->vht_cap.vht_supported) { | 200 | if (sta->vht_cap.vht_supported) { |
| 200 | agg_size = sta->vht_cap.cap & | 201 | agg_size = sta->vht_cap.cap & |
| 201 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; | 202 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; |
| @@ -205,6 +206,23 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, · 3 unmodified lines | |||
| 205 | agg_size = sta->ht_cap.ampdu_factor; | 206 | agg_size = sta->ht_cap.ampdu_factor; |
| 206 | } | 207 | } |
| 207 | 208 | ||
| 209 | /* D6.0 10.12.2 A-MPDU length limit rules | ||
| 210 | * A STA indicates the maximum length of the A-MPDU preEOF padding | ||
| 211 | * that it can receive in an HE PPDU in the Maximum A-MPDU Length | ||
| 212 | * Exponent field in its HT Capabilities, VHT Capabilities, | ||
| 213 | * and HE 6 GHz Band Capabilities elements (if present) and the | ||
| 214 | * Maximum AMPDU Length Exponent Extension field in its HE | ||
| 215 | * Capabilities element | ||
| 216 | */ | ||
| 217 | if (sta->he_cap.has_he) | ||
| 218 | agg_size += u8_get_bits(sta->he_cap.he_cap_elem.mac_cap_info[3], | ||
| 219 | IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK); | ||
| 220 | |||
| 221 | /* Limit to max A-MPDU supported by FW */ | ||
| 222 | if (agg_size > (STA_FLG_MAX_AGG_SIZE_4M >> STA_FLG_MAX_AGG_SIZE_SHIFT)) | ||
| 223 | agg_size = (STA_FLG_MAX_AGG_SIZE_4M >> | ||
| 224 | STA_FLG_MAX_AGG_SIZE_SHIFT); | ||
| 225 | |||
| 208 | add_sta_cmd.station_flags |= | 226 | add_sta_cmd.station_flags |= |
| 209 | cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT); | 227 | cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT); |
| 210 | add_sta_cmd.station_flags |= | 228 | add_sta_cmd.station_flags |= |
| @@ -641,11 +641,32 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, · 640 unmodified lines | |||
| 641 | } | 641 | } |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm, | ||
| 645 | struct iwl_mvm_vif *mvmvif) | ||
| 646 | { | ||
| 647 | struct iwl_mvm_session_prot_cmd cmd = { | ||
| 648 | .id_and_color = | ||
| 649 | cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | ||
| 650 | mvmvif->color)), | ||
| 651 | .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE), | ||
| 652 | .conf_id = cpu_to_le32(mvmvif->time_event_data.id), | ||
| 653 | }; | ||
| 654 | int ret; | ||
| 655 | |||
| 656 | ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD, | ||
| 657 | MAC_CONF_GROUP, 0), | ||
| 658 | 0, sizeof(cmd), &cmd); | ||
| 659 | if (ret) | ||
| 660 | IWL_ERR(mvm, | ||
| 661 | "Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret); | ||
| 662 | } | ||
| 663 | |||
| 644 | static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, | 664 | static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, |
| 645 | struct iwl_mvm_time_event_data *te_data, | 665 | struct iwl_mvm_time_event_data *te_data, |
| 646 | u32 *uid) | 666 | u32 *uid) |
| 647 | { | 667 | { |
| 648 | u32 id; | 668 | u32 id; |
| 669 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | ||
| 649 | 670 | ||
| 650 | /* | 671 | /* |
| 651 | * It is possible that by the time we got to this point the time | 672 | * It is possible that by the time we got to this point the time |
| @@ -663,14 +684,29 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, · 11 unmodified lines | |||
| 663 | iwl_mvm_te_clear_data(mvm, te_data); | 684 | iwl_mvm_te_clear_data(mvm, te_data); |
| 664 | spin_unlock_bh(&mvm->time_event_lock); | 685 | spin_unlock_bh(&mvm->time_event_lock); |
| 665 | 686 | ||
| 666 | /* | 687 | /* When session protection is supported, the te_data->id field |
| 667 | * It is possible that by the time we try to remove it, the time event | 688 | * is reused to save session protection's configuration. |
| 668 | * has already ended and removed. In such a case there is no need to | ||
| 669 | * send a removal command. | ||
| 670 | */ | 689 | */ |
| 671 | if (id == TE_MAX) { | 690 | if (fw_has_capa(&mvm->fw->ucode_capa, |
| 672 | IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", *uid); | 691 | IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) { |
| 692 | if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) { | ||
| 693 | /* Session protection is still ongoing. Cancel it */ | ||
| 694 | iwl_mvm_cancel_session_protection(mvm, mvmvif); | ||
| 695 | if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { | ||
| 696 | set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status); | ||
| 697 | iwl_mvm_roc_finished(mvm); | ||
| 698 | } | ||
| 699 | } | ||
| 673 | return false; | 700 | return false; |
| 701 | } else { | ||
| 702 | /* It is possible that by the time we try to remove it, the | ||
| 703 | * time event has already ended and removed. In such a case | ||
| 704 | * there is no need to send a removal command. | ||
| 705 | */ | ||
| 706 | if (id == TE_MAX) { | ||
| 707 | IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", *uid); | ||
| 708 | return false; | ||
| 709 | } | ||
| 674 | } | 710 | } |
| 675 | 711 | ||
| 676 | return true; | 712 | return true; |
| @@ -771,6 +807,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, · 94 unmodified lines | |||
| 771 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 807 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 772 | struct iwl_mvm_session_prot_notif *notif = (void *)pkt->data; | 808 | struct iwl_mvm_session_prot_notif *notif = (void *)pkt->data; |
| 773 | struct ieee80211_vif *vif; | 809 | struct ieee80211_vif *vif; |
| 810 | struct iwl_mvm_vif *mvmvif; | ||
| 774 | 811 | ||
| 775 | rcu_read_lock(); | 812 | rcu_read_lock(); |
| 776 | vif = iwl_mvm_rcu_dereference_vif_id(mvm, le32_to_cpu(notif->mac_id), | 813 | vif = iwl_mvm_rcu_dereference_vif_id(mvm, le32_to_cpu(notif->mac_id), |
| @@ -779,9 +816,10 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, · 2 unmodified lines | |||
| 779 | if (!vif) | 816 | if (!vif) |
| 780 | goto out_unlock; | 817 | goto out_unlock; |
| 781 | 818 | ||
| 819 | mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 820 | |||
| 782 | /* The vif is not a P2P_DEVICE, maintain its time_event_data */ | 821 | /* The vif is not a P2P_DEVICE, maintain its time_event_data */ |
| 783 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) { | 822 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) { |
| 784 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 785 | struct iwl_mvm_time_event_data *te_data = | 823 | struct iwl_mvm_time_event_data *te_data = |
| 786 | &mvmvif->time_event_data; | 824 | &mvmvif->time_event_data; |
| 787 | 825 | ||
| @@ -816,10 +854,14 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, · 28 unmodified lines | |||
| 816 | 854 | ||
| 817 | if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) { | 855 | if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) { |
| 818 | /* End TE, notify mac80211 */ | 856 | /* End TE, notify mac80211 */ |
| 857 | mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID; | ||
| 819 | ieee80211_remain_on_channel_expired(mvm->hw); | 858 | ieee80211_remain_on_channel_expired(mvm->hw); |
| 820 | set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status); | 859 | set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status); |
| 821 | iwl_mvm_roc_finished(mvm); | 860 | iwl_mvm_roc_finished(mvm); |
| 822 | } else if (le32_to_cpu(notif->start)) { | 861 | } else if (le32_to_cpu(notif->start)) { |
| 862 | if (WARN_ON(mvmvif->time_event_data.id != | ||
| 863 | le32_to_cpu(notif->conf_id))) | ||
| 864 | goto out_unlock; | ||
| 823 | set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); | 865 | set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); |
| 824 | ieee80211_ready_on_channel(mvm->hw); /* Start TE */ | 866 | ieee80211_ready_on_channel(mvm->hw); /* Start TE */ |
| 825 | } | 867 | } |
| @@ -845,20 +887,24 @@ iwl_mvm_start_p2p_roc_session_protection(struct iwl_mvm *mvm, · 19 unmodified lines | |||
| 845 | 887 | ||
| 846 | lockdep_assert_held(&mvm->mutex); | 888 | lockdep_assert_held(&mvm->mutex); |
| 847 | 889 | ||
| 890 | /* The time_event_data.id field is reused to save session | ||
| 891 | * protection's configuration. | ||
| 892 | */ | ||
| 848 | switch (type) { | 893 | switch (type) { |
| 849 | case IEEE80211_ROC_TYPE_NORMAL: | 894 | case IEEE80211_ROC_TYPE_NORMAL: |
| 850 | cmd.conf_id = | 895 | mvmvif->time_event_data.id = |
| 851 | cpu_to_le32(SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV); | 896 | SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV; |
| 852 | break; | 897 | break; |
| 853 | case IEEE80211_ROC_TYPE_MGMT_TX: | 898 | case IEEE80211_ROC_TYPE_MGMT_TX: |
| 854 | cmd.conf_id = | 899 | mvmvif->time_event_data.id = |
| 855 | cpu_to_le32(SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION); | 900 | SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION; |
| 856 | break; | 901 | break; |
| 857 | default: | 902 | default: |
| 858 | WARN_ONCE(1, "Got an invalid ROC type\n"); | 903 | WARN_ONCE(1, "Got an invalid ROC type\n"); |
| 859 | return -EINVAL; | 904 | return -EINVAL; |
| 860 | } | 905 | } |
| 861 | 906 | ||
| 907 | cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id); | ||
| 862 | return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD, | 908 | return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD, |
| 863 | MAC_CONF_GROUP, 0), | 909 | MAC_CONF_GROUP, 0), |
| 864 | 0, sizeof(cmd), &cmd); | 910 | 0, sizeof(cmd), &cmd); |
| @@ -960,25 +1006,6 @@ void iwl_mvm_cleanup_roc_te(struct iwl_mvm *mvm) · 95 unmodified lines | |||
| 960 | __iwl_mvm_remove_time_event(mvm, te_data, &uid); | 1006 | __iwl_mvm_remove_time_event(mvm, te_data, &uid); |
| 961 | } | 1007 | } |
| 962 | 1008 | ||
| 963 | static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm, | ||
| 964 | struct iwl_mvm_vif *mvmvif) | ||
| 965 | { | ||
| 966 | struct iwl_mvm_session_prot_cmd cmd = { | ||
| 967 | .id_and_color = | ||
| 968 | cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | ||
| 969 | mvmvif->color)), | ||
| 970 | .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE), | ||
| 971 | }; | ||
| 972 | int ret; | ||
| 973 | |||
| 974 | ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD, | ||
| 975 | MAC_CONF_GROUP, 0), | ||
| 976 | 0, sizeof(cmd), &cmd); | ||
| 977 | if (ret) | ||
| 978 | IWL_ERR(mvm, | ||
| 979 | "Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret); | ||
| 980 | } | ||
| 981 | |||
| 982 | void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 1009 | void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
| 983 | { | 1010 | { |
| 984 | struct iwl_mvm_vif *mvmvif; | 1011 | struct iwl_mvm_vif *mvmvif; |
| @@ -988,10 +1015,13 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) · 3 unmodified lines | |||
| 988 | IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) { | 1015 | IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) { |
| 989 | mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1016 | mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 990 | 1017 | ||
| 991 | iwl_mvm_cancel_session_protection(mvm, mvmvif); | 1018 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
| 992 | 1019 | iwl_mvm_cancel_session_protection(mvm, mvmvif); | |
| 993 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) | ||
| 994 | set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status); | 1020 | set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status); |
| 1021 | } else { | ||
| 1022 | iwl_mvm_remove_aux_roc_te(mvm, mvmvif, | ||
| 1023 | &mvmvif->time_event_data); | ||
| 1024 | } | ||
| 995 | 1025 | ||
| 996 | iwl_mvm_roc_finished(mvm); | 1026 | iwl_mvm_roc_finished(mvm); |
| 997 | 1027 | ||
| @@ -1126,10 +1156,15 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, · 128 unmodified lines | |||
| 1126 | cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 1156 | cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, |
| 1127 | mvmvif->color)), | 1157 | mvmvif->color)), |
| 1128 | .action = cpu_to_le32(FW_CTXT_ACTION_ADD), | 1158 | .action = cpu_to_le32(FW_CTXT_ACTION_ADD), |
| 1129 | .conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC), | ||
| 1130 | .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)), | 1159 | .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)), |
| 1131 | }; | 1160 | }; |
| 1132 | 1161 | ||
| 1162 | /* The time_event_data.id field is reused to save session | ||
| 1163 | * protection's configuration. | ||
| 1164 | */ | ||
| 1165 | mvmvif->time_event_data.id = SESSION_PROTECT_CONF_ASSOC; | ||
| 1166 | cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id); | ||
| 1167 | |||
| 1133 | lockdep_assert_held(&mvm->mutex); | 1168 | lockdep_assert_held(&mvm->mutex); |
| 1134 | 1169 | ||
| 1135 | spin_lock_bh(&mvm->time_event_lock); | 1170 | spin_lock_bh(&mvm->time_event_lock); |
| @@ -252,6 +252,26 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, · 251 unmodified lines | |||
| 252 | 252 | ||
| 253 | iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, | 253 | iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, |
| 254 | CSR_AUTO_FUNC_BOOT_ENA); | 254 | CSR_AUTO_FUNC_BOOT_ENA); |
| 255 | |||
| 256 | if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { | ||
| 257 | /* | ||
| 258 | * The firmware initializes this again later (to a smaller | ||
| 259 | * value), but for the boot process initialize the LTR to | ||
| 260 | * ~250 usec. | ||
| 261 | */ | ||
| 262 | u32 val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | | ||
| 263 | u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, | ||
| 264 | CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | | ||
| 265 | u32_encode_bits(250, | ||
| 266 | CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | | ||
| 267 | CSR_LTR_LONG_VAL_AD_SNOOP_REQ | | ||
| 268 | u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, | ||
| 269 | CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | | ||
| 270 | u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL); | ||
| 271 | |||
| 272 | iwl_write32(trans, CSR_LTR_LONG_VAL_AD, val); | ||
| 273 | } | ||
| 274 | |||
| 255 | if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) | 275 | if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) |
| 256 | iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); | 276 | iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); |
| 257 | else | 277 | else |
| @@ -2156,18 +2156,36 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, · 2155 unmodified lines | |||
| 2156 | void *buf, int dwords) | 2156 | void *buf, int dwords) |
| 2157 | { | 2157 | { |
| 2158 | unsigned long flags; | 2158 | unsigned long flags; |
| 2159 | int offs, ret = 0; | 2159 | int offs = 0; |
| 2160 | u32 *vals = buf; | 2160 | u32 *vals = buf; |
| 2161 | 2161 | ||
| 2162 | if (iwl_trans_grab_nic_access(trans, &flags)) { | 2162 | while (offs < dwords) { |
| 2163 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | 2163 | /* limit the time we spin here under lock to 1/2s */ |
| 2164 | for (offs = 0; offs < dwords; offs++) | 2164 | ktime_t timeout = ktime_add_us(ktime_get(), 500 * USEC_PER_MSEC); |
| 2165 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 2165 | |
| 2166 | iwl_trans_release_nic_access(trans, &flags); | 2166 | if (iwl_trans_grab_nic_access(trans, &flags)) { |
| 2167 | } else { | 2167 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, |
| 2168 | ret = -EBUSY; | 2168 | addr + 4 * offs); |
| 2169 | |||
| 2170 | while (offs < dwords) { | ||
| 2171 | vals[offs] = iwl_read32(trans, | ||
| 2172 | HBUS_TARG_MEM_RDAT); | ||
| 2173 | offs++; | ||
| 2174 | |||
| 2175 | /* calling ktime_get is expensive so | ||
| 2176 | * do it once in 128 reads | ||
| 2177 | */ | ||
| 2178 | if (offs % 128 == 0 && ktime_after(ktime_get(), | ||
| 2179 | timeout)) | ||
| 2180 | break; | ||
| 2181 | } | ||
| 2182 | iwl_trans_release_nic_access(trans, &flags); | ||
| 2183 | } else { | ||
| 2184 | return -EBUSY; | ||
| 2185 | } | ||
| 2169 | } | 2186 | } |
| 2170 | return ret; | 2187 | |
| 2188 | return 0; | ||
| 2171 | } | 2189 | } |
| 2172 | 2190 | ||
| 2173 | static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, | 2191 | static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, |
| @@ -1482,7 +1482,7 @@ static bool rtw_fw_dump_check_size(struct rtw_dev *rtwdev, · 1481 unmodified lines | |||
| 1482 | int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, | 1482 | int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size, |
| 1483 | u32 *buffer) | 1483 | u32 *buffer) |
| 1484 | { | 1484 | { |
| 1485 | if (!rtwdev->chip->fw_fifo_addr) { | 1485 | if (!rtwdev->chip->fw_fifo_addr[0]) { |
| 1486 | rtw_dbg(rtwdev, RTW_DBG_FW, "chip not support dump fw fifo\n"); | 1486 | rtw_dbg(rtwdev, RTW_DBG_FW, "chip not support dump fw fifo\n"); |
| 1487 | return -ENOTSUPP; | 1487 | return -ENOTSUPP; |
| 1488 | } | 1488 | } |
| @@ -25,8 +25,8 @@ struct s3fwrn5_i2c_phy { · 24 unmodified lines | |||
| 25 | struct i2c_client *i2c_dev; | 25 | struct i2c_client *i2c_dev; |
| 26 | struct nci_dev *ndev; | 26 | struct nci_dev *ndev; |
| 27 | 27 | ||
| 28 | unsigned int gpio_en; | 28 | int gpio_en; |
| 29 | unsigned int gpio_fw_wake; | 29 | int gpio_fw_wake; |
| 30 | 30 | ||
| 31 | struct mutex mutex; | 31 | struct mutex mutex; |
| 32 | 32 | ||
| @@ -2929,7 +2929,7 @@ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, · 2928 unmodified lines | |||
| 2929 | static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, | 2929 | static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, |
| 2930 | struct nvme_effects_log **log) | 2930 | struct nvme_effects_log **log) |
| 2931 | { | 2931 | { |
| 2932 | struct nvme_cel *cel = xa_load(&ctrl->cels, csi); | 2932 | struct nvme_effects_log *cel = xa_load(&ctrl->cels, csi); |
| 2933 | int ret; | 2933 | int ret; |
| 2934 | 2934 | ||
| 2935 | if (cel) | 2935 | if (cel) |
| @@ -2940,16 +2940,15 @@ static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, · 4 unmodified lines | |||
| 2940 | return -ENOMEM; | 2940 | return -ENOMEM; |
| 2941 | 2941 | ||
| 2942 | ret = nvme_get_log(ctrl, 0x00, NVME_LOG_CMD_EFFECTS, 0, csi, | 2942 | ret = nvme_get_log(ctrl, 0x00, NVME_LOG_CMD_EFFECTS, 0, csi, |
| 2943 | &cel->log, sizeof(cel->log), 0); | 2943 | cel, sizeof(*cel), 0); |
| 2944 | if (ret) { | 2944 | if (ret) { |
| 2945 | kfree(cel); | 2945 | kfree(cel); |
| 2946 | return ret; | 2946 | return ret; |
| 2947 | } | 2947 | } |
| 2948 | 2948 | ||
| 2949 | cel->csi = csi; | 2949 | xa_store(&ctrl->cels, csi, cel, GFP_KERNEL); |
| 2950 | xa_store(&ctrl->cels, cel->csi, cel, GFP_KERNEL); | ||
| 2951 | out: | 2950 | out: |
| 2952 | *log = &cel->log; | 2951 | *log = cel; |
| 2953 | return 0; | 2952 | return 0; |
| 2954 | } | 2953 | } |
| 2955 | 2954 | ||
| @@ -4374,6 +4373,19 @@ void nvme_uninit_ctrl(struct nvme_ctrl *ctrl) · 1418 unmodified lines | |||
| 4374 | } | 4373 | } |
| 4375 | EXPORT_SYMBOL_GPL(nvme_uninit_ctrl); | 4374 | EXPORT_SYMBOL_GPL(nvme_uninit_ctrl); |
| 4376 | 4375 | ||
| 4376 | static void nvme_free_cels(struct nvme_ctrl *ctrl) | ||
| 4377 | { | ||
| 4378 | struct nvme_effects_log *cel; | ||
| 4379 | unsigned long i; | ||
| 4380 | |||
| 4381 | xa_for_each (&ctrl->cels, i, cel) { | ||
| 4382 | xa_erase(&ctrl->cels, i); | ||
| 4383 | kfree(cel); | ||
| 4384 | } | ||
| 4385 | |||
| 4386 | xa_destroy(&ctrl->cels); | ||
| 4387 | } | ||
| 4388 | |||
| 4377 | static void nvme_free_ctrl(struct device *dev) | 4389 | static void nvme_free_ctrl(struct device *dev) |
| 4378 | { | 4390 | { |
| 4379 | struct nvme_ctrl *ctrl = | 4391 | struct nvme_ctrl *ctrl = |
| @@ -4383,8 +4395,7 @@ static void nvme_free_ctrl(struct device *dev) · 3 unmodified lines | |||
| 4383 | if (!subsys || ctrl->instance != subsys->instance) | 4395 | if (!subsys || ctrl->instance != subsys->instance) |
| 4384 | ida_simple_remove(&nvme_instance_ida, ctrl->instance); | 4396 | ida_simple_remove(&nvme_instance_ida, ctrl->instance); |
| 4385 | 4397 | ||
| 4386 | xa_destroy(&ctrl->cels); | 4398 | nvme_free_cels(ctrl); |
| 4387 | |||
| 4388 | nvme_mpath_uninit(ctrl); | 4399 | nvme_mpath_uninit(ctrl); |
| 4389 | __free_page(ctrl->discard_page); | 4400 | __free_page(ctrl->discard_page); |
| 4390 | 4401 | ||
| @@ -226,12 +226,6 @@ struct nvme_fault_inject { · 225 unmodified lines | |||
| 226 | #endif | 226 | #endif |
| 227 | }; | 227 | }; |
| 228 | 228 | ||
| 229 | struct nvme_cel { | ||
| 230 | struct list_head entry; | ||
| 231 | struct nvme_effects_log log; | ||
| 232 | u8 csi; | ||
| 233 | }; | ||
| 234 | |||
| 235 | struct nvme_ctrl { | 229 | struct nvme_ctrl { |
| 236 | bool comp_seen; | 230 | bool comp_seen; |
| 237 | enum nvme_ctrl_state state; | 231 | enum nvme_ctrl_state state; |
| @@ -292,9 +292,21 @@ static void nvme_dbbuf_init(struct nvme_dev *dev, · 291 unmodified lines | |||
| 292 | nvmeq->dbbuf_cq_ei = &dev->dbbuf_eis[cq_idx(qid, dev->db_stride)]; | 292 | nvmeq->dbbuf_cq_ei = &dev->dbbuf_eis[cq_idx(qid, dev->db_stride)]; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | static void nvme_dbbuf_free(struct nvme_queue *nvmeq) | ||
| 296 | { | ||
| 297 | if (!nvmeq->qid) | ||
| 298 | return; | ||
| 299 | |||
| 300 | nvmeq->dbbuf_sq_db = NULL; | ||
| 301 | nvmeq->dbbuf_cq_db = NULL; | ||
| 302 | nvmeq->dbbuf_sq_ei = NULL; | ||
| 303 | nvmeq->dbbuf_cq_ei = NULL; | ||
| 304 | } | ||
| 305 | |||
| 295 | static void nvme_dbbuf_set(struct nvme_dev *dev) | 306 | static void nvme_dbbuf_set(struct nvme_dev *dev) |
| 296 | { | 307 | { |
| 297 | struct nvme_command c; | 308 | struct nvme_command c; |
| 309 | unsigned int i; | ||
| 298 | 310 | ||
| 299 | if (!dev->dbbuf_dbs) | 311 | if (!dev->dbbuf_dbs) |
| 300 | return; | 312 | return; |
| @@ -308,6 +320,9 @@ static void nvme_dbbuf_set(struct nvme_dev *dev) · 7 unmodified lines | |||
| 308 | dev_warn(dev->ctrl.device, "unable to set dbbuf\n"); | 320 | dev_warn(dev->ctrl.device, "unable to set dbbuf\n"); |
| 309 | /* Free memory and continue on */ | 321 | /* Free memory and continue on */ |
| 310 | nvme_dbbuf_dma_free(dev); | 322 | nvme_dbbuf_dma_free(dev); |
| 323 | |||
| 324 | for (i = 1; i <= dev->online_queues; i++) | ||
| 325 | nvme_dbbuf_free(&dev->queues[i]); | ||
| 311 | } | 326 | } |
| 312 | } | 327 | } |
| 313 | 328 | ||
| @@ -111,6 +111,7 @@ static const struct key_entry acer_wmi_keymap[] __initconst = { · 110 unmodified lines | |||
| 111 | {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ | 111 | {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ |
| 112 | {KE_IGNORE, 0x81, {KEY_SLEEP} }, | 112 | {KE_IGNORE, 0x81, {KEY_SLEEP} }, |
| 113 | {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ | 113 | {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ |
| 114 | {KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */ | ||
| 114 | {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, | 115 | {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, |
| 115 | {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, | 116 | {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, |
| 116 | {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, | 117 | {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, |
| @@ -206,6 +206,12 @@ static const struct dmi_system_id dmi_switches_allow_list[] = { · 205 unmodified lines | |||
| 206 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Stream x360 Convertible PC 11"), | 206 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Stream x360 Convertible PC 11"), |
| 207 | }, | 207 | }, |
| 208 | }, | 208 | }, |
| 209 | { | ||
| 210 | .matches = { | ||
| 211 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 212 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"), | ||
| 213 | }, | ||
| 214 | }, | ||
| 209 | {} /* Array terminator */ | 215 | {} /* Array terminator */ |
| 210 | }; | 216 | }; |
| 211 | 217 | ||
| @@ -3218,7 +3218,14 @@ static int hotkey_init_tablet_mode(void) · 3217 unmodified lines | |||
| 3218 | 3218 | ||
| 3219 | in_tablet_mode = hotkey_gmms_get_tablet_mode(res, | 3219 | in_tablet_mode = hotkey_gmms_get_tablet_mode(res, |
| 3220 | &has_tablet_mode); | 3220 | &has_tablet_mode); |
| 3221 | if (has_tablet_mode) | 3221 | /* |
| 3222 | * The Yoga 11e series has 2 accelerometers described by a | ||
| 3223 | * BOSC0200 ACPI node. This setup relies on a Windows service | ||
| 3224 | * which calls special ACPI methods on this node to report | ||
| 3225 | * the laptop/tent/tablet mode to the EC. The bmc150 iio driver | ||
| 3226 | * does not support this, so skip the hotkey on these models. | ||
| 3227 | */ | ||
| 3228 | if (has_tablet_mode && !acpi_dev_present("BOSC0200", "1", -1)) | ||
| 3222 | tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GMMS; | 3229 | tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GMMS; |
| 3223 | type = "GMMS"; | 3230 | type = "GMMS"; |
| 3224 | } else if (acpi_evalf(hkey_handle, &res, "MHKG", "qd")) { | 3231 | } else if (acpi_evalf(hkey_handle, &res, "MHKG", "qd")) { |
| @@ -4228,6 +4235,7 @@ static void hotkey_resume(void) · 1003 unmodified lines | |||
| 4228 | pr_err("error while attempting to reset the event firmware interface\n"); | 4235 | pr_err("error while attempting to reset the event firmware interface\n"); |
| 4229 | 4236 | ||
| 4230 | tpacpi_send_radiosw_update(); | 4237 | tpacpi_send_radiosw_update(); |
| 4238 | tpacpi_input_send_tabletsw(); | ||
| 4231 | hotkey_tablet_mode_notify_change(); | 4239 | hotkey_tablet_mode_notify_change(); |
| 4232 | hotkey_wakeup_reason_notify_change(); | 4240 | hotkey_wakeup_reason_notify_change(); |
| 4233 | hotkey_wakeup_hotunplug_complete_notify_change(); | 4241 | hotkey_wakeup_hotunplug_complete_notify_change(); |
| @@ -8776,6 +8784,8 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { · 4542 unmodified lines | |||
| 8776 | TPACPI_Q_LNV3('N', '2', 'C', TPACPI_FAN_2CTL), /* P52 / P72 */ | 8784 | TPACPI_Q_LNV3('N', '2', 'C', TPACPI_FAN_2CTL), /* P52 / P72 */ |
| 8777 | TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (1st gen) */ | 8785 | TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (1st gen) */ |
| 8778 | TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */ | 8786 | TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */ |
| 8787 | TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (3nd gen) */ | ||
| 8788 | TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */ | ||
| 8779 | }; | 8789 | }; |
| 8780 | 8790 | ||
| 8781 | static int __init fan_init(struct ibm_init_struct *iibm) | 8791 | static int __init fan_init(struct ibm_init_struct *iibm) |
| @@ -9703,6 +9713,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = { · 921 unmodified lines | |||
| 9703 | TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */ | 9713 | TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */ |
| 9704 | TPACPI_Q_LNV3('R', '0', 'C', true), /* Thinkpad 13 */ | 9714 | TPACPI_Q_LNV3('R', '0', 'C', true), /* Thinkpad 13 */ |
| 9705 | TPACPI_Q_LNV3('R', '0', 'J', true), /* Thinkpad 13 gen 2 */ | 9715 | TPACPI_Q_LNV3('R', '0', 'J', true), /* Thinkpad 13 gen 2 */ |
| 9716 | TPACPI_Q_LNV3('R', '0', 'K', true), /* Thinkpad 11e gen 4 celeron BIOS */ | ||
| 9706 | }; | 9717 | }; |
| 9707 | 9718 | ||
| 9708 | static int __init tpacpi_battery_init(struct ibm_init_struct *ibm) | 9719 | static int __init tpacpi_battery_init(struct ibm_init_struct *ibm) |
| @@ -1478,7 +1478,7 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, · 1477 unmodified lines | |||
| 1478 | struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); | 1478 | struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); |
| 1479 | char *buffer; | 1479 | char *buffer; |
| 1480 | char *cmd; | 1480 | char *cmd; |
| 1481 | int lcd_out, crt_out, tv_out; | 1481 | int lcd_out = -1, crt_out = -1, tv_out = -1; |
| 1482 | int remain = count; | 1482 | int remain = count; |
| 1483 | int value; | 1483 | int value; |
| 1484 | int ret; | 1484 | int ret; |
| @@ -1510,7 +1510,6 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, · 25 unmodified lines | |||
| 1510 | 1510 | ||
| 1511 | kfree(cmd); | 1511 | kfree(cmd); |
| 1512 | 1512 | ||
| 1513 | lcd_out = crt_out = tv_out = -1; | ||
| 1514 | ret = get_video_status(dev, &video_out); | 1513 | ret = get_video_status(dev, &video_out); |
| 1515 | if (!ret) { | 1514 | if (!ret) { |
| 1516 | unsigned int new_video_out = video_out; | 1515 | unsigned int new_video_out = video_out; |
| @@ -295,6 +295,21 @@ static const struct ts_dmi_data irbis_tw90_data = { · 294 unmodified lines | |||
| 295 | .properties = irbis_tw90_props, | 295 | .properties = irbis_tw90_props, |
| 296 | }; | 296 | }; |
| 297 | 297 | ||
| 298 | static const struct property_entry irbis_tw118_props[] = { | ||
| 299 | PROPERTY_ENTRY_U32("touchscreen-min-x", 20), | ||
| 300 | PROPERTY_ENTRY_U32("touchscreen-min-y", 30), | ||
| 301 | PROPERTY_ENTRY_U32("touchscreen-size-x", 1960), | ||
| 302 | PROPERTY_ENTRY_U32("touchscreen-size-y", 1510), | ||
| 303 | PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-irbis-tw118.fw"), | ||
| 304 | PROPERTY_ENTRY_U32("silead,max-fingers", 10), | ||
| 305 | { } | ||
| 306 | }; | ||
| 307 | |||
| 308 | static const struct ts_dmi_data irbis_tw118_data = { | ||
| 309 | .acpi_name = "MSSL1680:00", | ||
| 310 | .properties = irbis_tw118_props, | ||
| 311 | }; | ||
| 312 | |||
| 298 | static const struct property_entry itworks_tw891_props[] = { | 313 | static const struct property_entry itworks_tw891_props[] = { |
| 299 | PROPERTY_ENTRY_U32("touchscreen-min-x", 1), | 314 | PROPERTY_ENTRY_U32("touchscreen-min-x", 1), |
| 300 | PROPERTY_ENTRY_U32("touchscreen-min-y", 5), | 315 | PROPERTY_ENTRY_U32("touchscreen-min-y", 5), |
| @@ -623,6 +638,23 @@ static const struct ts_dmi_data pov_mobii_wintab_p1006w_v10_data = { · 322 unmodified lines | |||
| 623 | .properties = pov_mobii_wintab_p1006w_v10_props, | 638 | .properties = pov_mobii_wintab_p1006w_v10_props, |
| 624 | }; | 639 | }; |
| 625 | 640 | ||
| 641 | static const struct property_entry predia_basic_props[] = { | ||
| 642 | PROPERTY_ENTRY_U32("touchscreen-min-x", 3), | ||
| 643 | PROPERTY_ENTRY_U32("touchscreen-min-y", 10), | ||
| 644 | PROPERTY_ENTRY_U32("touchscreen-size-x", 1728), | ||
| 645 | PROPERTY_ENTRY_U32("touchscreen-size-y", 1144), | ||
| 646 | PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), | ||
| 647 | PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-predia-basic.fw"), | ||
| 648 | PROPERTY_ENTRY_U32("silead,max-fingers", 10), | ||
| 649 | PROPERTY_ENTRY_BOOL("silead,home-button"), | ||
| 650 | { } | ||
| 651 | }; | ||
| 652 | |||
| 653 | static const struct ts_dmi_data predia_basic_data = { | ||
| 654 | .acpi_name = "MSSL1680:00", | ||
| 655 | .properties = predia_basic_props, | ||
| 656 | }; | ||
| 657 | |||
| 626 | static const struct property_entry schneider_sct101ctm_props[] = { | 658 | static const struct property_entry schneider_sct101ctm_props[] = { |
| 627 | PROPERTY_ENTRY_U32("touchscreen-size-x", 1715), | 659 | PROPERTY_ENTRY_U32("touchscreen-size-x", 1715), |
| 628 | PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), | 660 | PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), |
| @@ -936,6 +968,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { · 307 unmodified lines | |||
| 936 | DMI_MATCH(DMI_PRODUCT_NAME, "TW90"), | 968 | DMI_MATCH(DMI_PRODUCT_NAME, "TW90"), |
| 937 | }, | 969 | }, |
| 938 | }, | 970 | }, |
| 971 | { | ||
| 972 | /* Irbis TW118 */ | ||
| 973 | .driver_data = (void *)&irbis_tw118_data, | ||
| 974 | .matches = { | ||
| 975 | DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"), | ||
| 976 | DMI_MATCH(DMI_PRODUCT_NAME, "TW118"), | ||
| 977 | }, | ||
| 978 | }, | ||
| 939 | { | 979 | { |
| 940 | /* I.T.Works TW891 */ | 980 | /* I.T.Works TW891 */ |
| 941 | .driver_data = (void *)&itworks_tw891_data, | 981 | .driver_data = (void *)&itworks_tw891_data, |
| @@ -1109,6 +1149,16 @@ const struct dmi_system_id touchscreen_dmi_table[] = { · 167 unmodified lines | |||
| 1109 | DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"), | 1149 | DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"), |
| 1110 | }, | 1150 | }, |
| 1111 | }, | 1151 | }, |
| 1152 | { | ||
| 1153 | /* Predia Basic tablet) */ | ||
| 1154 | .driver_data = (void *)&predia_basic_data, | ||
| 1155 | .matches = { | ||
| 1156 | DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), | ||
| 1157 | DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"), | ||
| 1158 | /* Above matches are too generic, add bios-version match */ | ||
| 1159 | DMI_MATCH(DMI_BIOS_VERSION, "Mx.WT107.KUBNGEA"), | ||
| 1160 | }, | ||
| 1161 | }, | ||
| 1112 | { | 1162 | { |
| 1113 | /* Point of View mobii wintab p800w (v2.1) */ | 1163 | /* Point of View mobii wintab p800w (v2.1) */ |
| 1114 | .driver_data = (void *)&pov_mobii_wintab_p800w_v21_data, | 1164 | .driver_data = (void *)&pov_mobii_wintab_p800w_v21_data, |
| @@ -103,43 +103,26 @@ static int timespec_to_char_array(struct timespec64 const *ts, · 102 unmodified lines | |||
| 103 | return 0; | 103 | return 0; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static int idtcm_strverscmp(const char *ver1, const char *ver2) | 106 | static int idtcm_strverscmp(const char *version1, const char *version2) |
| 107 | { | 107 | { |
| 108 | u8 num1; | 108 | u8 ver1[3], ver2[3]; |
| 109 | u8 num2; | 109 | int i; |
| 110 | int result = 0; | ||
| 111 | |||
| 112 | /* loop through each level of the version string */ | ||
| 113 | while (result == 0) { | ||
| 114 | /* extract leading version numbers */ | ||
| 115 | if (kstrtou8(ver1, 10, &num1) < 0) | ||
| 116 | return -1; | ||
| 117 | 110 | ||
| 118 | if (kstrtou8(ver2, 10, &num2) < 0) | 111 | if (sscanf(version1, "%hhu.%hhu.%hhu", |
| 119 | return -1; | 112 | &ver1[0], &ver1[1], &ver1[2]) != 3) |
| 113 | return -1; | ||
| 114 | if (sscanf(version2, "%hhu.%hhu.%hhu", | ||
| 115 | &ver2[0], &ver2[1], &ver2[2]) != 3) | ||
| 116 | return -1; | ||
| 120 | 117 | ||
| 121 | /* if numbers differ, then set the result */ | 118 | for (i = 0; i < 3; i++) { |
| 122 | if (num1 < num2) | 119 | if (ver1[i] > ver2[i]) |
| 123 | result = -1; | 120 | return 1; |
| 124 | else if (num1 > num2) | 121 | if (ver1[i] < ver2[i]) |
| 125 | result = 1; | 122 | return -1; |
| 126 | else { | ||
| 127 | /* if numbers are the same, go to next level */ | ||
| 128 | ver1 = strchr(ver1, '.'); | ||
| 129 | ver2 = strchr(ver2, '.'); | ||
| 130 | if (!ver1 && !ver2) | ||
| 131 | break; | ||
| 132 | else if (!ver1) | ||
| 133 | result = -1; | ||
| 134 | else if (!ver2) | ||
| 135 | result = 1; | ||
| 136 | else { | ||
| 137 | ver1++; | ||
| 138 | ver2++; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | 123 | } |
| 142 | return result; | 124 | |
| 125 | return 0; | ||
| 143 | } | 126 | } |
| 144 | 127 | ||
| 145 | static int idtcm_xfer_read(struct idtcm *idtcm, | 128 | static int idtcm_xfer_read(struct idtcm *idtcm, |
| @@ -2980,6 +2980,12 @@ static int _dasd_requeue_request(struct dasd_ccw_req *cqr) · 2979 unmodified lines | |||
| 2980 | 2980 | ||
| 2981 | if (!block) | 2981 | if (!block) |
| 2982 | return -EINVAL; | 2982 | return -EINVAL; |
| 2983 | /* | ||
| 2984 | * If the request is an ERP request there is nothing to requeue. | ||
| 2985 | * This will be done with the remaining original request. | ||
| 2986 | */ | ||
| 2987 | if (cqr->refers) | ||
| 2988 | return 0; | ||
| 2983 | spin_lock_irq(&cqr->dq->lock); | 2989 | spin_lock_irq(&cqr->dq->lock); |
| 2984 | req = (struct request *) cqr->callback_data; | 2990 | req = (struct request *) cqr->callback_data; |
| 2985 | blk_mq_requeue_request(req, false); | 2991 | blk_mq_requeue_request(req, false); |
| @@ -417,10 +417,13 @@ enum qeth_qdio_out_buffer_state { · 416 unmodified lines | |||
| 417 | QETH_QDIO_BUF_EMPTY, | 417 | QETH_QDIO_BUF_EMPTY, |
| 418 | /* Filled by driver; owned by hardware in order to be sent. */ | 418 | /* Filled by driver; owned by hardware in order to be sent. */ |
| 419 | QETH_QDIO_BUF_PRIMED, | 419 | QETH_QDIO_BUF_PRIMED, |
| 420 | /* Identified to be pending in TPQ. */ | 420 | /* Discovered by the TX completion code: */ |
| 421 | QETH_QDIO_BUF_PENDING, | 421 | QETH_QDIO_BUF_PENDING, |
| 422 | /* Found in completion queue. */ | 422 | /* Finished by the TX completion code: */ |
| 423 | QETH_QDIO_BUF_IN_CQ, | 423 | QETH_QDIO_BUF_NEED_QAOB, |
| 424 | /* Received QAOB notification on CQ: */ | ||
| 425 | QETH_QDIO_BUF_QAOB_OK, | ||
| 426 | QETH_QDIO_BUF_QAOB_ERROR, | ||
| 424 | /* Handled via transfer pending / completion queue. */ | 427 | /* Handled via transfer pending / completion queue. */ |
| 425 | QETH_QDIO_BUF_HANDLED_DELAYED, | 428 | QETH_QDIO_BUF_HANDLED_DELAYED, |
| 426 | }; | 429 | }; |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | #include <net/iucv/af_iucv.h> | 34 | #include <net/iucv/af_iucv.h> |
| 35 | #include <net/dsfield.h> | 35 | #include <net/dsfield.h> |
| 36 | #include <net/sock.h> | ||
| 36 | 37 | ||
| 37 | #include <asm/ebcdic.h> | 38 | #include <asm/ebcdic.h> |
| 38 | #include <asm/chpid.h> | 39 | #include <asm/chpid.h> |
| @@ -499,17 +500,12 @@ static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx, · 460 unmodified lines | |||
| 499 | 500 | ||
| 500 | } | 501 | } |
| 501 | } | 502 | } |
| 502 | if (forced_cleanup && (atomic_read(&(q->bufs[bidx]->state)) == | ||
| 503 | QETH_QDIO_BUF_HANDLED_DELAYED)) { | ||
| 504 | /* for recovery situations */ | ||
| 505 | qeth_init_qdio_out_buf(q, bidx); | ||
| 506 | QETH_CARD_TEXT(q->card, 2, "clprecov"); | ||
| 507 | } | ||
| 508 | } | 503 | } |
| 509 | 504 | ||
| 510 | static void qeth_qdio_handle_aob(struct qeth_card *card, | 505 | static void qeth_qdio_handle_aob(struct qeth_card *card, |
| 511 | unsigned long phys_aob_addr) | 506 | unsigned long phys_aob_addr) |
| 512 | { | 507 | { |
| 508 | enum qeth_qdio_out_buffer_state new_state = QETH_QDIO_BUF_QAOB_OK; | ||
| 513 | struct qaob *aob; | 509 | struct qaob *aob; |
| 514 | struct qeth_qdio_out_buffer *buffer; | 510 | struct qeth_qdio_out_buffer *buffer; |
| 515 | enum iucv_tx_notify notification; | 511 | enum iucv_tx_notify notification; |
| @@ -521,22 +517,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, · 5 unmodified lines | |||
| 521 | buffer = (struct qeth_qdio_out_buffer *) aob->user1; | 517 | buffer = (struct qeth_qdio_out_buffer *) aob->user1; |
| 522 | QETH_CARD_TEXT_(card, 5, "%lx", aob->user1); | 518 | QETH_CARD_TEXT_(card, 5, "%lx", aob->user1); |
| 523 | 519 | ||
| 524 | if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, | ||
| 525 | QETH_QDIO_BUF_IN_CQ) == QETH_QDIO_BUF_PRIMED) { | ||
| 526 | notification = TX_NOTIFY_OK; | ||
| 527 | } else { | ||
| 528 | WARN_ON_ONCE(atomic_read(&buffer->state) != | ||
| 529 | QETH_QDIO_BUF_PENDING); | ||
| 530 | atomic_set(&buffer->state, QETH_QDIO_BUF_IN_CQ); | ||
| 531 | notification = TX_NOTIFY_DELAYED_OK; | ||
| 532 | } | ||
| 533 | |||
| 534 | if (aob->aorc != 0) { | ||
| 535 | QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); | ||
| 536 | notification = qeth_compute_cq_notification(aob->aorc, 1); | ||
| 537 | } | ||
| 538 | qeth_notify_skbs(buffer->q, buffer, notification); | ||
| 539 | |||
| 540 | /* Free dangling allocations. The attached skbs are handled by | 520 | /* Free dangling allocations. The attached skbs are handled by |
| 541 | * qeth_cleanup_handled_pending(). | 521 | * qeth_cleanup_handled_pending(). |
| 542 | */ | 522 | */ |
| @@ -548,7 +528,33 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, · 5 unmodified lines | |||
| 548 | if (data && buffer->is_header[i]) | 528 | if (data && buffer->is_header[i]) |
| 549 | kmem_cache_free(qeth_core_header_cache, data); | 529 | kmem_cache_free(qeth_core_header_cache, data); |
| 550 | } | 530 | } |
| 551 | atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); | 531 | |
| 532 | if (aob->aorc) { | ||
| 533 | QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); | ||
| 534 | new_state = QETH_QDIO_BUF_QAOB_ERROR; | ||
| 535 | } | ||
| 536 | |||
| 537 | switch (atomic_xchg(&buffer->state, new_state)) { | ||
| 538 | case QETH_QDIO_BUF_PRIMED: | ||
| 539 | /* Faster than TX completion code. */ | ||
| 540 | notification = qeth_compute_cq_notification(aob->aorc, 0); | ||
| 541 | qeth_notify_skbs(buffer->q, buffer, notification); | ||
| 542 | atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); | ||
| 543 | break; | ||
| 544 | case QETH_QDIO_BUF_PENDING: | ||
| 545 | /* TX completion code is active and will handle the async | ||
| 546 | * completion for us. | ||
| 547 | */ | ||
| 548 | break; | ||
| 549 | case QETH_QDIO_BUF_NEED_QAOB: | ||
| 550 | /* TX completion code is already finished. */ | ||
| 551 | notification = qeth_compute_cq_notification(aob->aorc, 1); | ||
| 552 | qeth_notify_skbs(buffer->q, buffer, notification); | ||
| 553 | atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); | ||
| 554 | break; | ||
| 555 | default: | ||
| 556 | WARN_ON_ONCE(1); | ||
| 557 | } | ||
| 552 | 558 | ||
| 553 | qdio_release_aob(aob); | 559 | qdio_release_aob(aob); |
| 554 | } | 560 | } |
| @@ -1405,7 +1411,7 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *q, · 850 unmodified lines | |||
| 1405 | skb_queue_walk(&buf->skb_list, skb) { | 1411 | skb_queue_walk(&buf->skb_list, skb) { |
| 1406 | QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification); | 1412 | QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification); |
| 1407 | QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb); | 1413 | QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb); |
| 1408 | if (skb->protocol == htons(ETH_P_AF_IUCV) && skb->sk) | 1414 | if (skb->sk && skb->sk->sk_family == PF_IUCV) |
| 1409 | iucv_sk(skb->sk)->sk_txnotify(skb, notification); | 1415 | iucv_sk(skb->sk)->sk_txnotify(skb, notification); |
| 1410 | } | 1416 | } |
| 1411 | } | 1417 | } |
| @@ -1416,9 +1422,6 @@ static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error, · 4 unmodified lines | |||
| 1416 | struct qeth_qdio_out_q *queue = buf->q; | 1422 | struct qeth_qdio_out_q *queue = buf->q; |
| 1417 | struct sk_buff *skb; | 1423 | struct sk_buff *skb; |
| 1418 | 1424 | ||
| 1419 | /* release may never happen from within CQ tasklet scope */ | ||
| 1420 | WARN_ON_ONCE(atomic_read(&buf->state) == QETH_QDIO_BUF_IN_CQ); | ||
| 1421 | |||
| 1422 | if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING) | 1425 | if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING) |
| 1423 | qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR); | 1426 | qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR); |
| 1424 | 1427 | ||
| @@ -6078,9 +6081,32 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue, · 4653 unmodified lines | |||
| 6078 | 6081 | ||
| 6079 | if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, | 6082 | if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, |
| 6080 | QETH_QDIO_BUF_PENDING) == | 6083 | QETH_QDIO_BUF_PENDING) == |
| 6081 | QETH_QDIO_BUF_PRIMED) | 6084 | QETH_QDIO_BUF_PRIMED) { |
| 6082 | qeth_notify_skbs(queue, buffer, TX_NOTIFY_PENDING); | 6085 | qeth_notify_skbs(queue, buffer, TX_NOTIFY_PENDING); |
| 6083 | 6086 | ||
| 6087 | /* Handle race with qeth_qdio_handle_aob(): */ | ||
| 6088 | switch (atomic_xchg(&buffer->state, | ||
| 6089 | QETH_QDIO_BUF_NEED_QAOB)) { | ||
| 6090 | case QETH_QDIO_BUF_PENDING: | ||
| 6091 | /* No concurrent QAOB notification. */ | ||
| 6092 | break; | ||
| 6093 | case QETH_QDIO_BUF_QAOB_OK: | ||
| 6094 | qeth_notify_skbs(queue, buffer, | ||
| 6095 | TX_NOTIFY_DELAYED_OK); | ||
| 6096 | atomic_set(&buffer->state, | ||
| 6097 | QETH_QDIO_BUF_HANDLED_DELAYED); | ||
| 6098 | break; | ||
| 6099 | case QETH_QDIO_BUF_QAOB_ERROR: | ||
| 6100 | qeth_notify_skbs(queue, buffer, | ||
| 6101 | TX_NOTIFY_DELAYED_GENERALERROR); | ||
| 6102 | atomic_set(&buffer->state, | ||
| 6103 | QETH_QDIO_BUF_HANDLED_DELAYED); | ||
| 6104 | break; | ||
| 6105 | default: | ||
| 6106 | WARN_ON_ONCE(1); | ||
| 6107 | } | ||
| 6108 | } | ||
| 6109 | |||
| 6084 | QETH_CARD_TEXT_(card, 5, "pel%u", bidx); | 6110 | QETH_CARD_TEXT_(card, 5, "pel%u", bidx); |
| 6085 | 6111 | ||
| 6086 | /* prepare the queue slot for re-use: */ | 6112 | /* prepare the queue slot for re-use: */ |
| @@ -983,32 +983,19 @@ static void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) · 982 unmodified lines | |||
| 983 | * change notification' and thus can support the learning_sync bridgeport | 983 | * change notification' and thus can support the learning_sync bridgeport |
| 984 | * attribute | 984 | * attribute |
| 985 | * @card: qeth_card structure pointer | 985 | * @card: qeth_card structure pointer |
| 986 | * | ||
| 987 | * This is a destructive test and must be called before dev2br or | ||
| 988 | * bridgeport address notification is enabled! | ||
| 989 | */ | 986 | */ |
| 990 | static void qeth_l2_detect_dev2br_support(struct qeth_card *card) | 987 | static void qeth_l2_detect_dev2br_support(struct qeth_card *card) |
| 991 | { | 988 | { |
| 992 | struct qeth_priv *priv = netdev_priv(card->dev); | 989 | struct qeth_priv *priv = netdev_priv(card->dev); |
| 993 | bool dev2br_supported; | 990 | bool dev2br_supported; |
| 994 | int rc; | ||
| 995 | 991 | ||
| 996 | QETH_CARD_TEXT(card, 2, "d2brsup"); | 992 | QETH_CARD_TEXT(card, 2, "d2brsup"); |
| 997 | if (!IS_IQD(card)) | 993 | if (!IS_IQD(card)) |
| 998 | return; | 994 | return; |
| 999 | 995 | ||
| 1000 | /* dev2br requires valid cssid,iid,chid */ | 996 | /* dev2br requires valid cssid,iid,chid */ |
| 1001 | if (!card->info.ids_valid) { | 997 | dev2br_supported = card->info.ids_valid && |
| 1002 | dev2br_supported = false; | 998 | css_general_characteristics.enarf; |
| 1003 | } else if (css_general_characteristics.enarf) { | ||
| 1004 | dev2br_supported = true; | ||
| 1005 | } else { | ||
| 1006 | /* Old machines don't have the feature bit: | ||
| 1007 | * Probe by testing whether a disable succeeds | ||
| 1008 | */ | ||
| 1009 | rc = qeth_l2_pnso(card, PNSO_OC_NET_ADDR_INFO, 0, NULL, NULL); | ||
| 1010 | dev2br_supported = !rc; | ||
| 1011 | } | ||
| 1012 | QETH_CARD_TEXT_(card, 2, "D2Bsup%02x", dev2br_supported); | 999 | QETH_CARD_TEXT_(card, 2, "D2Bsup%02x", dev2br_supported); |
| 1013 | 1000 | ||
| 1014 | if (dev2br_supported) | 1001 | if (dev2br_supported) |
| @@ -2233,7 +2220,6 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) · 1218 unmodified lines | |||
| 2233 | struct net_device *dev = card->dev; | 2220 | struct net_device *dev = card->dev; |
| 2234 | int rc = 0; | 2221 | int rc = 0; |
| 2235 | 2222 | ||
| 2236 | /* query before bridgeport_notification may be enabled */ | ||
| 2237 | qeth_l2_detect_dev2br_support(card); | 2223 | qeth_l2_detect_dev2br_support(card); |
| 2238 | 2224 | ||
| 2239 | mutex_lock(&card->sbp_lock); | 2225 | mutex_lock(&card->sbp_lock); |
| @@ -533,8 +533,8 @@ static void iscsi_complete_task(struct iscsi_task *task, int state) · 532 unmodified lines | |||
| 533 | if (conn->task == task) | 533 | if (conn->task == task) |
| 534 | conn->task = NULL; | 534 | conn->task = NULL; |
| 535 | 535 | ||
| 536 | if (conn->ping_task == task) | 536 | if (READ_ONCE(conn->ping_task) == task) |
| 537 | conn->ping_task = NULL; | 537 | WRITE_ONCE(conn->ping_task, NULL); |
| 538 | 538 | ||
| 539 | /* release get from queueing */ | 539 | /* release get from queueing */ |
| 540 | __iscsi_put_task(task); | 540 | __iscsi_put_task(task); |
| @@ -738,6 +738,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, · 197 unmodified lines | |||
| 738 | task->conn->session->age); | 738 | task->conn->session->age); |
| 739 | } | 739 | } |
| 740 | 740 | ||
| 741 | if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK)) | ||
| 742 | WRITE_ONCE(conn->ping_task, task); | ||
| 743 | |||
| 741 | if (!ihost->workq) { | 744 | if (!ihost->workq) { |
| 742 | if (iscsi_prep_mgmt_task(conn, task)) | 745 | if (iscsi_prep_mgmt_task(conn, task)) |
| 743 | goto free_task; | 746 | goto free_task; |
| @@ -941,8 +944,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) · 197 unmodified lines | |||
| 941 | struct iscsi_nopout hdr; | 944 | struct iscsi_nopout hdr; |
| 942 | struct iscsi_task *task; | 945 | struct iscsi_task *task; |
| 943 | 946 | ||
| 944 | if (!rhdr && conn->ping_task) | 947 | if (!rhdr) { |
| 945 | return -EINVAL; | 948 | if (READ_ONCE(conn->ping_task)) |
| 949 | return -EINVAL; | ||
| 950 | WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK); | ||
| 951 | } | ||
| 946 | 952 | ||
| 947 | memset(&hdr, 0, sizeof(struct iscsi_nopout)); | 953 | memset(&hdr, 0, sizeof(struct iscsi_nopout)); |
| 948 | hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE; | 954 | hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE; |
| @@ -957,11 +963,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) · 8 unmodified lines | |||
| 957 | 963 | ||
| 958 | task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); | 964 | task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); |
| 959 | if (!task) { | 965 | if (!task) { |
| 966 | if (!rhdr) | ||
| 967 | WRITE_ONCE(conn->ping_task, NULL); | ||
| 960 | iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); | 968 | iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); |
| 961 | return -EIO; | 969 | return -EIO; |
| 962 | } else if (!rhdr) { | 970 | } else if (!rhdr) { |
| 963 | /* only track our nops */ | 971 | /* only track our nops */ |
| 964 | conn->ping_task = task; | ||
| 965 | conn->last_ping = jiffies; | 972 | conn->last_ping = jiffies; |
| 966 | } | 973 | } |
| 967 | 974 | ||
| @@ -984,7 +991,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task, · 16 unmodified lines | |||
| 984 | struct iscsi_conn *conn = task->conn; | 991 | struct iscsi_conn *conn = task->conn; |
| 985 | int rc = 0; | 992 | int rc = 0; |
| 986 | 993 | ||
| 987 | if (conn->ping_task != task) { | 994 | if (READ_ONCE(conn->ping_task) != task) { |
| 988 | /* | 995 | /* |
| 989 | * If this is not in response to one of our | 996 | * If this is not in response to one of our |
| 990 | * nops then it must be from userspace. | 997 | * nops then it must be from userspace. |
| @@ -1923,7 +1930,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn) · 932 unmodified lines | |||
| 1923 | */ | 1930 | */ |
| 1924 | static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) | 1931 | static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) |
| 1925 | { | 1932 | { |
| 1926 | if (conn->ping_task && | 1933 | if (READ_ONCE(conn->ping_task) && |
| 1927 | time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + | 1934 | time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + |
| 1928 | (conn->ping_timeout * HZ), jiffies)) | 1935 | (conn->ping_timeout * HZ), jiffies)) |
| 1929 | return 1; | 1936 | return 1; |
| @@ -2058,7 +2065,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) · 128 unmodified lines | |||
| 2058 | * Checking the transport already or nop from a cmd timeout still | 2065 | * Checking the transport already or nop from a cmd timeout still |
| 2059 | * running | 2066 | * running |
| 2060 | */ | 2067 | */ |
| 2061 | if (conn->ping_task) { | 2068 | if (READ_ONCE(conn->ping_task)) { |
| 2062 | task->have_checked_conn = true; | 2069 | task->have_checked_conn = true; |
| 2063 | rc = BLK_EH_RESET_TIMER; | 2070 | rc = BLK_EH_RESET_TIMER; |
| 2064 | goto done; | 2071 | goto done; |
| @@ -1294,8 +1294,15 @@ static int ufshcd_devfreq_target(struct device *dev, · 1293 unmodified lines | |||
| 1294 | } | 1294 | } |
| 1295 | spin_unlock_irqrestore(hba->host->host_lock, irq_flags); | 1295 | spin_unlock_irqrestore(hba->host->host_lock, irq_flags); |
| 1296 | 1296 | ||
| 1297 | pm_runtime_get_noresume(hba->dev); | ||
| 1298 | if (!pm_runtime_active(hba->dev)) { | ||
| 1299 | pm_runtime_put_noidle(hba->dev); | ||
| 1300 | ret = -EAGAIN; | ||
| 1301 | goto out; | ||
| 1302 | } | ||
| 1297 | start = ktime_get(); | 1303 | start = ktime_get(); |
| 1298 | ret = ufshcd_devfreq_scale(hba, scale_up); | 1304 | ret = ufshcd_devfreq_scale(hba, scale_up); |
| 1305 | pm_runtime_put(hba->dev); | ||
| 1299 | 1306 | ||
| 1300 | trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), | 1307 | trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), |
| 1301 | (scale_up ? "up" : "down"), | 1308 | (scale_up ? "up" : "down"), |
| @@ -3192,13 +3199,19 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, · 1890 unmodified lines | |||
| 3192 | /* Get the length of descriptor */ | 3199 | /* Get the length of descriptor */ |
| 3193 | ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len); | 3200 | ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len); |
| 3194 | if (!buff_len) { | 3201 | if (!buff_len) { |
| 3195 | dev_err(hba->dev, "%s: Failed to get desc length", __func__); | 3202 | dev_err(hba->dev, "%s: Failed to get desc length\n", __func__); |
| 3203 | return -EINVAL; | ||
| 3204 | } | ||
| 3205 | |||
| 3206 | if (param_offset >= buff_len) { | ||
| 3207 | dev_err(hba->dev, "%s: Invalid offset 0x%x in descriptor IDN 0x%x, length 0x%x\n", | ||
| 3208 | __func__, param_offset, desc_id, buff_len); | ||
| 3196 | return -EINVAL; | 3209 | return -EINVAL; |
| 3197 | } | 3210 | } |
| 3198 | 3211 | ||
| 3199 | /* Check whether we need temp memory */ | 3212 | /* Check whether we need temp memory */ |
| 3200 | if (param_offset != 0 || param_size < buff_len) { | 3213 | if (param_offset != 0 || param_size < buff_len) { |
| 3201 | desc_buf = kmalloc(buff_len, GFP_KERNEL); | 3214 | desc_buf = kzalloc(buff_len, GFP_KERNEL); |
| 3202 | if (!desc_buf) | 3215 | if (!desc_buf) |
| 3203 | return -ENOMEM; | 3216 | return -ENOMEM; |
| 3204 | } else { | 3217 | } else { |
| @@ -3212,14 +3225,14 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, · 7 unmodified lines | |||
| 3212 | desc_buf, &buff_len); | 3225 | desc_buf, &buff_len); |
| 3213 | 3226 | ||
| 3214 | if (ret) { | 3227 | if (ret) { |
| 3215 | dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d", | 3228 | dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n", |
| 3216 | __func__, desc_id, desc_index, param_offset, ret); | 3229 | __func__, desc_id, desc_index, param_offset, ret); |
| 3217 | goto out; | 3230 | goto out; |
| 3218 | } | 3231 | } |
| 3219 | 3232 | ||
| 3220 | /* Sanity check */ | 3233 | /* Sanity check */ |
| 3221 | if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) { | 3234 | if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) { |
| 3222 | dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header", | 3235 | dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header\n", |
| 3223 | __func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]); | 3236 | __func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]); |
| 3224 | ret = -EINVAL; | 3237 | ret = -EINVAL; |
| 3225 | goto out; | 3238 | goto out; |
| @@ -3229,12 +3242,12 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, · 3 unmodified lines | |||
| 3229 | buff_len = desc_buf[QUERY_DESC_LENGTH_OFFSET]; | 3242 | buff_len = desc_buf[QUERY_DESC_LENGTH_OFFSET]; |
| 3230 | ufshcd_update_desc_length(hba, desc_id, desc_index, buff_len); | 3243 | ufshcd_update_desc_length(hba, desc_id, desc_index, buff_len); |
| 3231 | 3244 | ||
| 3232 | /* Check wherher we will not copy more data, than available */ | 3245 | if (is_kmalloc) { |
| 3233 | if (is_kmalloc && (param_offset + param_size) > buff_len) | 3246 | /* Make sure we don't copy more data than available */ |
| 3234 | param_size = buff_len - param_offset; | 3247 | if (param_offset + param_size > buff_len) |
| 3235 | 3248 | param_size = buff_len - param_offset; | |
| 3236 | if (is_kmalloc) | ||
| 3237 | memcpy(param_read_buf, &desc_buf[param_offset], param_size); | 3249 | memcpy(param_read_buf, &desc_buf[param_offset], param_size); |
| 3250 | } | ||
| 3238 | out: | 3251 | out: |
| 3239 | if (is_kmalloc) | 3252 | if (is_kmalloc) |
| 3240 | kfree(desc_buf); | 3253 | kfree(desc_buf); |
| @@ -8900,11 +8913,7 @@ int ufshcd_shutdown(struct ufs_hba *hba) · 5659 unmodified lines | |||
| 8900 | if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba)) | 8913 | if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba)) |
| 8901 | goto out; | 8914 | goto out; |
| 8902 | 8915 | ||
| 8903 | if (pm_runtime_suspended(hba->dev)) { | 8916 | pm_runtime_get_sync(hba->dev); |
| 8904 | ret = ufshcd_runtime_resume(hba); | ||
| 8905 | if (ret) | ||
| 8906 | goto out; | ||
| 8907 | } | ||
| 8908 | 8917 | ||
| 8909 | ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM); | 8918 | ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM); |
| 8910 | out: | 8919 | out: |
| @@ -95,7 +95,6 @@ static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) · 94 unmodified lines | |||
| 95 | { | 95 | { |
| 96 | int error; | 96 | int error; |
| 97 | struct fsl_mc_device_irq *irq; | 97 | struct fsl_mc_device_irq *irq; |
| 98 | cpumask_t mask; | ||
| 99 | 98 | ||
| 100 | irq = dpio_dev->irqs[0]; | 99 | irq = dpio_dev->irqs[0]; |
| 101 | error = devm_request_irq(&dpio_dev->dev, | 100 | error = devm_request_irq(&dpio_dev->dev, |
| @@ -112,9 +111,7 @@ static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) · 10 unmodified lines | |||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | /* set the affinity hint */ | 113 | /* set the affinity hint */ |
| 115 | cpumask_clear(&mask); | 114 | if (irq_set_affinity_hint(irq->msi_desc->irq, cpumask_of(cpu))) |
| 116 | cpumask_set_cpu(cpu, &mask); | ||
| 117 | if (irq_set_affinity_hint(irq->msi_desc->irq, &mask)) | ||
| 118 | dev_err(&dpio_dev->dev, | 115 | dev_err(&dpio_dev->dev, |
| 119 | "irq_set_affinity failed irq %d cpu %d\n", | 116 | "irq_set_affinity failed irq %d cpu %d\n", |
| 120 | irq->msi_desc->irq, cpu); | 117 | irq->msi_desc->irq, cpu); |
| @@ -875,7 +875,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) · 874 unmodified lines | |||
| 875 | master->set_cs = dw_spi_set_cs; | 875 | master->set_cs = dw_spi_set_cs; |
| 876 | master->transfer_one = dw_spi_transfer_one; | 876 | master->transfer_one = dw_spi_transfer_one; |
| 877 | master->handle_err = dw_spi_handle_err; | 877 | master->handle_err = dw_spi_handle_err; |
| 878 | master->mem_ops = &dws->mem_ops; | 878 | if (dws->mem_ops.exec_op) |
| 879 | master->mem_ops = &dws->mem_ops; | ||
| 879 | master->max_speed_hz = dws->max_freq; | 880 | master->max_speed_hz = dws->max_freq; |
| 880 | master->dev.of_node = dev->of_node; | 881 | master->dev.of_node = dev->of_node; |
| 881 | master->dev.fwnode = dev->fwnode; | 882 | master->dev.fwnode = dev->fwnode; |
| @@ -1686,6 +1686,7 @@ static int spi_imx_probe(struct platform_device *pdev) · 1685 unmodified lines | |||
| 1686 | 1686 | ||
| 1687 | pm_runtime_set_autosuspend_delay(spi_imx->dev, MXC_RPM_TIMEOUT); | 1687 | pm_runtime_set_autosuspend_delay(spi_imx->dev, MXC_RPM_TIMEOUT); |
| 1688 | pm_runtime_use_autosuspend(spi_imx->dev); | 1688 | pm_runtime_use_autosuspend(spi_imx->dev); |
| 1689 | pm_runtime_get_noresume(spi_imx->dev); | ||
| 1689 | pm_runtime_set_active(spi_imx->dev); | 1690 | pm_runtime_set_active(spi_imx->dev); |
| 1690 | pm_runtime_enable(spi_imx->dev); | 1691 | pm_runtime_enable(spi_imx->dev); |
| 1691 | 1692 | ||
| @@ -1001,6 +1001,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) · 1000 unmodified lines | |||
| 1001 | struct resource *res; | 1001 | struct resource *res; |
| 1002 | struct nxp_fspi *f; | 1002 | struct nxp_fspi *f; |
| 1003 | int ret; | 1003 | int ret; |
| 1004 | u32 reg; | ||
| 1004 | 1005 | ||
| 1005 | ctlr = spi_alloc_master(&pdev->dev, sizeof(*f)); | 1006 | ctlr = spi_alloc_master(&pdev->dev, sizeof(*f)); |
| 1006 | if (!ctlr) | 1007 | if (!ctlr) |
| @@ -1032,6 +1033,12 @@ static int nxp_fspi_probe(struct platform_device *pdev) · 25 unmodified lines | |||
| 1032 | goto err_put_ctrl; | 1033 | goto err_put_ctrl; |
| 1033 | } | 1034 | } |
| 1034 | 1035 | ||
| 1036 | /* Clear potential interrupts */ | ||
| 1037 | reg = fspi_readl(f, f->iobase + FSPI_INTR); | ||
| 1038 | if (reg) | ||
| 1039 | fspi_writel(f, reg, f->iobase + FSPI_INTR); | ||
| 1040 | |||
| 1041 | |||
| 1035 | /* find the resources - controller memory mapped space */ | 1042 | /* find the resources - controller memory mapped space */ |
| 1036 | if (is_acpi_node(f->dev->fwnode)) | 1043 | if (is_acpi_node(f->dev->fwnode)) |
| 1037 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1044 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| @@ -3372,12 +3372,15 @@ int spi_setup(struct spi_device *spi) · 3371 unmodified lines | |||
| 3372 | if (!spi->max_speed_hz) | 3372 | if (!spi->max_speed_hz) |
| 3373 | spi->max_speed_hz = spi->controller->max_speed_hz; | 3373 | spi->max_speed_hz = spi->controller->max_speed_hz; |
| 3374 | 3374 | ||
| 3375 | mutex_lock(&spi->controller->io_mutex); | ||
| 3376 | |||
| 3375 | if (spi->controller->setup) | 3377 | if (spi->controller->setup) |
| 3376 | status = spi->controller->setup(spi); | 3378 | status = spi->controller->setup(spi); |
| 3377 | 3379 | ||
| 3378 | if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { | 3380 | if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { |
| 3379 | status = pm_runtime_get_sync(spi->controller->dev.parent); | 3381 | status = pm_runtime_get_sync(spi->controller->dev.parent); |
| 3380 | if (status < 0) { | 3382 | if (status < 0) { |
| 3383 | mutex_unlock(&spi->controller->io_mutex); | ||
| 3381 | pm_runtime_put_noidle(spi->controller->dev.parent); | 3384 | pm_runtime_put_noidle(spi->controller->dev.parent); |
| 3382 | dev_err(&spi->controller->dev, "Failed to power device: %d\n", | 3385 | dev_err(&spi->controller->dev, "Failed to power device: %d\n", |
| 3383 | status); | 3386 | status); |
| @@ -3399,6 +3402,8 @@ int spi_setup(struct spi_device *spi) · 15 unmodified lines | |||
| 3399 | spi_set_cs(spi, false); | 3402 | spi_set_cs(spi, false); |
| 3400 | } | 3403 | } |
| 3401 | 3404 | ||
| 3405 | mutex_unlock(&spi->controller->io_mutex); | ||
| 3406 | |||
| 3402 | if (spi->rt && !spi->controller->rt) { | 3407 | if (spi->rt && !spi->controller->rt) { |
| 3403 | spi->controller->rt = true; | 3408 | spi->controller->rt = true; |
| 3404 | spi_set_thread_rt(spi->controller); | 3409 | spi_set_thread_rt(spi->controller); |
| @@ -446,7 +446,7 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, · 445 unmodified lines | |||
| 446 | reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16; | 446 | reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16; |
| 447 | reg |= (pps->chroma_qp_index_offset & 0x3f) << 8; | 447 | reg |= (pps->chroma_qp_index_offset & 0x3f) << 8; |
| 448 | reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f; | 448 | reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f; |
| 449 | if (pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT) | 449 | if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) |
| 450 | reg |= VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT; | 450 | reg |= VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT; |
| 451 | cedrus_write(dev, VE_H264_SHS_QP, reg); | 451 | cedrus_write(dev, VE_H264_SHS_QP, reg); |
| 452 | 452 | ||
| @@ -653,16 +653,11 @@ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie) · 652 unmodified lines | |||
| 653 | return 0; | 653 | return 0; |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | static int mt7621_pcie_request_resources(struct mt7621_pcie *pcie, | 656 | static void mt7621_pcie_add_resources(struct mt7621_pcie *pcie, |
| 657 | struct list_head *res) | 657 | struct list_head *res) |
| 658 | { | 658 | { |
| 659 | struct device *dev = pcie->dev; | ||
| 660 | |||
| 661 | pci_add_resource_offset(res, &pcie->io, pcie->offset.io); | 659 | pci_add_resource_offset(res, &pcie->io, pcie->offset.io); |
| 662 | pci_add_resource_offset(res, &pcie->mem, pcie->offset.mem); | 660 | pci_add_resource_offset(res, &pcie->mem, pcie->offset.mem); |
| 663 | pci_add_resource(res, &pcie->busn); | ||
| 664 | |||
| 665 | return devm_request_pci_bus_resources(dev, res); | ||
| 666 | } | 661 | } |
| 667 | 662 | ||
| 668 | static int mt7621_pcie_register_host(struct pci_host_bridge *host, | 663 | static int mt7621_pcie_register_host(struct pci_host_bridge *host, |
| @@ -738,11 +733,7 @@ static int mt7621_pci_probe(struct platform_device *pdev) · 69 unmodified lines | |||
| 738 | 733 | ||
| 739 | setup_cm_memory_region(pcie); | 734 | setup_cm_memory_region(pcie); |
| 740 | 735 | ||
| 741 | err = mt7621_pcie_request_resources(pcie, &res); | 736 | mt7621_pcie_add_resources(pcie, &res); |
| 742 | if (err) { | ||
| 743 | dev_err(dev, "Error requesting resources\n"); | ||
| 744 | return err; | ||
| 745 | } | ||
| 746 | 737 | ||
| 747 | err = mt7621_pcie_register_host(bridge, &res); | 738 | err = mt7621_pcie_register_host(bridge, &res); |
| 748 | if (err) { | 739 | if (err) { |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | config DMA_RALINK | 2 | config DMA_RALINK |
| 3 | tristate "RALINK DMA support" | 3 | tristate "RALINK DMA support" |
| 4 | depends on RALINK && !SOC_RT288X | 4 | depends on RALINK && !SOC_RT288X |
| 5 | depends on DMADEVICES | ||
| 5 | select DMA_ENGINE | 6 | select DMA_ENGINE |
| 6 | select DMA_VIRTUAL_CHANNELS | 7 | select DMA_VIRTUAL_CHANNELS |
| 7 | 8 | ||
| @@ -20,6 +20,7 @@ static const struct sdio_device_id sdio_ids[] = { · 19 unmodified lines | |||
| 20 | { SDIO_DEVICE(0x024c, 0x0525), }, | 20 | { SDIO_DEVICE(0x024c, 0x0525), }, |
| 21 | { SDIO_DEVICE(0x024c, 0x0623), }, | 21 | { SDIO_DEVICE(0x024c, 0x0623), }, |
| 22 | { SDIO_DEVICE(0x024c, 0x0626), }, | 22 | { SDIO_DEVICE(0x024c, 0x0626), }, |
| 23 | { SDIO_DEVICE(0x024c, 0x0627), }, | ||
| 23 | { SDIO_DEVICE(0x024c, 0xb723), }, | 24 | { SDIO_DEVICE(0x024c, 0xb723), }, |
| 24 | { /* end: all zeroes */ }, | 25 | { /* end: all zeroes */ }, |
| 25 | }; | 26 | }; |
| @@ -483,8 +483,7 @@ EXPORT_SYMBOL(iscsit_queue_rsp); · 482 unmodified lines | |||
| 483 | void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | 483 | void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) |
| 484 | { | 484 | { |
| 485 | spin_lock_bh(&conn->cmd_lock); | 485 | spin_lock_bh(&conn->cmd_lock); |
| 486 | if (!list_empty(&cmd->i_conn_node) && | 486 | if (!list_empty(&cmd->i_conn_node)) |
| 487 | !(cmd->se_cmd.transport_state & CMD_T_FABRIC_STOP)) | ||
| 488 | list_del_init(&cmd->i_conn_node); | 487 | list_del_init(&cmd->i_conn_node); |
| 489 | spin_unlock_bh(&conn->cmd_lock); | 488 | spin_unlock_bh(&conn->cmd_lock); |
| 490 | 489 | ||
| @@ -4083,12 +4082,22 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) · 3592 unmodified lines | |||
| 4083 | spin_lock_bh(&conn->cmd_lock); | 4082 | spin_lock_bh(&conn->cmd_lock); |
| 4084 | list_splice_init(&conn->conn_cmd_list, &tmp_list); | 4083 | list_splice_init(&conn->conn_cmd_list, &tmp_list); |
| 4085 | 4084 | ||
| 4086 | list_for_each_entry(cmd, &tmp_list, i_conn_node) { | 4085 | list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) { |
| 4087 | struct se_cmd *se_cmd = &cmd->se_cmd; | 4086 | struct se_cmd *se_cmd = &cmd->se_cmd; |
| 4088 | 4087 | ||
| 4089 | if (se_cmd->se_tfo != NULL) { | 4088 | if (se_cmd->se_tfo != NULL) { |
| 4090 | spin_lock_irq(&se_cmd->t_state_lock); | 4089 | spin_lock_irq(&se_cmd->t_state_lock); |
| 4091 | se_cmd->transport_state |= CMD_T_FABRIC_STOP; | 4090 | if (se_cmd->transport_state & CMD_T_ABORTED) { |
| 4091 | /* | ||
| 4092 | * LIO's abort path owns the cleanup for this, | ||
| 4093 | * so put it back on the list and let | ||
| 4094 | * aborted_task handle it. | ||
| 4095 | */ | ||
| 4096 | list_move_tail(&cmd->i_conn_node, | ||
| 4097 | &conn->conn_cmd_list); | ||
| 4098 | } else { | ||
| 4099 | se_cmd->transport_state |= CMD_T_FABRIC_STOP; | ||
| 4100 | } | ||
| 4092 | spin_unlock_irq(&se_cmd->t_state_lock); | 4101 | spin_unlock_irq(&se_cmd->t_state_lock); |
| 4093 | } | 4102 | } |
| 4094 | } | 4103 | } |
| @@ -534,7 +534,8 @@ void optee_free_pages_list(void *list, size_t num_entries) · 533 unmodified lines | |||
| 534 | static bool is_normal_memory(pgprot_t p) | 534 | static bool is_normal_memory(pgprot_t p) |
| 535 | { | 535 | { |
| 536 | #if defined(CONFIG_ARM) | 536 | #if defined(CONFIG_ARM) |
| 537 | return (pgprot_val(p) & L_PTE_MT_MASK) == L_PTE_MT_WRITEALLOC; | 537 | return (((pgprot_val(p) & L_PTE_MT_MASK) == L_PTE_MT_WRITEALLOC) || |
| 538 | ((pgprot_val(p) & L_PTE_MT_MASK) == L_PTE_MT_WRITEBACK)); | ||
| 538 | #elif defined(CONFIG_ARM64) | 539 | #elif defined(CONFIG_ARM64) |
| 539 | return (pgprot_val(p) & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL); | 540 | return (pgprot_val(p) & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL); |
| 540 | #else | 541 | #else |
| @@ -789,8 +789,10 @@ static int ar933x_uart_probe(struct platform_device *pdev) · 788 unmodified lines | |||
| 789 | goto err_disable_clk; | 789 | goto err_disable_clk; |
| 790 | 790 | ||
| 791 | up->gpios = mctrl_gpio_init(port, 0); | 791 | up->gpios = mctrl_gpio_init(port, 0); |
| 792 | if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) | 792 | if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) { |
| 793 | return PTR_ERR(up->gpios); | 793 | ret = PTR_ERR(up->gpios); |
| 794 | goto err_disable_clk; | ||
| 795 | } | ||
| 794 | 796 | ||
| 795 | up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS); | 797 | up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS); |
| 796 | 798 | ||
| @@ -942,8 +942,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) · 941 unmodified lines | |||
| 942 | struct imx_port *sport = dev_id; | 942 | struct imx_port *sport = dev_id; |
| 943 | unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4; | 943 | unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4; |
| 944 | irqreturn_t ret = IRQ_NONE; | 944 | irqreturn_t ret = IRQ_NONE; |
| 945 | unsigned long flags = 0; | ||
| 945 | 946 | ||
| 946 | spin_lock(&sport->port.lock); | 947 | /* |
| 948 | * IRQs might not be disabled upon entering this interrupt handler, | ||
| 949 | * e.g. when interrupt handlers are forced to be threaded. To support | ||
| 950 | * this scenario as well, disable IRQs when acquiring the spinlock. | ||
| 951 | */ | ||
| 952 | spin_lock_irqsave(&sport->port.lock, flags); | ||
| 947 | 953 | ||
| 948 | usr1 = imx_uart_readl(sport, USR1); | 954 | usr1 = imx_uart_readl(sport, USR1); |
| 949 | usr2 = imx_uart_readl(sport, USR2); | 955 | usr2 = imx_uart_readl(sport, USR2); |
| @@ -1013,7 +1019,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) · 63 unmodified lines | |||
| 1013 | ret = IRQ_HANDLED; | 1019 | ret = IRQ_HANDLED; |
| 1014 | } | 1020 | } |
| 1015 | 1021 | ||
| 1016 | spin_unlock(&sport->port.lock); | 1022 | spin_unlock_irqrestore(&sport->port.lock, flags); |
| 1017 | 1023 | ||
| 1018 | return ret; | 1024 | return ret; |
| 1019 | } | 1025 | } |
| @@ -2002,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) · 982 unmodified lines | |||
| 2002 | unsigned int ucr1; | 2008 | unsigned int ucr1; |
| 2003 | unsigned long flags = 0; | 2009 | unsigned long flags = 0; |
| 2004 | int locked = 1; | 2010 | int locked = 1; |
| 2005 | int retval; | ||
| 2006 | |||
| 2007 | retval = clk_enable(sport->clk_per); | ||
| 2008 | if (retval) | ||
| 2009 | return; | ||
| 2010 | retval = clk_enable(sport->clk_ipg); | ||
| 2011 | if (retval) { | ||
| 2012 | clk_disable(sport->clk_per); | ||
| 2013 | return; | ||
| 2014 | } | ||
| 2015 | 2011 | ||
| 2016 | if (sport->port.sysrq) | 2012 | if (sport->port.sysrq) |
| 2017 | locked = 0; | 2013 | locked = 0; |
| @@ -2047,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) · 29 unmodified lines | |||
| 2047 | 2043 | ||
| 2048 | if (locked) | 2044 | if (locked) |
| 2049 | spin_unlock_irqrestore(&sport->port.lock, flags); | 2045 | spin_unlock_irqrestore(&sport->port.lock, flags); |
| 2050 | |||
| 2051 | clk_disable(sport->clk_ipg); | ||
| 2052 | clk_disable(sport->clk_per); | ||
| 2053 | } | 2046 | } |
| 2054 | 2047 | ||
| 2055 | /* | 2048 | /* |
| @@ -2150,15 +2143,14 @@ imx_uart_console_setup(struct console *co, char *options) · 94 unmodified lines | |||
| 2150 | 2143 | ||
| 2151 | retval = uart_set_options(&sport->port, co, baud, parity, bits, flow); | 2144 | retval = uart_set_options(&sport->port, co, baud, parity, bits, flow); |
| 2152 | 2145 | ||
| 2153 | clk_disable(sport->clk_ipg); | ||
| 2154 | if (retval) { | 2146 | if (retval) { |
| 2155 | clk_unprepare(sport->clk_ipg); | 2147 | clk_disable_unprepare(sport->clk_ipg); |
| 2156 | goto error_console; | 2148 | goto error_console; |
| 2157 | } | 2149 | } |
| 2158 | 2150 | ||
| 2159 | retval = clk_prepare(sport->clk_per); | 2151 | retval = clk_prepare_enable(sport->clk_per); |
| 2160 | if (retval) | 2152 | if (retval) |
| 2161 | clk_unprepare(sport->clk_ipg); | 2153 | clk_disable_unprepare(sport->clk_ipg); |
| 2162 | 2154 | ||
| 2163 | error_console: | 2155 | error_console: |
| 2164 | return retval; | 2156 | return retval; |
| @@ -1093,7 +1093,12 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) · 1092 unmodified lines | |||
| 1093 | goto err1; | 1093 | goto err1; |
| 1094 | } | 1094 | } |
| 1095 | 1095 | ||
| 1096 | fb_virt = ioremap(par->mem->start, screen_fb_size); | 1096 | /* |
| 1097 | * Map the VRAM cacheable for performance. This is also required for | ||
| 1098 | * VM Connect to display properly for ARM64 Linux VM, as the host also | ||
| 1099 | * maps the VRAM cacheable. | ||
| 1100 | */ | ||
| 1101 | fb_virt = ioremap_cache(par->mem->start, screen_fb_size); | ||
| 1097 | if (!fb_virt) | 1102 | if (!fb_virt) |
| 1098 | goto err2; | 1103 | goto err2; |
| 1099 | 1104 | ||
| @@ -823,6 +823,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, · 822 unmodified lines | |||
| 823 | vp->cb_break_before = afs_calc_vnode_cb_break(vnode); | 823 | vp->cb_break_before = afs_calc_vnode_cb_break(vnode); |
| 824 | vp->vnode = vnode; | 824 | vp->vnode = vnode; |
| 825 | vp->put_vnode = true; | 825 | vp->put_vnode = true; |
| 826 | vp->speculative = true; /* vnode not locked */ | ||
| 826 | } | 827 | } |
| 827 | } | 828 | } |
| 828 | } | 829 | } |
| @@ -294,6 +294,13 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v · 293 unmodified lines | |||
| 294 | op->flags &= ~AFS_OPERATION_DIR_CONFLICT; | 294 | op->flags &= ~AFS_OPERATION_DIR_CONFLICT; |
| 295 | } | 295 | } |
| 296 | } else if (vp->scb.have_status) { | 296 | } else if (vp->scb.have_status) { |
| 297 | if (vp->dv_before + vp->dv_delta != vp->scb.status.data_version && | ||
| 298 | vp->speculative) | ||
| 299 | /* Ignore the result of a speculative bulk status fetch | ||
| 300 | * if it splits around a modification op, thereby | ||
| 301 | * appearing to regress the data version. | ||
| 302 | */ | ||
| 303 | goto out; | ||
| 297 | afs_apply_status(op, vp); | 304 | afs_apply_status(op, vp); |
| 298 | if (vp->scb.have_cb) | 305 | if (vp->scb.have_cb) |
| 299 | afs_apply_callback(op, vp); | 306 | afs_apply_callback(op, vp); |
| @@ -305,6 +312,7 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v · 5 unmodified lines | |||
| 305 | } | 312 | } |
| 306 | } | 313 | } |
| 307 | 314 | ||
| 315 | out: | ||
| 308 | write_sequnlock(&vnode->cb_lock); | 316 | write_sequnlock(&vnode->cb_lock); |
| 309 | 317 | ||
| 310 | if (vp->scb.have_status) | 318 | if (vp->scb.have_status) |
| @@ -755,6 +755,7 @@ struct afs_vnode_param { · 754 unmodified lines | |||
| 755 | bool update_ctime:1; /* Need to update the ctime */ | 755 | bool update_ctime:1; /* Need to update the ctime */ |
| 756 | bool set_size:1; /* Must update i_size */ | 756 | bool set_size:1; /* Must update i_size */ |
| 757 | bool op_unlinked:1; /* True if file was unlinked by op */ | 757 | bool op_unlinked:1; /* True if file was unlinked by op */ |
| 758 | bool speculative:1; /* T if speculative status fetch (no vnode lock) */ | ||
| 758 | }; | 759 | }; |
| 759 | 760 | ||
| 760 | /* | 761 | /* |
| @@ -878,7 +878,10 @@ struct btrfs_fs_info { · 877 unmodified lines | |||
| 878 | */ | 878 | */ |
| 879 | struct ulist *qgroup_ulist; | 879 | struct ulist *qgroup_ulist; |
| 880 | 880 | ||
| 881 | /* protect user change for quota operations */ | 881 | /* |
| 882 | * Protect user change for quota operations. If a transaction is needed, | ||
| 883 | * it must be started before locking this lock. | ||
| 884 | */ | ||
| 882 | struct mutex qgroup_ioctl_lock; | 885 | struct mutex qgroup_ioctl_lock; |
| 883 | 886 | ||
| 884 | /* list of dirty qgroups to be written at next commit */ | 887 | /* list of dirty qgroups to be written at next commit */ |
| @@ -452,46 +452,6 @@ static void btrfs_drop_pages(struct page **pages, size_t num_pages) · 451 unmodified lines | |||
| 452 | } | 452 | } |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode, | ||
| 456 | const u64 start, | ||
| 457 | const u64 len, | ||
| 458 | struct extent_state **cached_state) | ||
| 459 | { | ||
| 460 | u64 search_start = start; | ||
| 461 | const u64 end = start + len - 1; | ||
| 462 | |||
| 463 | while (search_start < end) { | ||
| 464 | const u64 search_len = end - search_start + 1; | ||
| 465 | struct extent_map *em; | ||
| 466 | u64 em_len; | ||
| 467 | int ret = 0; | ||
| 468 | |||
| 469 | em = btrfs_get_extent(inode, NULL, 0, search_start, search_len); | ||
| 470 | if (IS_ERR(em)) | ||
| 471 | return PTR_ERR(em); | ||
| 472 | |||
| 473 | if (em->block_start != EXTENT_MAP_HOLE) | ||
| 474 | goto next; | ||
| 475 | |||
| 476 | em_len = em->len; | ||
| 477 | if (em->start < search_start) | ||
| 478 | em_len -= search_start - em->start; | ||
| 479 | if (em_len > search_len) | ||
| 480 | em_len = search_len; | ||
| 481 | |||
| 482 | ret = set_extent_bit(&inode->io_tree, search_start, | ||
| 483 | search_start + em_len - 1, | ||
| 484 | EXTENT_DELALLOC_NEW, | ||
| 485 | NULL, cached_state, GFP_NOFS); | ||
| 486 | next: | ||
| 487 | search_start = extent_map_end(em); | ||
| 488 | free_extent_map(em); | ||
| 489 | if (ret) | ||
| 490 | return ret; | ||
| 491 | } | ||
| 492 | return 0; | ||
| 493 | } | ||
| 494 | |||
| 495 | /* | 455 | /* |
| 496 | * after copy_from_user, pages need to be dirtied and we need to make | 456 | * after copy_from_user, pages need to be dirtied and we need to make |
| 497 | * sure holes are created between the current EOF and the start of | 457 | * sure holes are created between the current EOF and the start of |
| @@ -528,23 +488,6 @@ int btrfs_dirty_pages(struct btrfs_inode *inode, struct page **pages, · 30 unmodified lines | |||
| 528 | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, | 488 | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, |
| 529 | 0, 0, cached); | 489 | 0, 0, cached); |
| 530 | 490 | ||
| 531 | if (!btrfs_is_free_space_inode(inode)) { | ||
| 532 | if (start_pos >= isize && | ||
| 533 | !(inode->flags & BTRFS_INODE_PREALLOC)) { | ||
| 534 | /* | ||
| 535 | * There can't be any extents following eof in this case | ||
| 536 | * so just set the delalloc new bit for the range | ||
| 537 | * directly. | ||
| 538 | */ | ||
| 539 | extra_bits |= EXTENT_DELALLOC_NEW; | ||
| 540 | } else { | ||
| 541 | err = btrfs_find_new_delalloc_bytes(inode, start_pos, | ||
| 542 | num_bytes, cached); | ||
| 543 | if (err) | ||
| 544 | return err; | ||
| 545 | } | ||
| 546 | } | ||
| 547 | |||
| 548 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, | 491 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
| 549 | extra_bits, cached); | 492 | extra_bits, cached); |
| 550 | if (err) | 493 | if (err) |
| @@ -2253,11 +2253,69 @@ static int add_pending_csums(struct btrfs_trans_handle *trans, · 2252 unmodified lines | |||
| 2253 | return 0; | 2253 | return 0; |
| 2254 | } | 2254 | } |
| 2255 | 2255 | ||
| 2256 | static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode, | ||
| 2257 | const u64 start, | ||
| 2258 | const u64 len, | ||
| 2259 | struct extent_state **cached_state) | ||
| 2260 | { | ||
| 2261 | u64 search_start = start; | ||
| 2262 | const u64 end = start + len - 1; | ||
| 2263 | |||
| 2264 | while (search_start < end) { | ||
| 2265 | const u64 search_len = end - search_start + 1; | ||
| 2266 | struct extent_map *em; | ||
| 2267 | u64 em_len; | ||
| 2268 | int ret = 0; | ||
| 2269 | |||
| 2270 | em = btrfs_get_extent(inode, NULL, 0, search_start, search_len); | ||
| 2271 | if (IS_ERR(em)) | ||
| 2272 | return PTR_ERR(em); | ||
| 2273 | |||
| 2274 | if (em->block_start != EXTENT_MAP_HOLE) | ||
| 2275 | goto next; | ||
| 2276 | |||
| 2277 | em_len = em->len; | ||
| 2278 | if (em->start < search_start) | ||
| 2279 | em_len -= search_start - em->start; | ||
| 2280 | if (em_len > search_len) | ||
| 2281 | em_len = search_len; | ||
| 2282 | |||
| 2283 | ret = set_extent_bit(&inode->io_tree, search_start, | ||
| 2284 | search_start + em_len - 1, | ||
| 2285 | EXTENT_DELALLOC_NEW, | ||
| 2286 | NULL, cached_state, GFP_NOFS); | ||
| 2287 | next: | ||
| 2288 | search_start = extent_map_end(em); | ||
| 2289 | free_extent_map(em); | ||
| 2290 | if (ret) | ||
| 2291 | return ret; | ||
| 2292 | } | ||
| 2293 | return 0; | ||
| 2294 | } | ||
| 2295 | |||
| 2256 | int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end, | 2296 | int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end, |
| 2257 | unsigned int extra_bits, | 2297 | unsigned int extra_bits, |
| 2258 | struct extent_state **cached_state) | 2298 | struct extent_state **cached_state) |
| 2259 | { | 2299 | { |
| 2260 | WARN_ON(PAGE_ALIGNED(end)); | 2300 | WARN_ON(PAGE_ALIGNED(end)); |
| 2301 | |||
| 2302 | if (start >= i_size_read(&inode->vfs_inode) && | ||
| 2303 | !(inode->flags & BTRFS_INODE_PREALLOC)) { | ||
| 2304 | /* | ||
| 2305 | * There can't be any extents following eof in this case so just | ||
| 2306 | * set the delalloc new bit for the range directly. | ||
| 2307 | */ | ||
| 2308 | extra_bits |= EXTENT_DELALLOC_NEW; | ||
| 2309 | } else { | ||
| 2310 | int ret; | ||
| 2311 | |||
| 2312 | ret = btrfs_find_new_delalloc_bytes(inode, start, | ||
| 2313 | end + 1 - start, | ||
| 2314 | cached_state); | ||
| 2315 | if (ret) | ||
| 2316 | return ret; | ||
| 2317 | } | ||
| 2318 | |||
| 2261 | return set_extent_delalloc(&inode->io_tree, start, end, extra_bits, | 2319 | return set_extent_delalloc(&inode->io_tree, start, end, extra_bits, |
| 2262 | cached_state); | 2320 | cached_state); |
| 2263 | } | 2321 | } |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
| 12 | #include <linux/workqueue.h> | 12 | #include <linux/workqueue.h> |
| 13 | #include <linux/btrfs.h> | 13 | #include <linux/btrfs.h> |
| 14 | #include <linux/sched/mm.h> | ||
| 14 | 15 | ||
| 15 | #include "ctree.h" | 16 | #include "ctree.h" |
| 16 | #include "transaction.h" | 17 | #include "transaction.h" |
| @@ -497,13 +498,13 @@ next2: · 480 unmodified lines | |||
| 497 | break; | 498 | break; |
| 498 | } | 499 | } |
| 499 | out: | 500 | out: |
| 501 | btrfs_free_path(path); | ||
| 500 | fs_info->qgroup_flags |= flags; | 502 | fs_info->qgroup_flags |= flags; |
| 501 | if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON)) | 503 | if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON)) |
| 502 | clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); | 504 | clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); |
| 503 | else if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN && | 505 | else if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN && |
| 504 | ret >= 0) | 506 | ret >= 0) |
| 505 | ret = qgroup_rescan_init(fs_info, rescan_progress, 0); | 507 | ret = qgroup_rescan_init(fs_info, rescan_progress, 0); |
| 506 | btrfs_free_path(path); | ||
| 507 | 508 | ||
| 508 | if (ret < 0) { | 509 | if (ret < 0) { |
| 509 | ulist_free(fs_info->qgroup_ulist); | 510 | ulist_free(fs_info->qgroup_ulist); |
| @@ -936,6 +937,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) · 426 unmodified lines | |||
| 936 | struct btrfs_key found_key; | 937 | struct btrfs_key found_key; |
| 937 | struct btrfs_qgroup *qgroup = NULL; | 938 | struct btrfs_qgroup *qgroup = NULL; |
| 938 | struct btrfs_trans_handle *trans = NULL; | 939 | struct btrfs_trans_handle *trans = NULL; |
| 940 | struct ulist *ulist = NULL; | ||
| 939 | int ret = 0; | 941 | int ret = 0; |
| 940 | int slot; | 942 | int slot; |
| 941 | 943 | ||
| @@ -943,8 +945,8 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) · 1 unmodified line | |||
| 943 | if (fs_info->quota_root) | 945 | if (fs_info->quota_root) |
| 944 | goto out; | 946 | goto out; |
| 945 | 947 | ||
| 946 | fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL); | 948 | ulist = ulist_alloc(GFP_KERNEL); |
| 947 | if (!fs_info->qgroup_ulist) { | 949 | if (!ulist) { |
| 948 | ret = -ENOMEM; | 950 | ret = -ENOMEM; |
| 949 | goto out; | 951 | goto out; |
| 950 | } | 952 | } |
| @@ -952,6 +954,22 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) · 1 unmodified line | |||
| 952 | ret = btrfs_sysfs_add_qgroups(fs_info); | 954 | ret = btrfs_sysfs_add_qgroups(fs_info); |
| 953 | if (ret < 0) | 955 | if (ret < 0) |
| 954 | goto out; | 956 | goto out; |
| 957 | |||
| 958 | /* | ||
| 959 | * Unlock qgroup_ioctl_lock before starting the transaction. This is to | ||
| 960 | * avoid lock acquisition inversion problems (reported by lockdep) between | ||
| 961 | * qgroup_ioctl_lock and the vfs freeze semaphores, acquired when we | ||
| 962 | * start a transaction. | ||
| 963 | * After we started the transaction lock qgroup_ioctl_lock again and | ||
| 964 | * check if someone else created the quota root in the meanwhile. If so, | ||
| 965 | * just return success and release the transaction handle. | ||
| 966 | * | ||
| 967 | * Also we don't need to worry about someone else calling | ||
| 968 | * btrfs_sysfs_add_qgroups() after we unlock and getting an error because | ||
| 969 | * that function returns 0 (success) when the sysfs entries already exist. | ||
| 970 | */ | ||
| 971 | mutex_unlock(&fs_info->qgroup_ioctl_lock); | ||
| 972 | |||
| 955 | /* | 973 | /* |
| 956 | * 1 for quota root item | 974 | * 1 for quota root item |
| 957 | * 1 for BTRFS_QGROUP_STATUS item | 975 | * 1 for BTRFS_QGROUP_STATUS item |
| @@ -961,12 +979,20 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) · 3 unmodified lines | |||
| 961 | * would be a lot of overkill. | 979 | * would be a lot of overkill. |
| 962 | */ | 980 | */ |
| 963 | trans = btrfs_start_transaction(tree_root, 2); | 981 | trans = btrfs_start_transaction(tree_root, 2); |
| 982 | |||
| 983 | mutex_lock(&fs_info->qgroup_ioctl_lock); | ||
| 964 | if (IS_ERR(trans)) { | 984 | if (IS_ERR(trans)) { |
| 965 | ret = PTR_ERR(trans); | 985 | ret = PTR_ERR(trans); |
| 966 | trans = NULL; | 986 | trans = NULL; |
| 967 | goto out; | 987 | goto out; |
| 968 | } | 988 | } |
| 969 | 989 | ||
| 990 | if (fs_info->quota_root) | ||
| 991 | goto out; | ||
| 992 | |||
| 993 | fs_info->qgroup_ulist = ulist; | ||
| 994 | ulist = NULL; | ||
| 995 | |||
| 970 | /* | 996 | /* |
| 971 | * initially create the quota tree | 997 | * initially create the quota tree |
| 972 | */ | 998 | */ |
| @@ -1124,11 +1150,14 @@ out: · 151 unmodified lines | |||
| 1124 | if (ret) { | 1150 | if (ret) { |
| 1125 | ulist_free(fs_info->qgroup_ulist); | 1151 | ulist_free(fs_info->qgroup_ulist); |
| 1126 | fs_info->qgroup_ulist = NULL; | 1152 | fs_info->qgroup_ulist = NULL; |
| 1127 | if (trans) | ||
| 1128 | btrfs_end_transaction(trans); | ||
| 1129 | btrfs_sysfs_del_qgroups(fs_info); | 1153 | btrfs_sysfs_del_qgroups(fs_info); |
| 1130 | } | 1154 | } |
| 1131 | mutex_unlock(&fs_info->qgroup_ioctl_lock); | 1155 | mutex_unlock(&fs_info->qgroup_ioctl_lock); |
| 1156 | if (ret && trans) | ||
| 1157 | btrfs_end_transaction(trans); | ||
| 1158 | else if (trans) | ||
| 1159 | ret = btrfs_end_transaction(trans); | ||
| 1160 | ulist_free(ulist); | ||
| 1132 | return ret; | 1161 | return ret; |
| 1133 | } | 1162 | } |
| 1134 | 1163 | ||
| @@ -1141,19 +1170,29 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) · 6 unmodified lines | |||
| 1141 | mutex_lock(&fs_info->qgroup_ioctl_lock); | 1170 | mutex_lock(&fs_info->qgroup_ioctl_lock); |
| 1142 | if (!fs_info->quota_root) | 1171 | if (!fs_info->quota_root) |
| 1143 | goto out; | 1172 | goto out; |
| 1173 | mutex_unlock(&fs_info->qgroup_ioctl_lock); | ||
| 1144 | 1174 | ||
| 1145 | /* | 1175 | /* |
| 1146 | * 1 For the root item | 1176 | * 1 For the root item |
| 1147 | * | 1177 | * |
| 1148 | * We should also reserve enough items for the quota tree deletion in | 1178 | * We should also reserve enough items for the quota tree deletion in |
| 1149 | * btrfs_clean_quota_tree but this is not done. | 1179 | * btrfs_clean_quota_tree but this is not done. |
| 1180 | * | ||
| 1181 | * Also, we must always start a transaction without holding the mutex | ||
| 1182 | * qgroup_ioctl_lock, see btrfs_quota_enable(). | ||
| 1150 | */ | 1183 | */ |
| 1151 | trans = btrfs_start_transaction(fs_info->tree_root, 1); | 1184 | trans = btrfs_start_transaction(fs_info->tree_root, 1); |
| 1185 | |||
| 1186 | mutex_lock(&fs_info->qgroup_ioctl_lock); | ||
| 1152 | if (IS_ERR(trans)) { | 1187 | if (IS_ERR(trans)) { |
| 1153 | ret = PTR_ERR(trans); | 1188 | ret = PTR_ERR(trans); |
| 1189 | trans = NULL; | ||
| 1154 | goto out; | 1190 | goto out; |
| 1155 | } | 1191 | } |
| 1156 | 1192 | ||
| 1193 | if (!fs_info->quota_root) | ||
| 1194 | goto out; | ||
| 1195 | |||
| 1157 | clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); | 1196 | clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); |
| 1158 | btrfs_qgroup_wait_for_completion(fs_info, false); | 1197 | btrfs_qgroup_wait_for_completion(fs_info, false); |
| 1159 | spin_lock(&fs_info->qgroup_lock); | 1198 | spin_lock(&fs_info->qgroup_lock); |
| @@ -1167,13 +1206,13 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) · 7 unmodified lines | |||
| 1167 | ret = btrfs_clean_quota_tree(trans, quota_root); | 1206 | ret = btrfs_clean_quota_tree(trans, quota_root); |
| 1168 | if (ret) { | 1207 | if (ret) { |
| 1169 | btrfs_abort_transaction(trans, ret); | 1208 | btrfs_abort_transaction(trans, ret); |
| 1170 | goto end_trans; | 1209 | goto out; |
| 1171 | } | 1210 | } |
| 1172 | 1211 | ||
| 1173 | ret = btrfs_del_root(trans, "a_root->root_key); | 1212 | ret = btrfs_del_root(trans, "a_root->root_key); |
| 1174 | if (ret) { | 1213 | if (ret) { |
| 1175 | btrfs_abort_transaction(trans, ret); | 1214 | btrfs_abort_transaction(trans, ret); |
| 1176 | goto end_trans; | 1215 | goto out; |
| 1177 | } | 1216 | } |
| 1178 | 1217 | ||
| 1179 | list_del("a_root->dirty_list); | 1218 | list_del("a_root->dirty_list); |
| @@ -1185,10 +1224,13 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) · 5 unmodified lines | |||
| 1185 | 1224 | ||
| 1186 | btrfs_put_root(quota_root); | 1225 | btrfs_put_root(quota_root); |
| 1187 | 1226 | ||
| 1188 | end_trans: | ||
| 1189 | ret = btrfs_end_transaction(trans); | ||
| 1190 | out: | 1227 | out: |
| 1191 | mutex_unlock(&fs_info->qgroup_ioctl_lock); | 1228 | mutex_unlock(&fs_info->qgroup_ioctl_lock); |
| 1229 | if (ret && trans) | ||
| 1230 | btrfs_end_transaction(trans); | ||
| 1231 | else if (trans) | ||
| 1232 | ret = btrfs_end_transaction(trans); | ||
| 1233 | |||
| 1192 | return ret; | 1234 | return ret; |
| 1193 | } | 1235 | } |
| 1194 | 1236 | ||
| @@ -1324,13 +1366,17 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, · 129 unmodified lines | |||
| 1324 | struct btrfs_qgroup *member; | 1366 | struct btrfs_qgroup *member; |
| 1325 | struct btrfs_qgroup_list *list; | 1367 | struct btrfs_qgroup_list *list; |
| 1326 | struct ulist *tmp; | 1368 | struct ulist *tmp; |
| 1369 | unsigned int nofs_flag; | ||
| 1327 | int ret = 0; | 1370 | int ret = 0; |
| 1328 | 1371 | ||
| 1329 | /* Check the level of src and dst first */ | 1372 | /* Check the level of src and dst first */ |
| 1330 | if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst)) | 1373 | if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst)) |
| 1331 | return -EINVAL; | 1374 | return -EINVAL; |
| 1332 | 1375 | ||
| 1376 | /* We hold a transaction handle open, must do a NOFS allocation. */ | ||
| 1377 | nofs_flag = memalloc_nofs_save(); | ||
| 1333 | tmp = ulist_alloc(GFP_KERNEL); | 1378 | tmp = ulist_alloc(GFP_KERNEL); |
| 1379 | memalloc_nofs_restore(nofs_flag); | ||
| 1334 | if (!tmp) | 1380 | if (!tmp) |
| 1335 | return -ENOMEM; | 1381 | return -ENOMEM; |
| 1336 | 1382 | ||
| @@ -1387,10 +1433,14 @@ static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, · 50 unmodified lines | |||
| 1387 | struct btrfs_qgroup_list *list; | 1433 | struct btrfs_qgroup_list *list; |
| 1388 | struct ulist *tmp; | 1434 | struct ulist *tmp; |
| 1389 | bool found = false; | 1435 | bool found = false; |
| 1436 | unsigned int nofs_flag; | ||
| 1390 | int ret = 0; | 1437 | int ret = 0; |
| 1391 | int ret2; | 1438 | int ret2; |
| 1392 | 1439 | ||
| 1440 | /* We hold a transaction handle open, must do a NOFS allocation. */ | ||
| 1441 | nofs_flag = memalloc_nofs_save(); | ||
| 1393 | tmp = ulist_alloc(GFP_KERNEL); | 1442 | tmp = ulist_alloc(GFP_KERNEL); |
| 1443 | memalloc_nofs_restore(nofs_flag); | ||
| 1394 | if (!tmp) | 1444 | if (!tmp) |
| 1395 | return -ENOMEM; | 1445 | return -ENOMEM; |
| 1396 | 1446 | ||
| @@ -3512,6 +3562,7 @@ static int try_flush_qgroup(struct btrfs_root *root) · 2115 unmodified lines | |||
| 3512 | { | 3562 | { |
| 3513 | struct btrfs_trans_handle *trans; | 3563 | struct btrfs_trans_handle *trans; |
| 3514 | int ret; | 3564 | int ret; |
| 3565 | bool can_commit = true; | ||
| 3515 | 3566 | ||
| 3516 | /* | 3567 | /* |
| 3517 | * We don't want to run flush again and again, so if there is a running | 3568 | * We don't want to run flush again and again, so if there is a running |
| @@ -3523,6 +3574,20 @@ static int try_flush_qgroup(struct btrfs_root *root) · 5 unmodified lines | |||
| 3523 | return 0; | 3574 | return 0; |
| 3524 | } | 3575 | } |
| 3525 | 3576 | ||
| 3577 | /* | ||
| 3578 | * If current process holds a transaction, we shouldn't flush, as we | ||
| 3579 | * assume all space reservation happens before a transaction handle is | ||
| 3580 | * held. | ||
| 3581 | * | ||
| 3582 | * But there are cases like btrfs_delayed_item_reserve_metadata() where | ||
| 3583 | * we try to reserve space with one transction handle already held. | ||
| 3584 | * In that case we can't commit transaction, but at least try to end it | ||
| 3585 | * and hope the started data writes can free some space. | ||
| 3586 | */ | ||
| 3587 | if (current->journal_info && | ||
| 3588 | current->journal_info != BTRFS_SEND_TRANS_STUB) | ||
| 3589 | can_commit = false; | ||
| 3590 | |||
| 3526 | ret = btrfs_start_delalloc_snapshot(root); | 3591 | ret = btrfs_start_delalloc_snapshot(root); |
| 3527 | if (ret < 0) | 3592 | if (ret < 0) |
| 3528 | goto out; | 3593 | goto out; |
| @@ -3534,7 +3599,10 @@ static int try_flush_qgroup(struct btrfs_root *root) · 5 unmodified lines | |||
| 3534 | goto out; | 3599 | goto out; |
| 3535 | } | 3600 | } |
| 3536 | 3601 | ||
| 3537 | ret = btrfs_commit_transaction(trans); | 3602 | if (can_commit) |
| 3603 | ret = btrfs_commit_transaction(trans); | ||
| 3604 | else | ||
| 3605 | ret = btrfs_end_transaction(trans); | ||
| 3538 | out: | 3606 | out: |
| 3539 | clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state); | 3607 | clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state); |
| 3540 | wake_up(&root->qgroup_flush_wait); | 3608 | wake_up(&root->qgroup_flush_wait); |
| @@ -983,7 +983,8 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) · 982 unmodified lines | |||
| 983 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, | 983 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, |
| 984 | BTRFS_MAX_EXTENT_SIZE >> 1, | 984 | BTRFS_MAX_EXTENT_SIZE >> 1, |
| 985 | (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1, | 985 | (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1, |
| 986 | EXTENT_DELALLOC | EXTENT_UPTODATE, 0, 0, NULL); | 986 | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | |
| 987 | EXTENT_UPTODATE, 0, 0, NULL); | ||
| 987 | if (ret) { | 988 | if (ret) { |
| 988 | test_err("clear_extent_bit returned %d", ret); | 989 | test_err("clear_extent_bit returned %d", ret); |
| 989 | goto out; | 990 | goto out; |
| @@ -1050,7 +1051,8 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) · 60 unmodified lines | |||
| 1050 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, | 1051 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, |
| 1051 | BTRFS_MAX_EXTENT_SIZE + sectorsize, | 1052 | BTRFS_MAX_EXTENT_SIZE + sectorsize, |
| 1052 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, | 1053 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, |
| 1053 | EXTENT_DELALLOC | EXTENT_UPTODATE, 0, 0, NULL); | 1054 | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | |
| 1055 | EXTENT_UPTODATE, 0, 0, NULL); | ||
| 1054 | if (ret) { | 1056 | if (ret) { |
| 1055 | test_err("clear_extent_bit returned %d", ret); | 1057 | test_err("clear_extent_bit returned %d", ret); |
| 1056 | goto out; | 1058 | goto out; |
| @@ -1082,7 +1084,8 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) · 25 unmodified lines | |||
| 1082 | 1084 | ||
| 1083 | /* Empty */ | 1085 | /* Empty */ |
| 1084 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, | 1086 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, |
| 1085 | EXTENT_DELALLOC | EXTENT_UPTODATE, 0, 0, NULL); | 1087 | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | |
| 1088 | EXTENT_UPTODATE, 0, 0, NULL); | ||
| 1086 | if (ret) { | 1089 | if (ret) { |
| 1087 | test_err("clear_extent_bit returned %d", ret); | 1090 | test_err("clear_extent_bit returned %d", ret); |
| 1088 | goto out; | 1091 | goto out; |
| @@ -1097,7 +1100,8 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) · 8 unmodified lines | |||
| 1097 | out: | 1100 | out: |
| 1098 | if (ret) | 1101 | if (ret) |
| 1099 | clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, | 1102 | clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, |
| 1100 | EXTENT_DELALLOC | EXTENT_UPTODATE, 0, 0, NULL); | 1103 | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | |
| 1104 | EXTENT_UPTODATE, 0, 0, NULL); | ||
| 1101 | iput(inode); | 1105 | iput(inode); |
| 1102 | btrfs_free_dummy_root(root); | 1106 | btrfs_free_dummy_root(root); |
| 1103 | btrfs_free_dummy_fs_info(fs_info); | 1107 | btrfs_free_dummy_fs_info(fs_info); |
| @@ -1068,6 +1068,7 @@ static int check_root_item(struct extent_buffer *leaf, struct btrfs_key *key, · 1067 unmodified lines | |||
| 1068 | "invalid root item size, have %u expect %zu or %u", | 1068 | "invalid root item size, have %u expect %zu or %u", |
| 1069 | btrfs_item_size_nr(leaf, slot), sizeof(ri), | 1069 | btrfs_item_size_nr(leaf, slot), sizeof(ri), |
| 1070 | btrfs_legacy_root_item_size()); | 1070 | btrfs_legacy_root_item_size()); |
| 1071 | return -EUCLEAN; | ||
| 1071 | } | 1072 | } |
| 1072 | 1073 | ||
| 1073 | /* | 1074 | /* |
| @@ -1423,6 +1424,7 @@ static int check_extent_data_ref(struct extent_buffer *leaf, · 349 unmodified lines | |||
| 1423 | "invalid item size, have %u expect aligned to %zu for key type %u", | 1424 | "invalid item size, have %u expect aligned to %zu for key type %u", |
| 1424 | btrfs_item_size_nr(leaf, slot), | 1425 | btrfs_item_size_nr(leaf, slot), |
| 1425 | sizeof(*dref), key->type); | 1426 | sizeof(*dref), key->type); |
| 1427 | return -EUCLEAN; | ||
| 1426 | } | 1428 | } |
| 1427 | if (!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize)) { | 1429 | if (!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize)) { |
| 1428 | generic_err(leaf, slot, | 1430 | generic_err(leaf, slot, |
| @@ -1451,6 +1453,7 @@ static int check_extent_data_ref(struct extent_buffer *leaf, · 22 unmodified lines | |||
| 1451 | extent_err(leaf, slot, | 1453 | extent_err(leaf, slot, |
| 1452 | "invalid extent data backref offset, have %llu expect aligned to %u", | 1454 | "invalid extent data backref offset, have %llu expect aligned to %u", |
| 1453 | offset, leaf->fs_info->sectorsize); | 1455 | offset, leaf->fs_info->sectorsize); |
| 1456 | return -EUCLEAN; | ||
| 1454 | } | 1457 | } |
| 1455 | } | 1458 | } |
| 1456 | return 0; | 1459 | return 0; |
| @@ -940,7 +940,13 @@ static noinline struct btrfs_device *device_list_add(const char *path, · 939 unmodified lines | |||
| 940 | if (device->bdev != path_bdev) { | 940 | if (device->bdev != path_bdev) { |
| 941 | bdput(path_bdev); | 941 | bdput(path_bdev); |
| 942 | mutex_unlock(&fs_devices->device_list_mutex); | 942 | mutex_unlock(&fs_devices->device_list_mutex); |
| 943 | btrfs_warn_in_rcu(device->fs_info, | 943 | /* |
| 944 | * device->fs_info may not be reliable here, so | ||
| 945 | * pass in a NULL instead. This avoids a | ||
| 946 | * possible use-after-free when the fs_info and | ||
| 947 | * fs_info->sb are already torn down. | ||
| 948 | */ | ||
| 949 | btrfs_warn_in_rcu(NULL, | ||
| 944 | "duplicate device %s devid %llu generation %llu scanned by %s (%d)", | 950 | "duplicate device %s devid %llu generation %llu scanned by %s (%d)", |
| 945 | path, devid, found_transid, | 951 | path, devid, found_transid, |
| 946 | current->comm, | 952 | current->comm, |
| @@ -1266,6 +1266,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, · 1265 unmodified lines | |||
| 1266 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); | 1266 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); |
| 1267 | } else if (mode_from_special_sid) { | 1267 | } else if (mode_from_special_sid) { |
| 1268 | rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true); | 1268 | rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true); |
| 1269 | kfree(pntsd); | ||
| 1269 | } else { | 1270 | } else { |
| 1270 | /* get approximated mode from ACL */ | 1271 | /* get approximated mode from ACL */ |
| 1271 | rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false); | 1272 | rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false); |
| @@ -264,7 +264,7 @@ smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val) · 263 unmodified lines | |||
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static struct mid_q_entry * | 266 | static struct mid_q_entry * |
| 267 | smb2_find_mid(struct TCP_Server_Info *server, char *buf) | 267 | __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue) |
| 268 | { | 268 | { |
| 269 | struct mid_q_entry *mid; | 269 | struct mid_q_entry *mid; |
| 270 | struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf; | 270 | struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf; |
| @@ -281,6 +281,10 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf) · 10 unmodified lines | |||
| 281 | (mid->mid_state == MID_REQUEST_SUBMITTED) && | 281 | (mid->mid_state == MID_REQUEST_SUBMITTED) && |
| 282 | (mid->command == shdr->Command)) { | 282 | (mid->command == shdr->Command)) { |
| 283 | kref_get(&mid->refcount); | 283 | kref_get(&mid->refcount); |
| 284 | if (dequeue) { | ||
| 285 | list_del_init(&mid->qhead); | ||
| 286 | mid->mid_flags |= MID_DELETED; | ||
| 287 | } | ||
| 284 | spin_unlock(&GlobalMid_Lock); | 288 | spin_unlock(&GlobalMid_Lock); |
| 285 | return mid; | 289 | return mid; |
| 286 | } | 290 | } |
| @@ -289,6 +293,18 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf) · 2 unmodified lines | |||
| 289 | return NULL; | 293 | return NULL; |
| 290 | } | 294 | } |
| 291 | 295 | ||
| 296 | static struct mid_q_entry * | ||
| 297 | smb2_find_mid(struct TCP_Server_Info *server, char *buf) | ||
| 298 | { | ||
| 299 | return __smb2_find_mid(server, buf, false); | ||
| 300 | } | ||
| 301 | |||
| 302 | static struct mid_q_entry * | ||
| 303 | smb2_find_dequeue_mid(struct TCP_Server_Info *server, char *buf) | ||
| 304 | { | ||
| 305 | return __smb2_find_mid(server, buf, true); | ||
| 306 | } | ||
| 307 | |||
| 292 | static void | 308 | static void |
| 293 | smb2_dump_detail(void *buf, struct TCP_Server_Info *server) | 309 | smb2_dump_detail(void *buf, struct TCP_Server_Info *server) |
| 294 | { | 310 | { |
| @@ -4356,7 +4372,8 @@ init_read_bvec(struct page **pages, unsigned int npages, unsigned int data_size, · 4061 unmodified lines | |||
| 4356 | static int | 4372 | static int |
| 4357 | handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, | 4373 | handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, |
| 4358 | char *buf, unsigned int buf_len, struct page **pages, | 4374 | char *buf, unsigned int buf_len, struct page **pages, |
| 4359 | unsigned int npages, unsigned int page_data_size) | 4375 | unsigned int npages, unsigned int page_data_size, |
| 4376 | bool is_offloaded) | ||
| 4360 | { | 4377 | { |
| 4361 | unsigned int data_offset; | 4378 | unsigned int data_offset; |
| 4362 | unsigned int data_len; | 4379 | unsigned int data_len; |
| @@ -4378,7 +4395,8 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 15 unmodified lines | |||
| 4378 | 4395 | ||
| 4379 | if (server->ops->is_session_expired && | 4396 | if (server->ops->is_session_expired && |
| 4380 | server->ops->is_session_expired(buf)) { | 4397 | server->ops->is_session_expired(buf)) { |
| 4381 | cifs_reconnect(server); | 4398 | if (!is_offloaded) |
| 4399 | cifs_reconnect(server); | ||
| 4382 | return -1; | 4400 | return -1; |
| 4383 | } | 4401 | } |
| 4384 | 4402 | ||
| @@ -4402,7 +4420,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 17 unmodified lines | |||
| 4402 | cifs_dbg(FYI, "%s: server returned error %d\n", | 4420 | cifs_dbg(FYI, "%s: server returned error %d\n", |
| 4403 | __func__, rdata->result); | 4421 | __func__, rdata->result); |
| 4404 | /* normal error on read response */ | 4422 | /* normal error on read response */ |
| 4405 | dequeue_mid(mid, false); | 4423 | if (is_offloaded) |
| 4424 | mid->mid_state = MID_RESPONSE_RECEIVED; | ||
| 4425 | else | ||
| 4426 | dequeue_mid(mid, false); | ||
| 4406 | return 0; | 4427 | return 0; |
| 4407 | } | 4428 | } |
| 4408 | 4429 | ||
| @@ -4426,7 +4447,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 17 unmodified lines | |||
| 4426 | cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n", | 4447 | cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n", |
| 4427 | __func__, data_offset); | 4448 | __func__, data_offset); |
| 4428 | rdata->result = -EIO; | 4449 | rdata->result = -EIO; |
| 4429 | dequeue_mid(mid, rdata->result); | 4450 | if (is_offloaded) |
| 4451 | mid->mid_state = MID_RESPONSE_MALFORMED; | ||
| 4452 | else | ||
| 4453 | dequeue_mid(mid, rdata->result); | ||
| 4430 | return 0; | 4454 | return 0; |
| 4431 | } | 4455 | } |
| 4432 | 4456 | ||
| @@ -4442,21 +4466,30 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 9 unmodified lines | |||
| 4442 | cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n", | 4466 | cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n", |
| 4443 | __func__, data_offset); | 4467 | __func__, data_offset); |
| 4444 | rdata->result = -EIO; | 4468 | rdata->result = -EIO; |
| 4445 | dequeue_mid(mid, rdata->result); | 4469 | if (is_offloaded) |
| 4470 | mid->mid_state = MID_RESPONSE_MALFORMED; | ||
| 4471 | else | ||
| 4472 | dequeue_mid(mid, rdata->result); | ||
| 4446 | return 0; | 4473 | return 0; |
| 4447 | } | 4474 | } |
| 4448 | 4475 | ||
| 4449 | if (data_len > page_data_size - pad_len) { | 4476 | if (data_len > page_data_size - pad_len) { |
| 4450 | /* data_len is corrupt -- discard frame */ | 4477 | /* data_len is corrupt -- discard frame */ |
| 4451 | rdata->result = -EIO; | 4478 | rdata->result = -EIO; |
| 4452 | dequeue_mid(mid, rdata->result); | 4479 | if (is_offloaded) |
| 4480 | mid->mid_state = MID_RESPONSE_MALFORMED; | ||
| 4481 | else | ||
| 4482 | dequeue_mid(mid, rdata->result); | ||
| 4453 | return 0; | 4483 | return 0; |
| 4454 | } | 4484 | } |
| 4455 | 4485 | ||
| 4456 | rdata->result = init_read_bvec(pages, npages, page_data_size, | 4486 | rdata->result = init_read_bvec(pages, npages, page_data_size, |
| 4457 | cur_off, &bvec); | 4487 | cur_off, &bvec); |
| 4458 | if (rdata->result != 0) { | 4488 | if (rdata->result != 0) { |
| 4459 | dequeue_mid(mid, rdata->result); | 4489 | if (is_offloaded) |
| 4490 | mid->mid_state = MID_RESPONSE_MALFORMED; | ||
| 4491 | else | ||
| 4492 | dequeue_mid(mid, rdata->result); | ||
| 4460 | return 0; | 4493 | return 0; |
| 4461 | } | 4494 | } |
| 4462 | 4495 | ||
| @@ -4471,7 +4504,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 8 unmodified lines | |||
| 4471 | /* read response payload cannot be in both buf and pages */ | 4504 | /* read response payload cannot be in both buf and pages */ |
| 4472 | WARN_ONCE(1, "buf can not contain only a part of read data"); | 4505 | WARN_ONCE(1, "buf can not contain only a part of read data"); |
| 4473 | rdata->result = -EIO; | 4506 | rdata->result = -EIO; |
| 4474 | dequeue_mid(mid, rdata->result); | 4507 | if (is_offloaded) |
| 4508 | mid->mid_state = MID_RESPONSE_MALFORMED; | ||
| 4509 | else | ||
| 4510 | dequeue_mid(mid, rdata->result); | ||
| 4475 | return 0; | 4511 | return 0; |
| 4476 | } | 4512 | } |
| 4477 | 4513 | ||
| @@ -4482,7 +4518,10 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 4 unmodified lines | |||
| 4482 | if (length < 0) | 4518 | if (length < 0) |
| 4483 | return length; | 4519 | return length; |
| 4484 | 4520 | ||
| 4485 | dequeue_mid(mid, false); | 4521 | if (is_offloaded) |
| 4522 | mid->mid_state = MID_RESPONSE_RECEIVED; | ||
| 4523 | else | ||
| 4524 | dequeue_mid(mid, false); | ||
| 4486 | return length; | 4525 | return length; |
| 4487 | } | 4526 | } |
| 4488 | 4527 | ||
| @@ -4511,15 +4550,34 @@ static void smb2_decrypt_offload(struct work_struct *work) · 22 unmodified lines | |||
| 4511 | } | 4550 | } |
| 4512 | 4551 | ||
| 4513 | dw->server->lstrp = jiffies; | 4552 | dw->server->lstrp = jiffies; |
| 4514 | mid = smb2_find_mid(dw->server, dw->buf); | 4553 | mid = smb2_find_dequeue_mid(dw->server, dw->buf); |
| 4515 | if (mid == NULL) | 4554 | if (mid == NULL) |
| 4516 | cifs_dbg(FYI, "mid not found\n"); | 4555 | cifs_dbg(FYI, "mid not found\n"); |
| 4517 | else { | 4556 | else { |
| 4518 | mid->decrypted = true; | 4557 | mid->decrypted = true; |
| 4519 | rc = handle_read_data(dw->server, mid, dw->buf, | 4558 | rc = handle_read_data(dw->server, mid, dw->buf, |
| 4520 | dw->server->vals->read_rsp_size, | 4559 | dw->server->vals->read_rsp_size, |
| 4521 | dw->ppages, dw->npages, dw->len); | 4560 | dw->ppages, dw->npages, dw->len, |
| 4522 | mid->callback(mid); | 4561 | true); |
| 4562 | if (rc >= 0) { | ||
| 4563 | #ifdef CONFIG_CIFS_STATS2 | ||
| 4564 | mid->when_received = jiffies; | ||
| 4565 | #endif | ||
| 4566 | mid->callback(mid); | ||
| 4567 | } else { | ||
| 4568 | spin_lock(&GlobalMid_Lock); | ||
| 4569 | if (dw->server->tcpStatus == CifsNeedReconnect) { | ||
| 4570 | mid->mid_state = MID_RETRY_NEEDED; | ||
| 4571 | spin_unlock(&GlobalMid_Lock); | ||
| 4572 | mid->callback(mid); | ||
| 4573 | } else { | ||
| 4574 | mid->mid_state = MID_REQUEST_SUBMITTED; | ||
| 4575 | mid->mid_flags &= ~(MID_DELETED); | ||
| 4576 | list_add_tail(&mid->qhead, | ||
| 4577 | &dw->server->pending_mid_q); | ||
| 4578 | spin_unlock(&GlobalMid_Lock); | ||
| 4579 | } | ||
| 4580 | } | ||
| 4523 | cifs_mid_q_entry_release(mid); | 4581 | cifs_mid_q_entry_release(mid); |
| 4524 | } | 4582 | } |
| 4525 | 4583 | ||
| @@ -4622,7 +4680,7 @@ non_offloaded_decrypt: · 96 unmodified lines | |||
| 4622 | (*mid)->decrypted = true; | 4680 | (*mid)->decrypted = true; |
| 4623 | rc = handle_read_data(server, *mid, buf, | 4681 | rc = handle_read_data(server, *mid, buf, |
| 4624 | server->vals->read_rsp_size, | 4682 | server->vals->read_rsp_size, |
| 4625 | pages, npages, len); | 4683 | pages, npages, len, false); |
| 4626 | } | 4684 | } |
| 4627 | 4685 | ||
| 4628 | free_pages: | 4686 | free_pages: |
| @@ -4765,7 +4823,7 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid) · 136 unmodified lines | |||
| 4765 | char *buf = server->large_buf ? server->bigbuf : server->smallbuf; | 4823 | char *buf = server->large_buf ? server->bigbuf : server->smallbuf; |
| 4766 | 4824 | ||
| 4767 | return handle_read_data(server, mid, buf, server->pdu_size, | 4825 | return handle_read_data(server, mid, buf, server->pdu_size, |
| 4768 | NULL, 0, 0); | 4826 | NULL, 0, 0, false); |
| 4769 | } | 4827 | } |
| 4770 | 4828 | ||
| 4771 | static int | 4829 | static int |
| @@ -21,6 +21,7 @@ LIST_HEAD(efivarfs_list); · 20 unmodified lines | |||
| 21 | static void efivarfs_evict_inode(struct inode *inode) | 21 | static void efivarfs_evict_inode(struct inode *inode) |
| 22 | { | 22 | { |
| 23 | clear_inode(inode); | 23 | clear_inode(inode); |
| 24 | kfree(inode->i_private); | ||
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | static const struct super_operations efivarfs_ops = { | 27 | static const struct super_operations efivarfs_ops = { |
| @@ -2695,7 +2695,8 @@ void ext4_insert_dentry(struct inode *inode, · 2694 unmodified lines | |||
| 2695 | struct ext4_filename *fname); | 2695 | struct ext4_filename *fname); |
| 2696 | static inline void ext4_update_dx_flag(struct inode *inode) | 2696 | static inline void ext4_update_dx_flag(struct inode *inode) |
| 2697 | { | 2697 | { |
| 2698 | if (!ext4_has_feature_dir_index(inode->i_sb)) { | 2698 | if (!ext4_has_feature_dir_index(inode->i_sb) && |
| 2699 | ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) { | ||
| 2699 | /* ext4_iget() should have caught this... */ | 2700 | /* ext4_iget() should have caught this... */ |
| 2700 | WARN_ON_ONCE(ext4_has_feature_metadata_csum(inode->i_sb)); | 2701 | WARN_ON_ONCE(ext4_has_feature_metadata_csum(inode->i_sb)); |
| 2701 | ext4_clear_inode_flag(inode, EXT4_INODE_INDEX); | 2702 | ext4_clear_inode_flag(inode, EXT4_INODE_INDEX); |
| @@ -2638,10 +2638,6 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb, · 2637 unmodified lines | |||
| 2638 | } else if (test_opt2(sb, DAX_INODE)) { | 2638 | } else if (test_opt2(sb, DAX_INODE)) { |
| 2639 | SEQ_OPTS_PUTS("dax=inode"); | 2639 | SEQ_OPTS_PUTS("dax=inode"); |
| 2640 | } | 2640 | } |
| 2641 | |||
| 2642 | if (test_opt2(sb, JOURNAL_FAST_COMMIT)) | ||
| 2643 | SEQ_OPTS_PUTS("fast_commit"); | ||
| 2644 | |||
| 2645 | ext4_show_quota_options(seq, sb); | 2641 | ext4_show_quota_options(seq, sb); |
| 2646 | return 0; | 2642 | return 0; |
| 2647 | } | 2643 | } |
| @@ -205,6 +205,7 @@ struct fixed_file_ref_node { · 204 unmodified lines | |||
| 205 | struct list_head file_list; | 205 | struct list_head file_list; |
| 206 | struct fixed_file_data *file_data; | 206 | struct fixed_file_data *file_data; |
| 207 | struct llist_node llist; | 207 | struct llist_node llist; |
| 208 | bool done; | ||
| 208 | }; | 209 | }; |
| 209 | 210 | ||
| 210 | struct fixed_file_data { | 211 | struct fixed_file_data { |
| @@ -478,6 +479,7 @@ struct io_sr_msg { · 267 unmodified lines | |||
| 478 | struct io_open { | 479 | struct io_open { |
| 479 | struct file *file; | 480 | struct file *file; |
| 480 | int dfd; | 481 | int dfd; |
| 482 | bool ignore_nonblock; | ||
| 481 | struct filename *filename; | 483 | struct filename *filename; |
| 482 | struct open_how how; | 484 | struct open_how how; |
| 483 | unsigned long nofile; | 485 | unsigned long nofile; |
| @@ -1311,22 +1313,6 @@ static bool io_grab_identity(struct io_kiocb *req) · 827 unmodified lines | |||
| 1311 | return false; | 1313 | return false; |
| 1312 | req->work.flags |= IO_WQ_WORK_FSIZE; | 1314 | req->work.flags |= IO_WQ_WORK_FSIZE; |
| 1313 | } | 1315 | } |
| 1314 | |||
| 1315 | if (!(req->work.flags & IO_WQ_WORK_FILES) && | ||
| 1316 | (def->work_flags & IO_WQ_WORK_FILES) && | ||
| 1317 | !(req->flags & REQ_F_NO_FILE_TABLE)) { | ||
| 1318 | if (id->files != current->files || | ||
| 1319 | id->nsproxy != current->nsproxy) | ||
| 1320 | return false; | ||
| 1321 | atomic_inc(&id->files->count); | ||
| 1322 | get_nsproxy(id->nsproxy); | ||
| 1323 | req->flags |= REQ_F_INFLIGHT; | ||
| 1324 | |||
| 1325 | spin_lock_irq(&ctx->inflight_lock); | ||
| 1326 | list_add(&req->inflight_entry, &ctx->inflight_list); | ||
| 1327 | spin_unlock_irq(&ctx->inflight_lock); | ||
| 1328 | req->work.flags |= IO_WQ_WORK_FILES; | ||
| 1329 | } | ||
| 1330 | #ifdef CONFIG_BLK_CGROUP | 1316 | #ifdef CONFIG_BLK_CGROUP |
| 1331 | if (!(req->work.flags & IO_WQ_WORK_BLKCG) && | 1317 | if (!(req->work.flags & IO_WQ_WORK_BLKCG) && |
| 1332 | (def->work_flags & IO_WQ_WORK_BLKCG)) { | 1318 | (def->work_flags & IO_WQ_WORK_BLKCG)) { |
| @@ -1368,6 +1354,21 @@ static bool io_grab_identity(struct io_kiocb *req) · 35 unmodified lines | |||
| 1368 | } | 1354 | } |
| 1369 | spin_unlock(¤t->fs->lock); | 1355 | spin_unlock(¤t->fs->lock); |
| 1370 | } | 1356 | } |
| 1357 | if (!(req->work.flags & IO_WQ_WORK_FILES) && | ||
| 1358 | (def->work_flags & IO_WQ_WORK_FILES) && | ||
| 1359 | !(req->flags & REQ_F_NO_FILE_TABLE)) { | ||
| 1360 | if (id->files != current->files || | ||
| 1361 | id->nsproxy != current->nsproxy) | ||
| 1362 | return false; | ||
| 1363 | atomic_inc(&id->files->count); | ||
| 1364 | get_nsproxy(id->nsproxy); | ||
| 1365 | req->flags |= REQ_F_INFLIGHT; | ||
| 1366 | |||
| 1367 | spin_lock_irq(&ctx->inflight_lock); | ||
| 1368 | list_add(&req->inflight_entry, &ctx->inflight_list); | ||
| 1369 | spin_unlock_irq(&ctx->inflight_lock); | ||
| 1370 | req->work.flags |= IO_WQ_WORK_FILES; | ||
| 1371 | } | ||
| 1371 | 1372 | ||
| 1372 | return true; | 1373 | return true; |
| 1373 | } | 1374 | } |
| @@ -2577,7 +2578,6 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error) · 1203 unmodified lines | |||
| 2577 | } | 2578 | } |
| 2578 | end_req: | 2579 | end_req: |
| 2579 | req_set_fail_links(req); | 2580 | req_set_fail_links(req); |
| 2580 | io_req_complete(req, ret); | ||
| 2581 | return false; | 2581 | return false; |
| 2582 | } | 2582 | } |
| 2583 | #endif | 2583 | #endif |
| @@ -3192,7 +3192,7 @@ static void io_req_map_rw(struct io_kiocb *req, const struct iovec *iovec, · 608 unmodified lines | |||
| 3192 | rw->free_iovec = iovec; | 3192 | rw->free_iovec = iovec; |
| 3193 | rw->bytes_done = 0; | 3193 | rw->bytes_done = 0; |
| 3194 | /* can only be fixed buffers, no need to do anything */ | 3194 | /* can only be fixed buffers, no need to do anything */ |
| 3195 | if (iter->type == ITER_BVEC) | 3195 | if (iov_iter_is_bvec(iter)) |
| 3196 | return; | 3196 | return; |
| 3197 | if (!iovec) { | 3197 | if (!iovec) { |
| 3198 | unsigned iov_off = 0; | 3198 | unsigned iov_off = 0; |
| @@ -3795,6 +3795,7 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe · 596 unmodified lines | |||
| 3795 | return ret; | 3795 | return ret; |
| 3796 | } | 3796 | } |
| 3797 | req->open.nofile = rlimit(RLIMIT_NOFILE); | 3797 | req->open.nofile = rlimit(RLIMIT_NOFILE); |
| 3798 | req->open.ignore_nonblock = false; | ||
| 3798 | req->flags |= REQ_F_NEED_CLEANUP; | 3799 | req->flags |= REQ_F_NEED_CLEANUP; |
| 3799 | return 0; | 3800 | return 0; |
| 3800 | } | 3801 | } |
| @@ -3838,7 +3839,7 @@ static int io_openat2(struct io_kiocb *req, bool force_nonblock) · 37 unmodified lines | |||
| 3838 | struct file *file; | 3839 | struct file *file; |
| 3839 | int ret; | 3840 | int ret; |
| 3840 | 3841 | ||
| 3841 | if (force_nonblock) | 3842 | if (force_nonblock && !req->open.ignore_nonblock) |
| 3842 | return -EAGAIN; | 3843 | return -EAGAIN; |
| 3843 | 3844 | ||
| 3844 | ret = build_open_flags(&req->open.how, &op); | 3845 | ret = build_open_flags(&req->open.how, &op); |
| @@ -3853,6 +3854,21 @@ static int io_openat2(struct io_kiocb *req, bool force_nonblock) · 8 unmodified lines | |||
| 3853 | if (IS_ERR(file)) { | 3854 | if (IS_ERR(file)) { |
| 3854 | put_unused_fd(ret); | 3855 | put_unused_fd(ret); |
| 3855 | ret = PTR_ERR(file); | 3856 | ret = PTR_ERR(file); |
| 3857 | /* | ||
| 3858 | * A work-around to ensure that /proc/self works that way | ||
| 3859 | * that it should - if we get -EOPNOTSUPP back, then assume | ||
| 3860 | * that proc_self_get_link() failed us because we're in async | ||
| 3861 | * context. We should be safe to retry this from the task | ||
| 3862 | * itself with force_nonblock == false set, as it should not | ||
| 3863 | * block on lookup. Would be nice to know this upfront and | ||
| 3864 | * avoid the async dance, but doesn't seem feasible. | ||
| 3865 | */ | ||
| 3866 | if (ret == -EOPNOTSUPP && io_wq_current_is_worker()) { | ||
| 3867 | req->open.ignore_nonblock = true; | ||
| 3868 | refcount_inc(&req->refs); | ||
| 3869 | io_req_task_queue(req); | ||
| 3870 | return 0; | ||
| 3871 | } | ||
| 3856 | } else { | 3872 | } else { |
| 3857 | fsnotify_open(file); | 3873 | fsnotify_open(file); |
| 3858 | fd_install(ret, file); | 3874 | fd_install(ret, file); |
| @@ -6957,9 +6973,7 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx) · 3098 unmodified lines | |||
| 6957 | return -ENXIO; | 6973 | return -ENXIO; |
| 6958 | 6974 | ||
| 6959 | spin_lock(&data->lock); | 6975 | spin_lock(&data->lock); |
| 6960 | if (!list_empty(&data->ref_list)) | 6976 | ref_node = data->node; |
| 6961 | ref_node = list_first_entry(&data->ref_list, | ||
| 6962 | struct fixed_file_ref_node, node); | ||
| 6963 | spin_unlock(&data->lock); | 6977 | spin_unlock(&data->lock); |
| 6964 | if (ref_node) | 6978 | if (ref_node) |
| 6965 | percpu_ref_kill(&ref_node->refs); | 6979 | percpu_ref_kill(&ref_node->refs); |
| @@ -7308,10 +7322,6 @@ static void __io_file_put_work(struct fixed_file_ref_node *ref_node) · 342 unmodified lines | |||
| 7308 | kfree(pfile); | 7322 | kfree(pfile); |
| 7309 | } | 7323 | } |
| 7310 | 7324 | ||
| 7311 | spin_lock(&file_data->lock); | ||
| 7312 | list_del(&ref_node->node); | ||
| 7313 | spin_unlock(&file_data->lock); | ||
| 7314 | |||
| 7315 | percpu_ref_exit(&ref_node->refs); | 7325 | percpu_ref_exit(&ref_node->refs); |
| 7316 | kfree(ref_node); | 7326 | kfree(ref_node); |
| 7317 | percpu_ref_put(&file_data->refs); | 7327 | percpu_ref_put(&file_data->refs); |
| @@ -7338,17 +7348,32 @@ static void io_file_put_work(struct work_struct *work) · 20 unmodified lines | |||
| 7338 | static void io_file_data_ref_zero(struct percpu_ref *ref) | 7348 | static void io_file_data_ref_zero(struct percpu_ref *ref) |
| 7339 | { | 7349 | { |
| 7340 | struct fixed_file_ref_node *ref_node; | 7350 | struct fixed_file_ref_node *ref_node; |
| 7351 | struct fixed_file_data *data; | ||
| 7341 | struct io_ring_ctx *ctx; | 7352 | struct io_ring_ctx *ctx; |
| 7342 | bool first_add; | 7353 | bool first_add = false; |
| 7343 | int delay = HZ; | 7354 | int delay = HZ; |
| 7344 | 7355 | ||
| 7345 | ref_node = container_of(ref, struct fixed_file_ref_node, refs); | 7356 | ref_node = container_of(ref, struct fixed_file_ref_node, refs); |
| 7346 | ctx = ref_node->file_data->ctx; | 7357 | data = ref_node->file_data; |
| 7358 | ctx = data->ctx; | ||
| 7359 | |||
| 7360 | spin_lock(&data->lock); | ||
| 7361 | ref_node->done = true; | ||
| 7347 | 7362 | ||
| 7348 | if (percpu_ref_is_dying(&ctx->file_data->refs)) | 7363 | while (!list_empty(&data->ref_list)) { |
| 7364 | ref_node = list_first_entry(&data->ref_list, | ||
| 7365 | struct fixed_file_ref_node, node); | ||
| 7366 | /* recycle ref nodes in order */ | ||
| 7367 | if (!ref_node->done) | ||
| 7368 | break; | ||
| 7369 | list_del(&ref_node->node); | ||
| 7370 | first_add |= llist_add(&ref_node->llist, &ctx->file_put_llist); | ||
| 7371 | } | ||
| 7372 | spin_unlock(&data->lock); | ||
| 7373 | |||
| 7374 | if (percpu_ref_is_dying(&data->refs)) | ||
| 7349 | delay = 0; | 7375 | delay = 0; |
| 7350 | 7376 | ||
| 7351 | first_add = llist_add(&ref_node->llist, &ctx->file_put_llist); | ||
| 7352 | if (!delay) | 7377 | if (!delay) |
| 7353 | mod_delayed_work(system_wq, &ctx->file_put_work, 0); | 7378 | mod_delayed_work(system_wq, &ctx->file_put_work, 0); |
| 7354 | else if (first_add) | 7379 | else if (first_add) |
| @@ -7372,6 +7397,7 @@ static struct fixed_file_ref_node *alloc_fixed_file_ref_node( · 17 unmodified lines | |||
| 7372 | INIT_LIST_HEAD(&ref_node->node); | 7397 | INIT_LIST_HEAD(&ref_node->node); |
| 7373 | INIT_LIST_HEAD(&ref_node->file_list); | 7398 | INIT_LIST_HEAD(&ref_node->file_list); |
| 7374 | ref_node->file_data = ctx->file_data; | 7399 | ref_node->file_data = ctx->file_data; |
| 7400 | ref_node->done = false; | ||
| 7375 | return ref_node; | 7401 | return ref_node; |
| 7376 | } | 7402 | } |
| 7377 | 7403 | ||
| @@ -7467,7 +7493,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, · 89 unmodified lines | |||
| 7467 | 7493 | ||
| 7468 | file_data->node = ref_node; | 7494 | file_data->node = ref_node; |
| 7469 | spin_lock(&file_data->lock); | 7495 | spin_lock(&file_data->lock); |
| 7470 | list_add(&ref_node->node, &file_data->ref_list); | 7496 | list_add_tail(&ref_node->node, &file_data->ref_list); |
| 7471 | spin_unlock(&file_data->lock); | 7497 | spin_unlock(&file_data->lock); |
| 7472 | percpu_ref_get(&file_data->refs); | 7498 | percpu_ref_get(&file_data->refs); |
| 7473 | return ret; | 7499 | return ret; |
| @@ -7626,7 +7652,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, · 152 unmodified lines | |||
| 7626 | if (needs_switch) { | 7652 | if (needs_switch) { |
| 7627 | percpu_ref_kill(&data->node->refs); | 7653 | percpu_ref_kill(&data->node->refs); |
| 7628 | spin_lock(&data->lock); | 7654 | spin_lock(&data->lock); |
| 7629 | list_add(&ref_node->node, &data->ref_list); | 7655 | list_add_tail(&ref_node->node, &data->ref_list); |
| 7630 | data->node = ref_node; | 7656 | data->node = ref_node; |
| 7631 | spin_unlock(&data->lock); | 7657 | spin_unlock(&data->lock); |
| 7632 | percpu_ref_get(&ctx->file_data->refs); | 7658 | percpu_ref_get(&ctx->file_data->refs); |
| @@ -9225,14 +9251,16 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p, · 1592 unmodified lines | |||
| 9225 | * to a power-of-two, if it isn't already. We do NOT impose | 9251 | * to a power-of-two, if it isn't already. We do NOT impose |
| 9226 | * any cq vs sq ring sizing. | 9252 | * any cq vs sq ring sizing. |
| 9227 | */ | 9253 | */ |
| 9228 | p->cq_entries = roundup_pow_of_two(p->cq_entries); | 9254 | if (!p->cq_entries) |
| 9229 | if (p->cq_entries < p->sq_entries) | ||
| 9230 | return -EINVAL; | 9255 | return -EINVAL; |
| 9231 | if (p->cq_entries > IORING_MAX_CQ_ENTRIES) { | 9256 | if (p->cq_entries > IORING_MAX_CQ_ENTRIES) { |
| 9232 | if (!(p->flags & IORING_SETUP_CLAMP)) | 9257 | if (!(p->flags & IORING_SETUP_CLAMP)) |
| 9233 | return -EINVAL; | 9258 | return -EINVAL; |
| 9234 | p->cq_entries = IORING_MAX_CQ_ENTRIES; | 9259 | p->cq_entries = IORING_MAX_CQ_ENTRIES; |
| 9235 | } | 9260 | } |
| 9261 | p->cq_entries = roundup_pow_of_two(p->cq_entries); | ||
| 9262 | if (p->cq_entries < p->sq_entries) | ||
| 9263 | return -EINVAL; | ||
| 9236 | } else { | 9264 | } else { |
| 9237 | p->cq_entries = 2 * p->sq_entries; | 9265 | p->cq_entries = 2 * p->sq_entries; |
| 9238 | } | 9266 | } |
| @@ -566,12 +566,14 @@ static int __jbd2_journal_force_commit(journal_t *journal) · 565 unmodified lines | |||
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | /** | 568 | /** |
| 569 | * Force and wait upon a commit if the calling process is not within | 569 | * jbd2_journal_force_commit_nested - Force and wait upon a commit if the |
| 570 | * transaction. This is used for forcing out undo-protected data which contains | 570 | * calling process is not within transaction. |
| 571 | * bitmaps, when the fs is running out of space. | ||
| 572 | * | 571 | * |
| 573 | * @journal: journal to force | 572 | * @journal: journal to force |
| 574 | * Returns true if progress was made. | 573 | * Returns true if progress was made. |
| 574 | * | ||
| 575 | * This is used for forcing out undo-protected data which contains | ||
| 576 | * bitmaps, when the fs is running out of space. | ||
| 575 | */ | 577 | */ |
| 576 | int jbd2_journal_force_commit_nested(journal_t *journal) | 578 | int jbd2_journal_force_commit_nested(journal_t *journal) |
| 577 | { | 579 | { |
| @@ -582,7 +584,7 @@ int jbd2_journal_force_commit_nested(journal_t *journal) · 4 unmodified lines | |||
| 582 | } | 584 | } |
| 583 | 585 | ||
| 584 | /** | 586 | /** |
| 585 | * int journal_force_commit() - force any uncommitted transactions | 587 | * jbd2_journal_force_commit() - force any uncommitted transactions |
| 586 | * @journal: journal to force | 588 | * @journal: journal to force |
| 587 | * | 589 | * |
| 588 | * Caller want unconditional commit. We can only force the running transaction | 590 | * Caller want unconditional commit. We can only force the running transaction |
| @@ -1881,7 +1883,7 @@ static int load_superblock(journal_t *journal) · 1292 unmodified lines | |||
| 1881 | 1883 | ||
| 1882 | 1884 | ||
| 1883 | /** | 1885 | /** |
| 1884 | * int jbd2_journal_load() - Read journal from disk. | 1886 | * jbd2_journal_load() - Read journal from disk. |
| 1885 | * @journal: Journal to act on. | 1887 | * @journal: Journal to act on. |
| 1886 | * | 1888 | * |
| 1887 | * Given a journal_t structure which tells us which disk blocks contain | 1889 | * Given a journal_t structure which tells us which disk blocks contain |
| @@ -1951,7 +1953,7 @@ recovery_error: · 63 unmodified lines | |||
| 1951 | } | 1953 | } |
| 1952 | 1954 | ||
| 1953 | /** | 1955 | /** |
| 1954 | * void jbd2_journal_destroy() - Release a journal_t structure. | 1956 | * jbd2_journal_destroy() - Release a journal_t structure. |
| 1955 | * @journal: Journal to act on. | 1957 | * @journal: Journal to act on. |
| 1956 | * | 1958 | * |
| 1957 | * Release a journal_t structure once it is no longer in use by the | 1959 | * Release a journal_t structure once it is no longer in use by the |
| @@ -2028,7 +2030,7 @@ int jbd2_journal_destroy(journal_t *journal) · 70 unmodified lines | |||
| 2028 | 2030 | ||
| 2029 | 2031 | ||
| 2030 | /** | 2032 | /** |
| 2031 | *int jbd2_journal_check_used_features() - Check if features specified are used. | 2033 | * jbd2_journal_check_used_features() - Check if features specified are used. |
| 2032 | * @journal: Journal to check. | 2034 | * @journal: Journal to check. |
| 2033 | * @compat: bitmask of compatible features | 2035 | * @compat: bitmask of compatible features |
| 2034 | * @ro: bitmask of features that force read-only mount | 2036 | * @ro: bitmask of features that force read-only mount |
| @@ -2063,7 +2065,7 @@ int jbd2_journal_check_used_features(journal_t *journal, unsigned long compat, · 28 unmodified lines | |||
| 2063 | } | 2065 | } |
| 2064 | 2066 | ||
| 2065 | /** | 2067 | /** |
| 2066 | * int jbd2_journal_check_available_features() - Check feature set in journalling layer | 2068 | * jbd2_journal_check_available_features() - Check feature set in journalling layer |
| 2067 | * @journal: Journal to check. | 2069 | * @journal: Journal to check. |
| 2068 | * @compat: bitmask of compatible features | 2070 | * @compat: bitmask of compatible features |
| 2069 | * @ro: bitmask of features that force read-only mount | 2071 | * @ro: bitmask of features that force read-only mount |
| @@ -2126,7 +2128,7 @@ jbd2_journal_initialize_fast_commit(journal_t *journal) · 56 unmodified lines | |||
| 2126 | } | 2128 | } |
| 2127 | 2129 | ||
| 2128 | /** | 2130 | /** |
| 2129 | * int jbd2_journal_set_features() - Mark a given journal feature in the superblock | 2131 | * jbd2_journal_set_features() - Mark a given journal feature in the superblock |
| 2130 | * @journal: Journal to act on. | 2132 | * @journal: Journal to act on. |
| 2131 | * @compat: bitmask of compatible features | 2133 | * @compat: bitmask of compatible features |
| 2132 | * @ro: bitmask of features that force read-only mount | 2134 | * @ro: bitmask of features that force read-only mount |
| @@ -2217,7 +2219,7 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat, · 84 unmodified lines | |||
| 2217 | } | 2219 | } |
| 2218 | 2220 | ||
| 2219 | /* | 2221 | /* |
| 2220 | * jbd2_journal_clear_features () - Clear a given journal feature in the | 2222 | * jbd2_journal_clear_features() - Clear a given journal feature in the |
| 2221 | * superblock | 2223 | * superblock |
| 2222 | * @journal: Journal to act on. | 2224 | * @journal: Journal to act on. |
| 2223 | * @compat: bitmask of compatible features | 2225 | * @compat: bitmask of compatible features |
| @@ -2246,7 +2248,7 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat, · 22 unmodified lines | |||
| 2246 | EXPORT_SYMBOL(jbd2_journal_clear_features); | 2248 | EXPORT_SYMBOL(jbd2_journal_clear_features); |
| 2247 | 2249 | ||
| 2248 | /** | 2250 | /** |
| 2249 | * int jbd2_journal_flush () - Flush journal | 2251 | * jbd2_journal_flush() - Flush journal |
| 2250 | * @journal: Journal to act on. | 2252 | * @journal: Journal to act on. |
| 2251 | * | 2253 | * |
| 2252 | * Flush all data for a given journal to disk and empty the journal. | 2254 | * Flush all data for a given journal to disk and empty the journal. |
| @@ -2321,7 +2323,7 @@ out: · 68 unmodified lines | |||
| 2321 | } | 2323 | } |
| 2322 | 2324 | ||
| 2323 | /** | 2325 | /** |
| 2324 | * int jbd2_journal_wipe() - Wipe journal contents | 2326 | * jbd2_journal_wipe() - Wipe journal contents |
| 2325 | * @journal: Journal to act on. | 2327 | * @journal: Journal to act on. |
| 2326 | * @write: flag (see below) | 2328 | * @write: flag (see below) |
| 2327 | * | 2329 | * |
| @@ -2362,7 +2364,7 @@ int jbd2_journal_wipe(journal_t *journal, int write) · 34 unmodified lines | |||
| 2362 | } | 2364 | } |
| 2363 | 2365 | ||
| 2364 | /** | 2366 | /** |
| 2365 | * void jbd2_journal_abort () - Shutdown the journal immediately. | 2367 | * jbd2_journal_abort () - Shutdown the journal immediately. |
| 2366 | * @journal: the journal to shutdown. | 2368 | * @journal: the journal to shutdown. |
| 2367 | * @errno: an error number to record in the journal indicating | 2369 | * @errno: an error number to record in the journal indicating |
| 2368 | * the reason for the shutdown. | 2370 | * the reason for the shutdown. |
| @@ -2453,7 +2455,7 @@ void jbd2_journal_abort(journal_t *journal, int errno) · 84 unmodified lines | |||
| 2453 | } | 2455 | } |
| 2454 | 2456 | ||
| 2455 | /** | 2457 | /** |
| 2456 | * int jbd2_journal_errno () - returns the journal's error state. | 2458 | * jbd2_journal_errno() - returns the journal's error state. |
| 2457 | * @journal: journal to examine. | 2459 | * @journal: journal to examine. |
| 2458 | * | 2460 | * |
| 2459 | * This is the errno number set with jbd2_journal_abort(), the last | 2461 | * This is the errno number set with jbd2_journal_abort(), the last |
| @@ -2477,7 +2479,7 @@ int jbd2_journal_errno(journal_t *journal) · 17 unmodified lines | |||
| 2477 | } | 2479 | } |
| 2478 | 2480 | ||
| 2479 | /** | 2481 | /** |
| 2480 | * int jbd2_journal_clear_err () - clears the journal's error state | 2482 | * jbd2_journal_clear_err() - clears the journal's error state |
| 2481 | * @journal: journal to act on. | 2483 | * @journal: journal to act on. |
| 2482 | * | 2484 | * |
| 2483 | * An error must be cleared or acked to take a FS out of readonly | 2485 | * An error must be cleared or acked to take a FS out of readonly |
| @@ -2497,7 +2499,7 @@ int jbd2_journal_clear_err(journal_t *journal) · 13 unmodified lines | |||
| 2497 | } | 2499 | } |
| 2498 | 2500 | ||
| 2499 | /** | 2501 | /** |
| 2500 | * void jbd2_journal_ack_err() - Ack journal err. | 2502 | * jbd2_journal_ack_err() - Ack journal err. |
| 2501 | * @journal: journal to act on. | 2503 | * @journal: journal to act on. |
| 2502 | * | 2504 | * |
| 2503 | * An error must be cleared or acked to take a FS out of readonly | 2505 | * An error must be cleared or acked to take a FS out of readonly |
| @@ -519,7 +519,7 @@ EXPORT_SYMBOL(jbd2__journal_start); · 518 unmodified lines | |||
| 519 | 519 | ||
| 520 | 520 | ||
| 521 | /** | 521 | /** |
| 522 | * handle_t *jbd2_journal_start() - Obtain a new handle. | 522 | * jbd2_journal_start() - Obtain a new handle. |
| 523 | * @journal: Journal to start transaction on. | 523 | * @journal: Journal to start transaction on. |
| 524 | * @nblocks: number of block buffer we might modify | 524 | * @nblocks: number of block buffer we might modify |
| 525 | * | 525 | * |
| @@ -566,7 +566,7 @@ void jbd2_journal_free_reserved(handle_t *handle) · 40 unmodified lines | |||
| 566 | EXPORT_SYMBOL(jbd2_journal_free_reserved); | 566 | EXPORT_SYMBOL(jbd2_journal_free_reserved); |
| 567 | 567 | ||
| 568 | /** | 568 | /** |
| 569 | * int jbd2_journal_start_reserved() - start reserved handle | 569 | * jbd2_journal_start_reserved() - start reserved handle |
| 570 | * @handle: handle to start | 570 | * @handle: handle to start |
| 571 | * @type: for handle statistics | 571 | * @type: for handle statistics |
| 572 | * @line_no: for handle statistics | 572 | * @line_no: for handle statistics |
| @@ -620,7 +620,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type, · 47 unmodified lines | |||
| 620 | EXPORT_SYMBOL(jbd2_journal_start_reserved); | 620 | EXPORT_SYMBOL(jbd2_journal_start_reserved); |
| 621 | 621 | ||
| 622 | /** | 622 | /** |
| 623 | * int jbd2_journal_extend() - extend buffer credits. | 623 | * jbd2_journal_extend() - extend buffer credits. |
| 624 | * @handle: handle to 'extend' | 624 | * @handle: handle to 'extend' |
| 625 | * @nblocks: nr blocks to try to extend by. | 625 | * @nblocks: nr blocks to try to extend by. |
| 626 | * @revoke_records: number of revoke records to try to extend by. | 626 | * @revoke_records: number of revoke records to try to extend by. |
| @@ -745,7 +745,7 @@ static void stop_this_handle(handle_t *handle) · 118 unmodified lines | |||
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | /** | 747 | /** |
| 748 | * int jbd2_journal_restart() - restart a handle . | 748 | * jbd2__journal_restart() - restart a handle . |
| 749 | * @handle: handle to restart | 749 | * @handle: handle to restart |
| 750 | * @nblocks: nr credits requested | 750 | * @nblocks: nr credits requested |
| 751 | * @revoke_records: number of revoke record credits requested | 751 | * @revoke_records: number of revoke record credits requested |
| @@ -815,7 +815,7 @@ int jbd2_journal_restart(handle_t *handle, int nblocks) · 63 unmodified lines | |||
| 815 | EXPORT_SYMBOL(jbd2_journal_restart); | 815 | EXPORT_SYMBOL(jbd2_journal_restart); |
| 816 | 816 | ||
| 817 | /** | 817 | /** |
| 818 | * void jbd2_journal_lock_updates () - establish a transaction barrier. | 818 | * jbd2_journal_lock_updates () - establish a transaction barrier. |
| 819 | * @journal: Journal to establish a barrier on. | 819 | * @journal: Journal to establish a barrier on. |
| 820 | * | 820 | * |
| 821 | * This locks out any further updates from being started, and blocks | 821 | * This locks out any further updates from being started, and blocks |
| @@ -874,7 +874,7 @@ void jbd2_journal_lock_updates(journal_t *journal) · 52 unmodified lines | |||
| 874 | } | 874 | } |
| 875 | 875 | ||
| 876 | /** | 876 | /** |
| 877 | * void jbd2_journal_unlock_updates (journal_t* journal) - release barrier | 877 | * jbd2_journal_unlock_updates () - release barrier |
| 878 | * @journal: Journal to release the barrier on. | 878 | * @journal: Journal to release the barrier on. |
| 879 | * | 879 | * |
| 880 | * Release a transaction barrier obtained with jbd2_journal_lock_updates(). | 880 | * Release a transaction barrier obtained with jbd2_journal_lock_updates(). |
| @@ -1182,7 +1182,8 @@ out: · 301 unmodified lines | |||
| 1182 | } | 1182 | } |
| 1183 | 1183 | ||
| 1184 | /** | 1184 | /** |
| 1185 | * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. | 1185 | * jbd2_journal_get_write_access() - notify intent to modify a buffer |
| 1186 | * for metadata (not data) update. | ||
| 1186 | * @handle: transaction to add buffer modifications to | 1187 | * @handle: transaction to add buffer modifications to |
| 1187 | * @bh: bh to be used for metadata writes | 1188 | * @bh: bh to be used for metadata writes |
| 1188 | * | 1189 | * |
| @@ -1226,7 +1227,7 @@ int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh) · 37 unmodified lines | |||
| 1226 | * unlocked buffer beforehand. */ | 1227 | * unlocked buffer beforehand. */ |
| 1227 | 1228 | ||
| 1228 | /** | 1229 | /** |
| 1229 | * int jbd2_journal_get_create_access () - notify intent to use newly created bh | 1230 | * jbd2_journal_get_create_access () - notify intent to use newly created bh |
| 1230 | * @handle: transaction to new buffer to | 1231 | * @handle: transaction to new buffer to |
| 1231 | * @bh: new buffer. | 1232 | * @bh: new buffer. |
| 1232 | * | 1233 | * |
| @@ -1306,7 +1307,7 @@ out: · 73 unmodified lines | |||
| 1306 | } | 1307 | } |
| 1307 | 1308 | ||
| 1308 | /** | 1309 | /** |
| 1309 | * int jbd2_journal_get_undo_access() - Notify intent to modify metadata with | 1310 | * jbd2_journal_get_undo_access() - Notify intent to modify metadata with |
| 1310 | * non-rewindable consequences | 1311 | * non-rewindable consequences |
| 1311 | * @handle: transaction | 1312 | * @handle: transaction |
| 1312 | * @bh: buffer to undo | 1313 | * @bh: buffer to undo |
| @@ -1383,7 +1384,7 @@ out: · 70 unmodified lines | |||
| 1383 | } | 1384 | } |
| 1384 | 1385 | ||
| 1385 | /** | 1386 | /** |
| 1386 | * void jbd2_journal_set_triggers() - Add triggers for commit writeout | 1387 | * jbd2_journal_set_triggers() - Add triggers for commit writeout |
| 1387 | * @bh: buffer to trigger on | 1388 | * @bh: buffer to trigger on |
| 1388 | * @type: struct jbd2_buffer_trigger_type containing the trigger(s). | 1389 | * @type: struct jbd2_buffer_trigger_type containing the trigger(s). |
| 1389 | * | 1390 | * |
| @@ -1425,7 +1426,7 @@ void jbd2_buffer_abort_trigger(struct journal_head *jh, · 35 unmodified lines | |||
| 1425 | } | 1426 | } |
| 1426 | 1427 | ||
| 1427 | /** | 1428 | /** |
| 1428 | * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata | 1429 | * jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata |
| 1429 | * @handle: transaction to add buffer to. | 1430 | * @handle: transaction to add buffer to. |
| 1430 | * @bh: buffer to mark | 1431 | * @bh: buffer to mark |
| 1431 | * | 1432 | * |
| @@ -1593,7 +1594,7 @@ out: · 161 unmodified lines | |||
| 1593 | } | 1594 | } |
| 1594 | 1595 | ||
| 1595 | /** | 1596 | /** |
| 1596 | * void jbd2_journal_forget() - bforget() for potentially-journaled buffers. | 1597 | * jbd2_journal_forget() - bforget() for potentially-journaled buffers. |
| 1597 | * @handle: transaction handle | 1598 | * @handle: transaction handle |
| 1598 | * @bh: bh to 'forget' | 1599 | * @bh: bh to 'forget' |
| 1599 | * | 1600 | * |
| @@ -1762,7 +1763,7 @@ drop: · 162 unmodified lines | |||
| 1762 | } | 1763 | } |
| 1763 | 1764 | ||
| 1764 | /** | 1765 | /** |
| 1765 | * int jbd2_journal_stop() - complete a transaction | 1766 | * jbd2_journal_stop() - complete a transaction |
| 1766 | * @handle: transaction to complete. | 1767 | * @handle: transaction to complete. |
| 1767 | * | 1768 | * |
| 1768 | * All done for a particular handle. | 1769 | * All done for a particular handle. |
| @@ -2080,7 +2081,7 @@ out: · 311 unmodified lines | |||
| 2080 | } | 2081 | } |
| 2081 | 2082 | ||
| 2082 | /** | 2083 | /** |
| 2083 | * int jbd2_journal_try_to_free_buffers() - try to free page buffers. | 2084 | * jbd2_journal_try_to_free_buffers() - try to free page buffers. |
| 2084 | * @journal: journal for operation | 2085 | * @journal: journal for operation |
| 2085 | * @page: to try and free | 2086 | * @page: to try and free |
| 2086 | * | 2087 | * |
| @@ -2411,7 +2412,7 @@ zap_buffer_unlocked: · 324 unmodified lines | |||
| 2411 | } | 2412 | } |
| 2412 | 2413 | ||
| 2413 | /** | 2414 | /** |
| 2414 | * void jbd2_journal_invalidatepage() | 2415 | * jbd2_journal_invalidatepage() |
| 2415 | * @journal: journal to use for flush... | 2416 | * @journal: journal to use for flush... |
| 2416 | * @page: page to flush | 2417 | * @page: page to flush |
| 2417 | * @offset: start of the range to invalidate | 2418 | * @offset: start of the range to invalidate |
| @@ -959,7 +959,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, · 958 unmodified lines | |||
| 959 | size_t len, loff_t *ppos) | 959 | size_t len, loff_t *ppos) |
| 960 | { | 960 | { |
| 961 | struct simple_attr *attr; | 961 | struct simple_attr *attr; |
| 962 | u64 val; | 962 | unsigned long long val; |
| 963 | size_t size; | 963 | size_t size; |
| 964 | ssize_t ret; | 964 | ssize_t ret; |
| 965 | 965 | ||
| @@ -977,7 +977,9 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, · 11 unmodified lines | |||
| 977 | goto out; | 977 | goto out; |
| 978 | 978 | ||
| 979 | attr->set_buf[size] = '\0'; | 979 | attr->set_buf[size] = '\0'; |
| 980 | val = simple_strtoll(attr->set_buf, NULL, 0); | 980 | ret = kstrtoull(attr->set_buf, 0, &val); |
| 981 | if (ret) | ||
| 982 | goto out; | ||
| 981 | ret = attr->set(attr->data, val); | 983 | ret = attr->set(attr->data, val); |
| 982 | if (ret == 0) | 984 | if (ret == 0) |
| 983 | ret = len; /* on success, claim we got the whole input */ | 985 | ret = len; /* on success, claim we got the whole input */ |
| @@ -178,6 +178,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, · 177 unmodified lines | |||
| 178 | struct inode *inode = d_inode(dentry); | 178 | struct inode *inode = d_inode(dentry); |
| 179 | struct dentry *parent; | 179 | struct dentry *parent; |
| 180 | bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED; | 180 | bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED; |
| 181 | bool parent_needed, parent_interested; | ||
| 181 | __u32 p_mask; | 182 | __u32 p_mask; |
| 182 | struct inode *p_inode = NULL; | 183 | struct inode *p_inode = NULL; |
| 183 | struct name_snapshot name; | 184 | struct name_snapshot name; |
| @@ -193,7 +194,8 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, · 9 unmodified lines | |||
| 193 | return 0; | 194 | return 0; |
| 194 | 195 | ||
| 195 | parent = NULL; | 196 | parent = NULL; |
| 196 | if (!parent_watched && !fsnotify_event_needs_parent(inode, mnt, mask)) | 197 | parent_needed = fsnotify_event_needs_parent(inode, mnt, mask); |
| 198 | if (!parent_watched && !parent_needed) | ||
| 197 | goto notify; | 199 | goto notify; |
| 198 | 200 | ||
| 199 | /* Does parent inode care about events on children? */ | 201 | /* Does parent inode care about events on children? */ |
| @@ -205,17 +207,17 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, · 5 unmodified lines | |||
| 205 | 207 | ||
| 206 | /* | 208 | /* |
| 207 | * Include parent/name in notification either if some notification | 209 | * Include parent/name in notification either if some notification |
| 208 | * groups require parent info (!parent_watched case) or the parent is | 210 | * groups require parent info or the parent is interested in this event. |
| 209 | * interested in this event. | ||
| 210 | */ | 211 | */ |
| 211 | if (!parent_watched || (mask & p_mask & ALL_FSNOTIFY_EVENTS)) { | 212 | parent_interested = mask & p_mask & ALL_FSNOTIFY_EVENTS; |
| 213 | if (parent_needed || parent_interested) { | ||
| 212 | /* When notifying parent, child should be passed as data */ | 214 | /* When notifying parent, child should be passed as data */ |
| 213 | WARN_ON_ONCE(inode != fsnotify_data_inode(data, data_type)); | 215 | WARN_ON_ONCE(inode != fsnotify_data_inode(data, data_type)); |
| 214 | 216 | ||
| 215 | /* Notify both parent and child with child name info */ | 217 | /* Notify both parent and child with child name info */ |
| 216 | take_dentry_name_snapshot(&name, dentry); | 218 | take_dentry_name_snapshot(&name, dentry); |
| 217 | file_name = &name.name; | 219 | file_name = &name.name; |
| 218 | if (parent_watched) | 220 | if (parent_interested) |
| 219 | mask |= FS_EVENT_ON_CHILD; | 221 | mask |= FS_EVENT_ON_CHILD; |
| 220 | } | 222 | } |
| 221 | 223 | ||
| @@ -16,6 +16,13 @@ static const char *proc_self_get_link(struct dentry *dentry, · 15 unmodified lines | |||
| 16 | pid_t tgid = task_tgid_nr_ns(current, ns); | 16 | pid_t tgid = task_tgid_nr_ns(current, ns); |
| 17 | char *name; | 17 | char *name; |
| 18 | 18 | ||
| 19 | /* | ||
| 20 | * Not currently supported. Once we can inherit all of struct pid, | ||
| 21 | * we can allow this. | ||
| 22 | */ | ||
| 23 | if (current->flags & PF_KTHREAD) | ||
| 24 | return ERR_PTR(-EOPNOTSUPP); | ||
| 25 | |||
| 19 | if (!tgid) | 26 | if (!tgid) |
| 20 | return ERR_PTR(-ENOENT); | 27 | return ERR_PTR(-ENOENT); |
| 21 | /* max length of unsigned int in decimal + NULL term */ | 28 | /* max length of unsigned int in decimal + NULL term */ |
| @@ -515,7 +515,7 @@ xfs_attr_copy_value( · 514 unmodified lines | |||
| 515 | *========================================================================*/ | 515 | *========================================================================*/ |
| 516 | 516 | ||
| 517 | /* | 517 | /* |
| 518 | * Query whether the requested number of additional bytes of extended | 518 | * Query whether the total requested number of attr fork bytes of extended |
| 519 | * attribute space will be able to fit inline. | 519 | * attribute space will be able to fit inline. |
| 520 | * | 520 | * |
| 521 | * Returns zero if not, else the di_forkoff fork offset to be used in the | 521 | * Returns zero if not, else the di_forkoff fork offset to be used in the |
| @@ -535,6 +535,12 @@ xfs_attr_shortform_bytesfit( · 13 unmodified lines | |||
| 535 | int maxforkoff; | 535 | int maxforkoff; |
| 536 | int offset; | 536 | int offset; |
| 537 | 537 | ||
| 538 | /* | ||
| 539 | * Check if the new size could fit at all first: | ||
| 540 | */ | ||
| 541 | if (bytes > XFS_LITINO(mp)) | ||
| 542 | return 0; | ||
| 543 | |||
| 538 | /* rounded down */ | 544 | /* rounded down */ |
| 539 | offset = (XFS_LITINO(mp) - bytes) >> 3; | 545 | offset = (XFS_LITINO(mp) - bytes) >> 3; |
| 540 | 546 | ||
| @@ -243,8 +243,8 @@ xfs_rmapbt_key_diff( · 242 unmodified lines | |||
| 243 | else if (y > x) | 243 | else if (y > x) |
| 244 | return -1; | 244 | return -1; |
| 245 | 245 | ||
| 246 | x = be64_to_cpu(kp->rm_offset); | 246 | x = XFS_RMAP_OFF(be64_to_cpu(kp->rm_offset)); |
| 247 | y = xfs_rmap_irec_offset_pack(rec); | 247 | y = rec->rm_offset; |
| 248 | if (x > y) | 248 | if (x > y) |
| 249 | return 1; | 249 | return 1; |
| 250 | else if (y > x) | 250 | else if (y > x) |
| @@ -275,8 +275,8 @@ xfs_rmapbt_diff_two_keys( · 24 unmodified lines | |||
| 275 | else if (y > x) | 275 | else if (y > x) |
| 276 | return -1; | 276 | return -1; |
| 277 | 277 | ||
| 278 | x = be64_to_cpu(kp1->rm_offset); | 278 | x = XFS_RMAP_OFF(be64_to_cpu(kp1->rm_offset)); |
| 279 | y = be64_to_cpu(kp2->rm_offset); | 279 | y = XFS_RMAP_OFF(be64_to_cpu(kp2->rm_offset)); |
| 280 | if (x > y) | 280 | if (x > y) |
| 281 | return 1; | 281 | return 1; |
| 282 | else if (y > x) | 282 | else if (y > x) |
| @@ -390,8 +390,8 @@ xfs_rmapbt_keys_inorder( · 107 unmodified lines | |||
| 390 | return 1; | 390 | return 1; |
| 391 | else if (a > b) | 391 | else if (a > b) |
| 392 | return 0; | 392 | return 0; |
| 393 | a = be64_to_cpu(k1->rmap.rm_offset); | 393 | a = XFS_RMAP_OFF(be64_to_cpu(k1->rmap.rm_offset)); |
| 394 | b = be64_to_cpu(k2->rmap.rm_offset); | 394 | b = XFS_RMAP_OFF(be64_to_cpu(k2->rmap.rm_offset)); |
| 395 | if (a <= b) | 395 | if (a <= b) |
| 396 | return 1; | 396 | return 1; |
| 397 | return 0; | 397 | return 0; |
| @@ -420,8 +420,8 @@ xfs_rmapbt_recs_inorder( · 22 unmodified lines | |||
| 420 | return 1; | 420 | return 1; |
| 421 | else if (a > b) | 421 | else if (a > b) |
| 422 | return 0; | 422 | return 0; |
| 423 | a = be64_to_cpu(r1->rmap.rm_offset); | 423 | a = XFS_RMAP_OFF(be64_to_cpu(r1->rmap.rm_offset)); |
| 424 | b = be64_to_cpu(r2->rmap.rm_offset); | 424 | b = XFS_RMAP_OFF(be64_to_cpu(r2->rmap.rm_offset)); |
| 425 | if (a <= b) | 425 | if (a <= b) |
| 426 | return 1; | 426 | return 1; |
| 427 | return 0; | 427 | return 0; |
| @@ -218,13 +218,13 @@ xchk_bmap_xref_rmap( · 217 unmodified lines | |||
| 218 | * which doesn't track unwritten state. | 218 | * which doesn't track unwritten state. |
| 219 | */ | 219 | */ |
| 220 | if (owner != XFS_RMAP_OWN_COW && | 220 | if (owner != XFS_RMAP_OWN_COW && |
| 221 | irec->br_state == XFS_EXT_UNWRITTEN && | 221 | !!(irec->br_state == XFS_EXT_UNWRITTEN) != |
| 222 | !(rmap.rm_flags & XFS_RMAP_UNWRITTEN)) | 222 | !!(rmap.rm_flags & XFS_RMAP_UNWRITTEN)) |
| 223 | xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, | 223 | xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, |
| 224 | irec->br_startoff); | 224 | irec->br_startoff); |
| 225 | 225 | ||
| 226 | if (info->whichfork == XFS_ATTR_FORK && | 226 | if (!!(info->whichfork == XFS_ATTR_FORK) != |
| 227 | !(rmap.rm_flags & XFS_RMAP_ATTR_FORK)) | 227 | !!(rmap.rm_flags & XFS_RMAP_ATTR_FORK)) |
| 228 | xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, | 228 | xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, |
| 229 | irec->br_startoff); | 229 | irec->br_startoff); |
| 230 | if (rmap.rm_flags & XFS_RMAP_BMBT_BLOCK) | 230 | if (rmap.rm_flags & XFS_RMAP_BMBT_BLOCK) |
| @@ -452,32 +452,41 @@ xchk_btree_check_minrecs( · 451 unmodified lines | |||
| 452 | int level, | 452 | int level, |
| 453 | struct xfs_btree_block *block) | 453 | struct xfs_btree_block *block) |
| 454 | { | 454 | { |
| 455 | unsigned int numrecs; | 455 | struct xfs_btree_cur *cur = bs->cur; |
| 456 | int ok_level; | 456 | unsigned int root_level = cur->bc_nlevels - 1; |
| 457 | 457 | unsigned int numrecs = be16_to_cpu(block->bb_numrecs); | |
| 458 | numrecs = be16_to_cpu(block->bb_numrecs); | ||
| 459 | 458 | ||
| 460 | /* More records than minrecs means the block is ok. */ | 459 | /* More records than minrecs means the block is ok. */ |
| 461 | if (numrecs >= bs->cur->bc_ops->get_minrecs(bs->cur, level)) | 460 | if (numrecs >= cur->bc_ops->get_minrecs(cur, level)) |
| 462 | return; | 461 | return; |
| 463 | 462 | ||
| 464 | /* | 463 | /* |
| 465 | * Certain btree blocks /can/ have fewer than minrecs records. Any | 464 | * For btrees rooted in the inode, it's possible that the root block |
| 466 | * level greater than or equal to the level of the highest dedicated | 465 | * contents spilled into a regular ondisk block because there wasn't |
| 467 | * btree block are allowed to violate this constraint. | 466 | * enough space in the inode root. The number of records in that |
| 468 | * | 467 | * child block might be less than the standard minrecs, but that's ok |
| 469 | * For a btree rooted in a block, the btree root can have fewer than | 468 | * provided that there's only one direct child of the root. |
| 470 | * minrecs records. If the btree is rooted in an inode and does not | ||
| 471 | * store records in the root, the direct children of the root and the | ||
| 472 | * root itself can have fewer than minrecs records. | ||
| 473 | */ | 469 | */ |
| 474 | ok_level = bs->cur->bc_nlevels - 1; | 470 | if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && |
| 475 | if (bs->cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) | 471 | level == cur->bc_nlevels - 2) { |
| 476 | ok_level--; | 472 | struct xfs_btree_block *root_block; |
| 477 | if (level >= ok_level) | 473 | struct xfs_buf *root_bp; |
| 474 | int root_maxrecs; | ||
| 475 | |||
| 476 | root_block = xfs_btree_get_block(cur, root_level, &root_bp); | ||
| 477 | root_maxrecs = cur->bc_ops->get_dmaxrecs(cur, root_level); | ||
| 478 | if (be16_to_cpu(root_block->bb_numrecs) != 1 || | ||
| 479 | numrecs <= root_maxrecs) | ||
| 480 | xchk_btree_set_corrupt(bs->sc, cur, level); | ||
| 478 | return; | 481 | return; |
| 482 | } | ||
| 479 | 483 | ||
| 480 | xchk_btree_set_corrupt(bs->sc, bs->cur, level); | 484 | /* |
| 485 | * Otherwise, only the root level is allowed to have fewer than minrecs | ||
| 486 | * records or keyptrs. | ||
| 487 | */ | ||
| 488 | if (level < root_level) | ||
| 489 | xchk_btree_set_corrupt(bs->sc, cur, level); | ||
| 481 | } | 490 | } |
| 482 | 491 | ||
| 483 | /* | 492 | /* |
| @@ -558,14 +558,27 @@ xchk_directory_leaf1_bestfree( · 557 unmodified lines | |||
| 558 | /* Check all the bestfree entries. */ | 558 | /* Check all the bestfree entries. */ |
| 559 | for (i = 0; i < bestcount; i++, bestp++) { | 559 | for (i = 0; i < bestcount; i++, bestp++) { |
| 560 | best = be16_to_cpu(*bestp); | 560 | best = be16_to_cpu(*bestp); |
| 561 | if (best == NULLDATAOFF) | ||
| 562 | continue; | ||
| 563 | error = xfs_dir3_data_read(sc->tp, sc->ip, | 561 | error = xfs_dir3_data_read(sc->tp, sc->ip, |
| 564 | i * args->geo->fsbcount, 0, &dbp); | 562 | xfs_dir2_db_to_da(args->geo, i), |
| 563 | XFS_DABUF_MAP_HOLE_OK, | ||
| 564 | &dbp); | ||
| 565 | if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, | 565 | if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, |
| 566 | &error)) | 566 | &error)) |
| 567 | break; | 567 | break; |
| 568 | xchk_directory_check_freesp(sc, lblk, dbp, best); | 568 | |
| 569 | if (!dbp) { | ||
| 570 | if (best != NULLDATAOFF) { | ||
| 571 | xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, | ||
| 572 | lblk); | ||
| 573 | break; | ||
| 574 | } | ||
| 575 | continue; | ||
| 576 | } | ||
| 577 | |||
| 578 | if (best == NULLDATAOFF) | ||
| 579 | xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); | ||
| 580 | else | ||
| 581 | xchk_directory_check_freesp(sc, lblk, dbp, best); | ||
| 569 | xfs_trans_brelse(sc->tp, dbp); | 582 | xfs_trans_brelse(sc->tp, dbp); |
| 570 | if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) | 583 | if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) |
| 571 | break; | 584 | break; |
| @@ -706,6 +706,23 @@ relock: · 705 unmodified lines | |||
| 706 | return 0; | 706 | return 0; |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | /* | ||
| 710 | * Check that the imap we are going to return to the caller spans the entire | ||
| 711 | * range that the caller requested for the IO. | ||
| 712 | */ | ||
| 713 | static bool | ||
| 714 | imap_spans_range( | ||
| 715 | struct xfs_bmbt_irec *imap, | ||
| 716 | xfs_fileoff_t offset_fsb, | ||
| 717 | xfs_fileoff_t end_fsb) | ||
| 718 | { | ||
| 719 | if (imap->br_startoff > offset_fsb) | ||
| 720 | return false; | ||
| 721 | if (imap->br_startoff + imap->br_blockcount < end_fsb) | ||
| 722 | return false; | ||
| 723 | return true; | ||
| 724 | } | ||
| 725 | |||
| 709 | static int | 726 | static int |
| 710 | xfs_direct_write_iomap_begin( | 727 | xfs_direct_write_iomap_begin( |
| 711 | struct inode *inode, | 728 | struct inode *inode, |
| @@ -766,6 +783,18 @@ xfs_direct_write_iomap_begin( · 54 unmodified lines | |||
| 766 | if (imap_needs_alloc(inode, flags, &imap, nimaps)) | 783 | if (imap_needs_alloc(inode, flags, &imap, nimaps)) |
| 767 | goto allocate_blocks; | 784 | goto allocate_blocks; |
| 768 | 785 | ||
| 786 | /* | ||
| 787 | * NOWAIT IO needs to span the entire requested IO with a single map so | ||
| 788 | * that we avoid partial IO failures due to the rest of the IO range not | ||
| 789 | * covered by this map triggering an EAGAIN condition when it is | ||
| 790 | * subsequently mapped and aborting the IO. | ||
| 791 | */ | ||
| 792 | if ((flags & IOMAP_NOWAIT) && | ||
| 793 | !imap_spans_range(&imap, offset_fsb, end_fsb)) { | ||
| 794 | error = -EAGAIN; | ||
| 795 | goto out_unlock; | ||
| 796 | } | ||
| 797 | |||
| 769 | xfs_iunlock(ip, lockmode); | 798 | xfs_iunlock(ip, lockmode); |
| 770 | trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap); | 799 | trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap); |
| 771 | return xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags); | 800 | return xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags); |
| @@ -55,6 +55,9 @@ struct xfs_iwalk_ag { · 54 unmodified lines | |||
| 55 | /* Where do we start the traversal? */ | 55 | /* Where do we start the traversal? */ |
| 56 | xfs_ino_t startino; | 56 | xfs_ino_t startino; |
| 57 | 57 | ||
| 58 | /* What was the last inode number we saw when iterating the inobt? */ | ||
| 59 | xfs_ino_t lastino; | ||
| 60 | |||
| 58 | /* Array of inobt records we cache. */ | 61 | /* Array of inobt records we cache. */ |
| 59 | struct xfs_inobt_rec_incore *recs; | 62 | struct xfs_inobt_rec_incore *recs; |
| 60 | 63 | ||
| @@ -301,6 +304,9 @@ xfs_iwalk_ag_start( · 240 unmodified lines | |||
| 301 | if (XFS_IS_CORRUPT(mp, *has_more != 1)) | 304 | if (XFS_IS_CORRUPT(mp, *has_more != 1)) |
| 302 | return -EFSCORRUPTED; | 305 | return -EFSCORRUPTED; |
| 303 | 306 | ||
| 307 | iwag->lastino = XFS_AGINO_TO_INO(mp, agno, | ||
| 308 | irec->ir_startino + XFS_INODES_PER_CHUNK - 1); | ||
| 309 | |||
| 304 | /* | 310 | /* |
| 305 | * If the LE lookup yielded an inobt record before the cursor position, | 311 | * If the LE lookup yielded an inobt record before the cursor position, |
| 306 | * skip it and see if there's another one after it. | 312 | * skip it and see if there's another one after it. |
| @@ -347,15 +353,17 @@ xfs_iwalk_run_callbacks( · 40 unmodified lines | |||
| 347 | struct xfs_mount *mp = iwag->mp; | 353 | struct xfs_mount *mp = iwag->mp; |
| 348 | struct xfs_trans *tp = iwag->tp; | 354 | struct xfs_trans *tp = iwag->tp; |
| 349 | struct xfs_inobt_rec_incore *irec; | 355 | struct xfs_inobt_rec_incore *irec; |
| 350 | xfs_agino_t restart; | 356 | xfs_agino_t next_agino; |
| 351 | int error; | 357 | int error; |
| 352 | 358 | ||
| 359 | next_agino = XFS_INO_TO_AGINO(mp, iwag->lastino) + 1; | ||
| 360 | |||
| 353 | ASSERT(iwag->nr_recs > 0); | 361 | ASSERT(iwag->nr_recs > 0); |
| 354 | 362 | ||
| 355 | /* Delete cursor but remember the last record we cached... */ | 363 | /* Delete cursor but remember the last record we cached... */ |
| 356 | xfs_iwalk_del_inobt(tp, curpp, agi_bpp, 0); | 364 | xfs_iwalk_del_inobt(tp, curpp, agi_bpp, 0); |
| 357 | irec = &iwag->recs[iwag->nr_recs - 1]; | 365 | irec = &iwag->recs[iwag->nr_recs - 1]; |
| 358 | restart = irec->ir_startino + XFS_INODES_PER_CHUNK - 1; | 366 | ASSERT(next_agino == irec->ir_startino + XFS_INODES_PER_CHUNK); |
| 359 | 367 | ||
| 360 | error = xfs_iwalk_ag_recs(iwag); | 368 | error = xfs_iwalk_ag_recs(iwag); |
| 361 | if (error) | 369 | if (error) |
| @@ -372,7 +380,7 @@ xfs_iwalk_run_callbacks( · 10 unmodified lines | |||
| 372 | if (error) | 380 | if (error) |
| 373 | return error; | 381 | return error; |
| 374 | 382 | ||
| 375 | return xfs_inobt_lookup(*curpp, restart, XFS_LOOKUP_GE, has_more); | 383 | return xfs_inobt_lookup(*curpp, next_agino, XFS_LOOKUP_GE, has_more); |
| 376 | } | 384 | } |
| 377 | 385 | ||
| 378 | /* Walk all inodes in a single AG, from @iwag->startino to the end of the AG. */ | 386 | /* Walk all inodes in a single AG, from @iwag->startino to the end of the AG. */ |
| @@ -396,6 +404,7 @@ xfs_iwalk_ag( · 17 unmodified lines | |||
| 396 | 404 | ||
| 397 | while (!error && has_more) { | 405 | while (!error && has_more) { |
| 398 | struct xfs_inobt_rec_incore *irec; | 406 | struct xfs_inobt_rec_incore *irec; |
| 407 | xfs_ino_t rec_fsino; | ||
| 399 | 408 | ||
| 400 | cond_resched(); | 409 | cond_resched(); |
| 401 | if (xfs_pwork_want_abort(&iwag->pwork)) | 410 | if (xfs_pwork_want_abort(&iwag->pwork)) |
| @@ -407,6 +416,15 @@ xfs_iwalk_ag( · 5 unmodified lines | |||
| 407 | if (error || !has_more) | 416 | if (error || !has_more) |
| 408 | break; | 417 | break; |
| 409 | 418 | ||
| 419 | /* Make sure that we always move forward. */ | ||
| 420 | rec_fsino = XFS_AGINO_TO_INO(mp, agno, irec->ir_startino); | ||
| 421 | if (iwag->lastino != NULLFSINO && | ||
| 422 | XFS_IS_CORRUPT(mp, iwag->lastino >= rec_fsino)) { | ||
| 423 | error = -EFSCORRUPTED; | ||
| 424 | goto out; | ||
| 425 | } | ||
| 426 | iwag->lastino = rec_fsino + XFS_INODES_PER_CHUNK - 1; | ||
| 427 | |||
| 410 | /* No allocated inodes in this chunk; skip it. */ | 428 | /* No allocated inodes in this chunk; skip it. */ |
| 411 | if (iwag->skip_empty && irec->ir_freecount == irec->ir_count) { | 429 | if (iwag->skip_empty && irec->ir_freecount == irec->ir_count) { |
| 412 | error = xfs_btree_increment(cur, 0, &has_more); | 430 | error = xfs_btree_increment(cur, 0, &has_more); |
| @@ -535,6 +553,7 @@ xfs_iwalk( · 122 unmodified lines | |||
| 535 | .trim_start = 1, | 553 | .trim_start = 1, |
| 536 | .skip_empty = 1, | 554 | .skip_empty = 1, |
| 537 | .pwork = XFS_PWORK_SINGLE_THREADED, | 555 | .pwork = XFS_PWORK_SINGLE_THREADED, |
| 556 | .lastino = NULLFSINO, | ||
| 538 | }; | 557 | }; |
| 539 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino); | 558 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino); |
| 540 | int error; | 559 | int error; |
| @@ -623,6 +642,7 @@ xfs_iwalk_threaded( · 82 unmodified lines | |||
| 623 | iwag->data = data; | 642 | iwag->data = data; |
| 624 | iwag->startino = startino; | 643 | iwag->startino = startino; |
| 625 | iwag->sz_recs = xfs_iwalk_prefetch(inode_records); | 644 | iwag->sz_recs = xfs_iwalk_prefetch(inode_records); |
| 645 | iwag->lastino = NULLFSINO; | ||
| 626 | xfs_pwork_queue(&pctl, &iwag->pwork); | 646 | xfs_pwork_queue(&pctl, &iwag->pwork); |
| 627 | startino = XFS_AGINO_TO_INO(mp, agno + 1, 0); | 647 | startino = XFS_AGINO_TO_INO(mp, agno + 1, 0); |
| 628 | if (flags & XFS_INOBT_WALK_SAME_AG) | 648 | if (flags & XFS_INOBT_WALK_SAME_AG) |
| @@ -696,6 +716,7 @@ xfs_inobt_walk( · 67 unmodified lines | |||
| 696 | .startino = startino, | 716 | .startino = startino, |
| 697 | .sz_recs = xfs_inobt_walk_prefetch(inobt_records), | 717 | .sz_recs = xfs_inobt_walk_prefetch(inobt_records), |
| 698 | .pwork = XFS_PWORK_SINGLE_THREADED, | 718 | .pwork = XFS_PWORK_SINGLE_THREADED, |
| 719 | .lastino = NULLFSINO, | ||
| 699 | }; | 720 | }; |
| 700 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino); | 721 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino); |
| 701 | int error; | 722 | int error; |
| @@ -194,20 +194,25 @@ xfs_initialize_perag( · 193 unmodified lines | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); | 196 | pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); |
| 197 | if (!pag) | 197 | if (!pag) { |
| 198 | error = -ENOMEM; | ||
| 198 | goto out_unwind_new_pags; | 199 | goto out_unwind_new_pags; |
| 200 | } | ||
| 199 | pag->pag_agno = index; | 201 | pag->pag_agno = index; |
| 200 | pag->pag_mount = mp; | 202 | pag->pag_mount = mp; |
| 201 | spin_lock_init(&pag->pag_ici_lock); | 203 | spin_lock_init(&pag->pag_ici_lock); |
| 202 | INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); | 204 | INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); |
| 203 | if (xfs_buf_hash_init(pag)) | 205 | |
| 206 | error = xfs_buf_hash_init(pag); | ||
| 207 | if (error) | ||
| 204 | goto out_free_pag; | 208 | goto out_free_pag; |
| 205 | init_waitqueue_head(&pag->pagb_wait); | 209 | init_waitqueue_head(&pag->pagb_wait); |
| 206 | spin_lock_init(&pag->pagb_lock); | 210 | spin_lock_init(&pag->pagb_lock); |
| 207 | pag->pagb_count = 0; | 211 | pag->pagb_count = 0; |
| 208 | pag->pagb_tree = RB_ROOT; | 212 | pag->pagb_tree = RB_ROOT; |
| 209 | 213 | ||
| 210 | if (radix_tree_preload(GFP_NOFS)) | 214 | error = radix_tree_preload(GFP_NOFS); |
| 215 | if (error) | ||
| 211 | goto out_hash_destroy; | 216 | goto out_hash_destroy; |
| 212 | 217 | ||
| 213 | spin_lock(&mp->m_perag_lock); | 218 | spin_lock(&mp->m_perag_lock); |
| @@ -8,8 +8,10 @@ · 7 unmodified lines | |||
| 8 | + __clang_patchlevel__) | 8 | + __clang_patchlevel__) |
| 9 | 9 | ||
| 10 | #if CLANG_VERSION < 100001 | 10 | #if CLANG_VERSION < 100001 |
| 11 | #ifndef __BPF_TRACING__ | ||
| 11 | # error Sorry, your version of Clang is too old - please use 10.0.1 or newer. | 12 | # error Sorry, your version of Clang is too old - please use 10.0.1 or newer. |
| 12 | #endif | 13 | #endif |
| 14 | #endif | ||
| 13 | 15 | ||
| 14 | /* Compiler specific definitions for Clang compiler */ | 16 | /* Compiler specific definitions for Clang compiler */ |
| 15 | 17 | ||
| @@ -50,10 +50,6 @@ · 49 unmodified lines | |||
| 50 | #define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U | 50 | #define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U |
| 51 | #define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U | 51 | #define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U |
| 52 | 52 | ||
| 53 | /* Feature check status */ | ||
| 54 | #define PM_FEATURE_INVALID -1 | ||
| 55 | #define PM_FEATURE_UNCHECKED 0 | ||
| 56 | |||
| 57 | /* | 53 | /* |
| 58 | * Firmware FPGA Manager flags | 54 | * Firmware FPGA Manager flags |
| 59 | * XILINX_ZYNQMP_PM_FPGA_FULL: FPGA full reconfiguration | 55 | * XILINX_ZYNQMP_PM_FPGA_FULL: FPGA full reconfiguration |
| @@ -798,7 +798,6 @@ extern int iommu_calculate_agaw(struct intel_iommu *iommu); · 797 unmodified lines | |||
| 798 | extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu); | 798 | extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu); |
| 799 | extern int dmar_disabled; | 799 | extern int dmar_disabled; |
| 800 | extern int intel_iommu_enabled; | 800 | extern int intel_iommu_enabled; |
| 801 | extern int intel_iommu_tboot_noforce; | ||
| 802 | extern int intel_iommu_gfx_mapped; | 801 | extern int intel_iommu_gfx_mapped; |
| 803 | #else | 802 | #else |
| 804 | static inline int iommu_calculate_agaw(struct intel_iommu *iommu) | 803 | static inline int iommu_calculate_agaw(struct intel_iommu *iommu) |
| @@ -401,7 +401,7 @@ static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) · 400 unmodified lines | |||
| 401 | #define JI_WAIT_DATA (1 << __JI_WAIT_DATA) | 401 | #define JI_WAIT_DATA (1 << __JI_WAIT_DATA) |
| 402 | 402 | ||
| 403 | /** | 403 | /** |
| 404 | * struct jbd_inode - The jbd_inode type is the structure linking inodes in | 404 | * struct jbd2_inode - The jbd_inode type is the structure linking inodes in |
| 405 | * ordered mode present in a transaction so that we can sync them during commit. | 405 | * ordered mode present in a transaction so that we can sync them during commit. |
| 406 | */ | 406 | */ |
| 407 | struct jbd2_inode { | 407 | struct jbd2_inode { |
| @@ -282,20 +282,6 @@ struct mem_cgroup { · 281 unmodified lines | |||
| 282 | 282 | ||
| 283 | MEMCG_PADDING(_pad1_); | 283 | MEMCG_PADDING(_pad1_); |
| 284 | 284 | ||
| 285 | /* | ||
| 286 | * set > 0 if pages under this cgroup are moving to other cgroup. | ||
| 287 | */ | ||
| 288 | atomic_t moving_account; | ||
| 289 | struct task_struct *move_lock_task; | ||
| 290 | |||
| 291 | /* Legacy local VM stats and events */ | ||
| 292 | struct memcg_vmstats_percpu __percpu *vmstats_local; | ||
| 293 | |||
| 294 | /* Subtree VM stats and events (batched updates) */ | ||
| 295 | struct memcg_vmstats_percpu __percpu *vmstats_percpu; | ||
| 296 | |||
| 297 | MEMCG_PADDING(_pad2_); | ||
| 298 | |||
| 299 | atomic_long_t vmstats[MEMCG_NR_STAT]; | 285 | atomic_long_t vmstats[MEMCG_NR_STAT]; |
| 300 | atomic_long_t vmevents[NR_VM_EVENT_ITEMS]; | 286 | atomic_long_t vmevents[NR_VM_EVENT_ITEMS]; |
| 301 | 287 | ||
| @@ -317,6 +303,20 @@ struct mem_cgroup { · 15 unmodified lines | |||
| 317 | struct list_head objcg_list; /* list of inherited objcgs */ | 303 | struct list_head objcg_list; /* list of inherited objcgs */ |
| 318 | #endif | 304 | #endif |
| 319 | 305 | ||
| 306 | MEMCG_PADDING(_pad2_); | ||
| 307 | |||
| 308 | /* | ||
| 309 | * set > 0 if pages under this cgroup are moving to other cgroup. | ||
| 310 | */ | ||
| 311 | atomic_t moving_account; | ||
| 312 | struct task_struct *move_lock_task; | ||
| 313 | |||
| 314 | /* Legacy local VM stats and events */ | ||
| 315 | struct memcg_vmstats_percpu __percpu *vmstats_local; | ||
| 316 | |||
| 317 | /* Subtree VM stats and events (batched updates) */ | ||
| 318 | struct memcg_vmstats_percpu __percpu *vmstats_percpu; | ||
| 319 | |||
| 320 | #ifdef CONFIG_CGROUP_WRITEBACK | 320 | #ifdef CONFIG_CGROUP_WRITEBACK |
| 321 | struct list_head cgwb_list; | 321 | struct list_head cgwb_list; |
| 322 | struct wb_domain cgwb_domain; | 322 | struct wb_domain cgwb_domain; |
| @@ -281,20 +281,6 @@ static inline bool movable_node_is_enabled(void) · 280 unmodified lines | |||
| 281 | } | 281 | } |
| 282 | #endif /* ! CONFIG_MEMORY_HOTPLUG */ | 282 | #endif /* ! CONFIG_MEMORY_HOTPLUG */ |
| 283 | 283 | ||
| 284 | #ifdef CONFIG_NUMA | ||
| 285 | extern int memory_add_physaddr_to_nid(u64 start); | ||
| 286 | extern int phys_to_target_node(u64 start); | ||
| 287 | #else | ||
| 288 | static inline int memory_add_physaddr_to_nid(u64 start) | ||
| 289 | { | ||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | static inline int phys_to_target_node(u64 start) | ||
| 293 | { | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | |||
| 298 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT) | 284 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT) |
| 299 | /* | 285 | /* |
| 300 | * pgdat resizing functions | 286 | * pgdat resizing functions |
| @@ -3163,6 +3163,11 @@ static inline bool dev_validate_header(const struct net_device *dev, · 3162 unmodified lines | |||
| 3163 | return false; | 3163 | return false; |
| 3164 | } | 3164 | } |
| 3165 | 3165 | ||
| 3166 | static inline bool dev_has_header(const struct net_device *dev) | ||
| 3167 | { | ||
| 3168 | return dev->header_ops && dev->header_ops->create; | ||
| 3169 | } | ||
| 3170 | |||
| 3166 | typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, | 3171 | typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, |
| 3167 | int len, int size); | 3172 | int len, int size); |
| 3168 | int register_gifconf(unsigned int family, gifconf_func_t *gifconf); | 3173 | int register_gifconf(unsigned int family, gifconf_func_t *gifconf); |
| @@ -21,13 +21,41 @@ · 20 unmodified lines | |||
| 21 | #endif | 21 | #endif |
| 22 | 22 | ||
| 23 | #ifdef CONFIG_NUMA | 23 | #ifdef CONFIG_NUMA |
| 24 | #include <linux/printk.h> | ||
| 25 | #include <asm/sparsemem.h> | ||
| 26 | |||
| 24 | /* Generic implementation available */ | 27 | /* Generic implementation available */ |
| 25 | int numa_map_to_online_node(int node); | 28 | int numa_map_to_online_node(int node); |
| 26 | #else | 29 | |
| 30 | #ifndef memory_add_physaddr_to_nid | ||
| 31 | static inline int memory_add_physaddr_to_nid(u64 start) | ||
| 32 | { | ||
| 33 | pr_info_once("Unknown online node for memory at 0x%llx, assuming node 0\n", | ||
| 34 | start); | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | #endif | ||
| 38 | #ifndef phys_to_target_node | ||
| 39 | static inline int phys_to_target_node(u64 start) | ||
| 40 | { | ||
| 41 | pr_info_once("Unknown target node for memory at 0x%llx, assuming node 0\n", | ||
| 42 | start); | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | #endif | ||
| 46 | #else /* !CONFIG_NUMA */ | ||
| 27 | static inline int numa_map_to_online_node(int node) | 47 | static inline int numa_map_to_online_node(int node) |
| 28 | { | 48 | { |
| 29 | return NUMA_NO_NODE; | 49 | return NUMA_NO_NODE; |
| 30 | } | 50 | } |
| 51 | static inline int memory_add_physaddr_to_nid(u64 start) | ||
| 52 | { | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | static inline int phys_to_target_node(u64 start) | ||
| 56 | { | ||
| 57 | return 0; | ||
| 58 | } | ||
| 31 | #endif | 59 | #endif |
| 32 | 60 | ||
| 33 | #endif /* _LINUX_NUMA_H */ | 61 | #endif /* _LINUX_NUMA_H */ |
| @@ -906,6 +906,8 @@ static inline unsigned int __readahead_batch(struct readahead_control *rac, · 905 unmodified lines | |||
| 906 | xas_set(&xas, rac->_index); | 906 | xas_set(&xas, rac->_index); |
| 907 | rcu_read_lock(); | 907 | rcu_read_lock(); |
| 908 | xas_for_each(&xas, page, rac->_index + rac->_nr_pages - 1) { | 908 | xas_for_each(&xas, page, rac->_index + rac->_nr_pages - 1) { |
| 909 | if (xas_retry(&xas, page)) | ||
| 910 | continue; | ||
| 909 | VM_BUG_ON_PAGE(!PageLocked(page), page); | 911 | VM_BUG_ON_PAGE(!PageLocked(page), page); |
| 910 | VM_BUG_ON_PAGE(PageTail(page), page); | 912 | VM_BUG_ON_PAGE(PageTail(page), page); |
| 911 | array[i++] = page; | 913 | array[i++] = page; |
| @@ -1427,6 +1427,19 @@ typedef unsigned int pgtbl_mod_mask; · 1426 unmodified lines | |||
| 1427 | 1427 | ||
| 1428 | #endif /* !__ASSEMBLY__ */ | 1428 | #endif /* !__ASSEMBLY__ */ |
| 1429 | 1429 | ||
| 1430 | #if !defined(MAX_POSSIBLE_PHYSMEM_BITS) && !defined(CONFIG_64BIT) | ||
| 1431 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
| 1432 | /* | ||
| 1433 | * ZSMALLOC needs to know the highest PFN on 32-bit architectures | ||
| 1434 | * with physical address space extension, but falls back to | ||
| 1435 | * BITS_PER_LONG otherwise. | ||
| 1436 | */ | ||
| 1437 | #error Missing MAX_POSSIBLE_PHYSMEM_BITS definition | ||
| 1438 | #else | ||
| 1439 | #define MAX_POSSIBLE_PHYSMEM_BITS 32 | ||
| 1440 | #endif | ||
| 1441 | #endif | ||
| 1442 | |||
| 1430 | #ifndef has_transparent_hugepage | 1443 | #ifndef has_transparent_hugepage |
| 1431 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1444 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 1432 | #define has_transparent_hugepage() 1 | 1445 | #define has_transparent_hugepage() 1 |
| @@ -50,6 +50,7 @@ struct sysc_regbits { · 49 unmodified lines | |||
| 50 | s8 emufree_shift; | 50 | s8 emufree_shift; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | #define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25) | ||
| 53 | #define SYSC_MODULE_QUIRK_PRUSS BIT(24) | 54 | #define SYSC_MODULE_QUIRK_PRUSS BIT(24) |
| 54 | #define SYSC_MODULE_QUIRK_DSS_RESET BIT(23) | 55 | #define SYSC_MODULE_QUIRK_DSS_RESET BIT(23) |
| 55 | #define SYSC_MODULE_QUIRK_RTC_UNLOCK BIT(22) | 56 | #define SYSC_MODULE_QUIRK_RTC_UNLOCK BIT(22) |
| @@ -552,7 +552,6 @@ struct sched_dl_entity { · 551 unmodified lines | |||
| 552 | * overruns. | 552 | * overruns. |
| 553 | */ | 553 | */ |
| 554 | unsigned int dl_throttled : 1; | 554 | unsigned int dl_throttled : 1; |
| 555 | unsigned int dl_boosted : 1; | ||
| 556 | unsigned int dl_yielded : 1; | 555 | unsigned int dl_yielded : 1; |
| 557 | unsigned int dl_non_contending : 1; | 556 | unsigned int dl_non_contending : 1; |
| 558 | unsigned int dl_overrun : 1; | 557 | unsigned int dl_overrun : 1; |
| @@ -571,6 +570,15 @@ struct sched_dl_entity { · 12 unmodified lines | |||
| 571 | * time. | 570 | * time. |
| 572 | */ | 571 | */ |
| 573 | struct hrtimer inactive_timer; | 572 | struct hrtimer inactive_timer; |
| 573 | |||
| 574 | #ifdef CONFIG_RT_MUTEXES | ||
| 575 | /* | ||
| 576 | * Priority Inheritance. When a DEADLINE scheduling entity is boosted | ||
| 577 | * pi_se points to the donor, otherwise points to the dl_se it belongs | ||
| 578 | * to (the original one/itself). | ||
| 579 | */ | ||
| 580 | struct sched_dl_entity *pi_se; | ||
| 581 | #endif | ||
| 574 | }; | 582 | }; |
| 575 | 583 | ||
| 576 | #ifdef CONFIG_UCLAMP_TASK | 584 | #ifdef CONFIG_UCLAMP_TASK |
| @@ -770,7 +778,6 @@ struct task_struct { · 193 unmodified lines | |||
| 770 | unsigned sched_reset_on_fork:1; | 778 | unsigned sched_reset_on_fork:1; |
| 771 | unsigned sched_contributes_to_load:1; | 779 | unsigned sched_contributes_to_load:1; |
| 772 | unsigned sched_migrated:1; | 780 | unsigned sched_migrated:1; |
| 773 | unsigned sched_remote_wakeup:1; | ||
| 774 | #ifdef CONFIG_PSI | 781 | #ifdef CONFIG_PSI |
| 775 | unsigned sched_psi_wake_requeue:1; | 782 | unsigned sched_psi_wake_requeue:1; |
| 776 | #endif | 783 | #endif |
| @@ -780,6 +787,21 @@ struct task_struct { · 3 unmodified lines | |||
| 780 | 787 | ||
| 781 | /* Unserialized, strictly 'current' */ | 788 | /* Unserialized, strictly 'current' */ |
| 782 | 789 | ||
| 790 | /* | ||
| 791 | * This field must not be in the scheduler word above due to wakelist | ||
| 792 | * queueing no longer being serialized by p->on_cpu. However: | ||
| 793 | * | ||
| 794 | * p->XXX = X; ttwu() | ||
| 795 | * schedule() if (p->on_rq && ..) // false | ||
| 796 | * smp_mb__after_spinlock(); if (smp_load_acquire(&p->on_cpu) && //true | ||
| 797 | * deactivate_task() ttwu_queue_wakelist()) | ||
| 798 | * p->on_rq = 0; p->sched_remote_wakeup = Y; | ||
| 799 | * | ||
| 800 | * guarantees all stores of 'current' are visible before | ||
| 801 | * ->sched_remote_wakeup gets used, so it can be in this word. | ||
| 802 | */ | ||
| 803 | unsigned sched_remote_wakeup:1; | ||
| 804 | |||
| 783 | /* Bit to tell LSMs we're in execve(): */ | 805 | /* Bit to tell LSMs we're in execve(): */ |
| 784 | unsigned in_execve:1; | 806 | unsigned in_execve:1; |
| 785 | unsigned in_iowait:1; | 807 | unsigned in_iowait:1; |
| @@ -185,6 +185,11 @@ struct slave { · 184 unmodified lines | |||
| 185 | struct rtnl_link_stats64 slave_stats; | 185 | struct rtnl_link_stats64 slave_stats; |
| 186 | }; | 186 | }; |
| 187 | 187 | ||
| 188 | static inline struct slave *to_slave(struct kobject *kobj) | ||
| 189 | { | ||
| 190 | return container_of(kobj, struct slave, kobj); | ||
| 191 | } | ||
| 192 | |||
| 188 | struct bond_up_slave { | 193 | struct bond_up_slave { |
| 189 | unsigned int count; | 194 | unsigned int count; |
| 190 | struct rcu_head rcu; | 195 | struct rcu_head rcu; |
| @@ -750,6 +755,9 @@ extern struct bond_parm_tbl ad_select_tbl[]; · 559 unmodified lines | |||
| 750 | /* exported from bond_netlink.c */ | 755 | /* exported from bond_netlink.c */ |
| 751 | extern struct rtnl_link_ops bond_link_ops; | 756 | extern struct rtnl_link_ops bond_link_ops; |
| 752 | 757 | ||
| 758 | /* exported from bond_sysfs_slave.c */ | ||
| 759 | extern const struct sysfs_ops slave_sysfs_ops; | ||
| 760 | |||
| 753 | static inline netdev_tx_t bond_tx_drop(struct net_device *dev, struct sk_buff *skb) | 761 | static inline netdev_tx_t bond_tx_drop(struct net_device *dev, struct sk_buff *skb) |
| 754 | { | 762 | { |
| 755 | atomic_long_inc(&dev->tx_dropped); | 763 | atomic_long_inc(&dev->tx_dropped); |
| @@ -247,8 +247,9 @@ void inet_hashinfo2_init(struct inet_hashinfo *h, const char *name, · 246 unmodified lines | |||
| 247 | unsigned long high_limit); | 247 | unsigned long high_limit); |
| 248 | int inet_hashinfo2_init_mod(struct inet_hashinfo *h); | 248 | int inet_hashinfo2_init_mod(struct inet_hashinfo *h); |
| 249 | 249 | ||
| 250 | bool inet_ehash_insert(struct sock *sk, struct sock *osk); | 250 | bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk); |
| 251 | bool inet_ehash_nolisten(struct sock *sk, struct sock *osk); | 251 | bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, |
| 252 | bool *found_dup_sk); | ||
| 252 | int __inet_hash(struct sock *sk, struct sock *osk); | 253 | int __inet_hash(struct sock *sk, struct sock *osk); |
| 253 | int inet_hash(struct sock *sk); | 254 | int inet_hash(struct sock *sk); |
| 254 | void inet_unhash(struct sock *sk); | 255 | void inet_unhash(struct sock *sk); |
| @@ -199,6 +199,12 @@ enum tls_context_flags { · 198 unmodified lines | |||
| 199 | * to be atomic. | 199 | * to be atomic. |
| 200 | */ | 200 | */ |
| 201 | TLS_TX_SYNC_SCHED = 1, | 201 | TLS_TX_SYNC_SCHED = 1, |
| 202 | /* tls_dev_del was called for the RX side, device state was released, | ||
| 203 | * but tls_ctx->netdev might still be kept, because TX-side driver | ||
| 204 | * resources might not be released yet. Used to prevent the second | ||
| 205 | * tls_dev_del call in tls_device_down if it happens simultaneously. | ||
| 206 | */ | ||
| 207 | TLS_RX_DEV_CLOSED = 2, | ||
| 202 | }; | 208 | }; |
| 203 | 209 | ||
| 204 | struct cipher_context { | 210 | struct cipher_context { |
| @@ -132,6 +132,9 @@ struct iscsi_task { · 131 unmodified lines | |||
| 132 | void *dd_data; /* driver/transport data */ | 132 | void *dd_data; /* driver/transport data */ |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | /* invalid scsi_task pointer */ | ||
| 136 | #define INVALID_SCSI_TASK (struct iscsi_task *)-1l | ||
| 137 | |||
| 135 | static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) | 138 | static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) |
| 136 | { | 139 | { |
| 137 | return task->unsol_r2t.data_length > task->unsol_r2t.sent; | 140 | return task->unsol_r2t.data_length > task->unsol_r2t.sent; |
| @@ -0,0 +1,15 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * linux/sound/rt1015.h -- Platform data for RT1015 | ||
| 4 | * | ||
| 5 | * Copyright 2020 Realtek Microelectronics | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef __LINUX_SND_RT1015_H | ||
| 9 | #define __LINUX_SND_RT1015_H | ||
| 10 | |||
| 11 | struct rt1015_platform_data { | ||
| 12 | unsigned int power_up_delay_ms; | ||
| 13 | }; | ||
| 14 | |||
| 15 | #endif | ||
| @@ -190,7 +190,7 @@ TRACE_EVENT(inode_foreign_history, · 189 unmodified lines | |||
| 190 | ), | 190 | ), |
| 191 | 191 | ||
| 192 | TP_fast_assign( | 192 | TP_fast_assign( |
| 193 | strncpy(__entry->name, bdi_dev_name(inode_to_bdi(inode)), 32); | 193 | strscpy_pad(__entry->name, bdi_dev_name(inode_to_bdi(inode)), 32); |
| 194 | __entry->ino = inode->i_ino; | 194 | __entry->ino = inode->i_ino; |
| 195 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc); | 195 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc); |
| 196 | __entry->history = history; | 196 | __entry->history = history; |
| @@ -219,7 +219,7 @@ TRACE_EVENT(inode_switch_wbs, · 22 unmodified lines | |||
| 219 | ), | 219 | ), |
| 220 | 220 | ||
| 221 | TP_fast_assign( | 221 | TP_fast_assign( |
| 222 | strncpy(__entry->name, bdi_dev_name(old_wb->bdi), 32); | 222 | strscpy_pad(__entry->name, bdi_dev_name(old_wb->bdi), 32); |
| 223 | __entry->ino = inode->i_ino; | 223 | __entry->ino = inode->i_ino; |
| 224 | __entry->old_cgroup_ino = __trace_wb_assign_cgroup(old_wb); | 224 | __entry->old_cgroup_ino = __trace_wb_assign_cgroup(old_wb); |
| 225 | __entry->new_cgroup_ino = __trace_wb_assign_cgroup(new_wb); | 225 | __entry->new_cgroup_ino = __trace_wb_assign_cgroup(new_wb); |
| @@ -252,7 +252,7 @@ TRACE_EVENT(track_foreign_dirty, · 26 unmodified lines | |||
| 252 | struct address_space *mapping = page_mapping(page); | 252 | struct address_space *mapping = page_mapping(page); |
| 253 | struct inode *inode = mapping ? mapping->host : NULL; | 253 | struct inode *inode = mapping ? mapping->host : NULL; |
| 254 | 254 | ||
| 255 | strncpy(__entry->name, bdi_dev_name(wb->bdi), 32); | 255 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); |
| 256 | __entry->bdi_id = wb->bdi->id; | 256 | __entry->bdi_id = wb->bdi->id; |
| 257 | __entry->ino = inode ? inode->i_ino : 0; | 257 | __entry->ino = inode ? inode->i_ino : 0; |
| 258 | __entry->memcg_id = wb->memcg_css->id; | 258 | __entry->memcg_id = wb->memcg_css->id; |
| @@ -285,7 +285,7 @@ TRACE_EVENT(flush_foreign, · 26 unmodified lines | |||
| 285 | ), | 285 | ), |
| 286 | 286 | ||
| 287 | TP_fast_assign( | 287 | TP_fast_assign( |
| 288 | strncpy(__entry->name, bdi_dev_name(wb->bdi), 32); | 288 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); |
| 289 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb); | 289 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb); |
| 290 | __entry->frn_bdi_id = frn_bdi_id; | 290 | __entry->frn_bdi_id = frn_bdi_id; |
| 291 | __entry->frn_memcg_id = frn_memcg_id; | 291 | __entry->frn_memcg_id = frn_memcg_id; |
| @@ -526,6 +526,8 @@ enum devlink_attr { · 525 unmodified lines | |||
| 526 | DEVLINK_ATTR_RELOAD_STATS_LIMIT, /* u8 */ | 526 | DEVLINK_ATTR_RELOAD_STATS_LIMIT, /* u8 */ |
| 527 | DEVLINK_ATTR_RELOAD_STATS_VALUE, /* u32 */ | 527 | DEVLINK_ATTR_RELOAD_STATS_VALUE, /* u32 */ |
| 528 | DEVLINK_ATTR_REMOTE_RELOAD_STATS, /* nested */ | 528 | DEVLINK_ATTR_REMOTE_RELOAD_STATS, /* nested */ |
| 529 | DEVLINK_ATTR_RELOAD_ACTION_INFO, /* nested */ | ||
| 530 | DEVLINK_ATTR_RELOAD_ACTION_STATS, /* nested */ | ||
| 529 | 531 | ||
| 530 | /* add new attributes above here, update the policy in devlink.c */ | 532 | /* add new attributes above here, update the policy in devlink.c */ |
| 531 | 533 | ||
| @@ -1058,4 +1058,6 @@ enum ovs_dec_ttl_attr { · 1057 unmodified lines | |||
| 1058 | __OVS_DEC_TTL_ATTR_MAX | 1058 | __OVS_DEC_TTL_ATTR_MAX |
| 1059 | }; | 1059 | }; |
| 1060 | 1060 | ||
| 1061 | #define OVS_DEC_TTL_ATTR_MAX (__OVS_DEC_TTL_ATTR_MAX - 1) | ||
| 1062 | |||
| 1061 | #endif /* _LINUX_OPENVSWITCH_H */ | 1063 | #endif /* _LINUX_OPENVSWITCH_H */ |
| @@ -719,7 +719,7 @@ config LOG_CPU_MAX_BUF_SHIFT · 718 unmodified lines | |||
| 719 | with more CPUs. Therefore this value is used only when the sum of | 719 | with more CPUs. Therefore this value is used only when the sum of |
| 720 | contributions is greater than the half of the default kernel ring | 720 | contributions is greater than the half of the default kernel ring |
| 721 | buffer as defined by LOG_BUF_SHIFT. The default values are set | 721 | buffer as defined by LOG_BUF_SHIFT. The default values are set |
| 722 | so that more than 64 CPUs are needed to trigger the allocation. | 722 | so that more than 16 CPUs are needed to trigger the allocation. |
| 723 | 723 | ||
| 724 | Also this option is ignored when "log_buf_len" kernel parameter is | 724 | Also this option is ignored when "log_buf_len" kernel parameter is |
| 725 | used as it forces an exact (power of two) size of the ring buffer. | 725 | used as it forces an exact (power of two) size of the ring buffer. |
| @@ -108,19 +108,21 @@ static inline void lockdep_lock(void) · 107 unmodified lines | |||
| 108 | { | 108 | { |
| 109 | DEBUG_LOCKS_WARN_ON(!irqs_disabled()); | 109 | DEBUG_LOCKS_WARN_ON(!irqs_disabled()); |
| 110 | 110 | ||
| 111 | __this_cpu_inc(lockdep_recursion); | ||
| 111 | arch_spin_lock(&__lock); | 112 | arch_spin_lock(&__lock); |
| 112 | __owner = current; | 113 | __owner = current; |
| 113 | __this_cpu_inc(lockdep_recursion); | ||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | static inline void lockdep_unlock(void) | 116 | static inline void lockdep_unlock(void) |
| 117 | { | 117 | { |
| 118 | DEBUG_LOCKS_WARN_ON(!irqs_disabled()); | ||
| 119 | |||
| 118 | if (debug_locks && DEBUG_LOCKS_WARN_ON(__owner != current)) | 120 | if (debug_locks && DEBUG_LOCKS_WARN_ON(__owner != current)) |
| 119 | return; | 121 | return; |
| 120 | 122 | ||
| 121 | __this_cpu_dec(lockdep_recursion); | ||
| 122 | __owner = NULL; | 123 | __owner = NULL; |
| 123 | arch_spin_unlock(&__lock); | 124 | arch_spin_unlock(&__lock); |
| 125 | __this_cpu_dec(lockdep_recursion); | ||
| 124 | } | 126 | } |
| 125 | 127 | ||
| 126 | static inline bool lockdep_assert_locked(void) | 128 | static inline bool lockdep_assert_locked(void) |
| @@ -528,8 +528,8 @@ static int log_store(u32 caller_id, int facility, int level, · 527 unmodified lines | |||
| 528 | if (dev_info) | 528 | if (dev_info) |
| 529 | memcpy(&r.info->dev_info, dev_info, sizeof(r.info->dev_info)); | 529 | memcpy(&r.info->dev_info, dev_info, sizeof(r.info->dev_info)); |
| 530 | 530 | ||
| 531 | /* insert message */ | 531 | /* A message without a trailing newline can be continued. */ |
| 532 | if ((flags & LOG_CONT) || !(flags & LOG_NEWLINE)) | 532 | if (!(flags & LOG_NEWLINE)) |
| 533 | prb_commit(&e); | 533 | prb_commit(&e); |
| 534 | else | 534 | else |
| 535 | prb_final_commit(&e); | 535 | prb_final_commit(&e); |
| @@ -882,8 +882,6 @@ static bool desc_reserve(struct printk_ringbuffer *rb, unsigned long *id_out) · 881 unmodified lines | |||
| 882 | head_id = atomic_long_read(&desc_ring->head_id); /* LMM(desc_reserve:A) */ | 882 | head_id = atomic_long_read(&desc_ring->head_id); /* LMM(desc_reserve:A) */ |
| 883 | 883 | ||
| 884 | do { | 884 | do { |
| 885 | desc = to_desc(desc_ring, head_id); | ||
| 886 | |||
| 887 | id = DESC_ID(head_id + 1); | 885 | id = DESC_ID(head_id + 1); |
| 888 | id_prev_wrap = DESC_ID_PREV_WRAP(desc_ring, id); | 886 | id_prev_wrap = DESC_ID_PREV_WRAP(desc_ring, id); |
| 889 | 887 | ||
| @@ -264,17 +264,11 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state) · 263 unmodified lines | |||
| 264 | return ret; | 264 | return ret; |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | static bool ptrace_has_cap(const struct cred *cred, struct user_namespace *ns, | 267 | static bool ptrace_has_cap(struct user_namespace *ns, unsigned int mode) |
| 268 | unsigned int mode) | ||
| 269 | { | 268 | { |
| 270 | int ret; | ||
| 271 | |||
| 272 | if (mode & PTRACE_MODE_NOAUDIT) | 269 | if (mode & PTRACE_MODE_NOAUDIT) |
| 273 | ret = security_capable(cred, ns, CAP_SYS_PTRACE, CAP_OPT_NOAUDIT); | 270 | return ns_capable_noaudit(ns, CAP_SYS_PTRACE); |
| 274 | else | 271 | return ns_capable(ns, CAP_SYS_PTRACE); |
| 275 | ret = security_capable(cred, ns, CAP_SYS_PTRACE, CAP_OPT_NONE); | ||
| 276 | |||
| 277 | return ret == 0; | ||
| 278 | } | 272 | } |
| 279 | 273 | ||
| 280 | /* Returns 0 on success, -errno on denial. */ | 274 | /* Returns 0 on success, -errno on denial. */ |
| @@ -326,7 +320,7 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode) · 45 unmodified lines | |||
| 326 | gid_eq(caller_gid, tcred->sgid) && | 320 | gid_eq(caller_gid, tcred->sgid) && |
| 327 | gid_eq(caller_gid, tcred->gid)) | 321 | gid_eq(caller_gid, tcred->gid)) |
| 328 | goto ok; | 322 | goto ok; |
| 329 | if (ptrace_has_cap(cred, tcred->user_ns, mode)) | 323 | if (ptrace_has_cap(tcred->user_ns, mode)) |
| 330 | goto ok; | 324 | goto ok; |
| 331 | rcu_read_unlock(); | 325 | rcu_read_unlock(); |
| 332 | return -EPERM; | 326 | return -EPERM; |
| @@ -345,7 +339,7 @@ ok: · 12 unmodified lines | |||
| 345 | mm = task->mm; | 339 | mm = task->mm; |
| 346 | if (mm && | 340 | if (mm && |
| 347 | ((get_dumpable(mm) != SUID_DUMP_USER) && | 341 | ((get_dumpable(mm) != SUID_DUMP_USER) && |
| 348 | !ptrace_has_cap(cred, mm->user_ns, mode))) | 342 | !ptrace_has_cap(mm->user_ns, mode))) |
| 349 | return -EPERM; | 343 | return -EPERM; |
| 350 | 344 | ||
| 351 | return security_ptrace_access_check(task, mode); | 345 | return security_ptrace_access_check(task, mode); |
| @@ -2501,7 +2501,12 @@ ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags, · 2500 unmodified lines | |||
| 2501 | #ifdef CONFIG_SMP | 2501 | #ifdef CONFIG_SMP |
| 2502 | if (wake_flags & WF_MIGRATED) | 2502 | if (wake_flags & WF_MIGRATED) |
| 2503 | en_flags |= ENQUEUE_MIGRATED; | 2503 | en_flags |= ENQUEUE_MIGRATED; |
| 2504 | else | ||
| 2504 | #endif | 2505 | #endif |
| 2506 | if (p->in_iowait) { | ||
| 2507 | delayacct_blkio_end(p); | ||
| 2508 | atomic_dec(&task_rq(p)->nr_iowait); | ||
| 2509 | } | ||
| 2505 | 2510 | ||
| 2506 | activate_task(rq, p, en_flags); | 2511 | activate_task(rq, p, en_flags); |
| 2507 | ttwu_do_wakeup(rq, p, wake_flags, rf); | 2512 | ttwu_do_wakeup(rq, p, wake_flags, rf); |
| @@ -2888,11 +2893,6 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) · 380 unmodified lines | |||
| 2888 | if (READ_ONCE(p->on_rq) && ttwu_runnable(p, wake_flags)) | 2893 | if (READ_ONCE(p->on_rq) && ttwu_runnable(p, wake_flags)) |
| 2889 | goto unlock; | 2894 | goto unlock; |
| 2890 | 2895 | ||
| 2891 | if (p->in_iowait) { | ||
| 2892 | delayacct_blkio_end(p); | ||
| 2893 | atomic_dec(&task_rq(p)->nr_iowait); | ||
| 2894 | } | ||
| 2895 | |||
| 2896 | #ifdef CONFIG_SMP | 2896 | #ifdef CONFIG_SMP |
| 2897 | /* | 2897 | /* |
| 2898 | * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be | 2898 | * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be |
| @@ -2963,6 +2963,11 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) · 64 unmodified lines | |||
| 2963 | 2963 | ||
| 2964 | cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags); | 2964 | cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags); |
| 2965 | if (task_cpu(p) != cpu) { | 2965 | if (task_cpu(p) != cpu) { |
| 2966 | if (p->in_iowait) { | ||
| 2967 | delayacct_blkio_end(p); | ||
| 2968 | atomic_dec(&task_rq(p)->nr_iowait); | ||
| 2969 | } | ||
| 2970 | |||
| 2966 | wake_flags |= WF_MIGRATED; | 2971 | wake_flags |= WF_MIGRATED; |
| 2967 | psi_ttwu_dequeue(p); | 2972 | psi_ttwu_dequeue(p); |
| 2968 | set_task_cpu(p, cpu); | 2973 | set_task_cpu(p, cpu); |
| @@ -4907,20 +4912,21 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task) · 1938 unmodified lines | |||
| 4907 | if (!dl_prio(p->normal_prio) || | 4912 | if (!dl_prio(p->normal_prio) || |
| 4908 | (pi_task && dl_prio(pi_task->prio) && | 4913 | (pi_task && dl_prio(pi_task->prio) && |
| 4909 | dl_entity_preempt(&pi_task->dl, &p->dl))) { | 4914 | dl_entity_preempt(&pi_task->dl, &p->dl))) { |
| 4910 | p->dl.dl_boosted = 1; | 4915 | p->dl.pi_se = pi_task->dl.pi_se; |
| 4911 | queue_flag |= ENQUEUE_REPLENISH; | 4916 | queue_flag |= ENQUEUE_REPLENISH; |
| 4912 | } else | 4917 | } else { |
| 4913 | p->dl.dl_boosted = 0; | 4918 | p->dl.pi_se = &p->dl; |
| 4919 | } | ||
| 4914 | p->sched_class = &dl_sched_class; | 4920 | p->sched_class = &dl_sched_class; |
| 4915 | } else if (rt_prio(prio)) { | 4921 | } else if (rt_prio(prio)) { |
| 4916 | if (dl_prio(oldprio)) | 4922 | if (dl_prio(oldprio)) |
| 4917 | p->dl.dl_boosted = 0; | 4923 | p->dl.pi_se = &p->dl; |
| 4918 | if (oldprio < prio) | 4924 | if (oldprio < prio) |
| 4919 | queue_flag |= ENQUEUE_HEAD; | 4925 | queue_flag |= ENQUEUE_HEAD; |
| 4920 | p->sched_class = &rt_sched_class; | 4926 | p->sched_class = &rt_sched_class; |
| 4921 | } else { | 4927 | } else { |
| 4922 | if (dl_prio(oldprio)) | 4928 | if (dl_prio(oldprio)) |
| 4923 | p->dl.dl_boosted = 0; | 4929 | p->dl.pi_se = &p->dl; |
| 4924 | if (rt_prio(oldprio)) | 4930 | if (rt_prio(oldprio)) |
| 4925 | p->rt.timeout = 0; | 4931 | p->rt.timeout = 0; |
| 4926 | p->sched_class = &fair_sched_class; | 4932 | p->sched_class = &fair_sched_class; |
| @@ -43,6 +43,28 @@ static inline int on_dl_rq(struct sched_dl_entity *dl_se) · 42 unmodified lines | |||
| 43 | return !RB_EMPTY_NODE(&dl_se->rb_node); | 43 | return !RB_EMPTY_NODE(&dl_se->rb_node); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | #ifdef CONFIG_RT_MUTEXES | ||
| 47 | static inline struct sched_dl_entity *pi_of(struct sched_dl_entity *dl_se) | ||
| 48 | { | ||
| 49 | return dl_se->pi_se; | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline bool is_dl_boosted(struct sched_dl_entity *dl_se) | ||
| 53 | { | ||
| 54 | return pi_of(dl_se) != dl_se; | ||
| 55 | } | ||
| 56 | #else | ||
| 57 | static inline struct sched_dl_entity *pi_of(struct sched_dl_entity *dl_se) | ||
| 58 | { | ||
| 59 | return dl_se; | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline bool is_dl_boosted(struct sched_dl_entity *dl_se) | ||
| 63 | { | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | #endif | ||
| 67 | |||
| 46 | #ifdef CONFIG_SMP | 68 | #ifdef CONFIG_SMP |
| 47 | static inline struct dl_bw *dl_bw_of(int i) | 69 | static inline struct dl_bw *dl_bw_of(int i) |
| 48 | { | 70 | { |
| @@ -698,7 +720,7 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se) · 649 unmodified lines | |||
| 698 | struct dl_rq *dl_rq = dl_rq_of_se(dl_se); | 720 | struct dl_rq *dl_rq = dl_rq_of_se(dl_se); |
| 699 | struct rq *rq = rq_of_dl_rq(dl_rq); | 721 | struct rq *rq = rq_of_dl_rq(dl_rq); |
| 700 | 722 | ||
| 701 | WARN_ON(dl_se->dl_boosted); | 723 | WARN_ON(is_dl_boosted(dl_se)); |
| 702 | WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline)); | 724 | WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline)); |
| 703 | 725 | ||
| 704 | /* | 726 | /* |
| @@ -736,21 +758,20 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se) · 31 unmodified lines | |||
| 736 | * could happen are, typically, a entity voluntarily trying to overcome its | 758 | * could happen are, typically, a entity voluntarily trying to overcome its |
| 737 | * runtime, or it just underestimated it during sched_setattr(). | 759 | * runtime, or it just underestimated it during sched_setattr(). |
| 738 | */ | 760 | */ |
| 739 | static void replenish_dl_entity(struct sched_dl_entity *dl_se, | 761 | static void replenish_dl_entity(struct sched_dl_entity *dl_se) |
| 740 | struct sched_dl_entity *pi_se) | ||
| 741 | { | 762 | { |
| 742 | struct dl_rq *dl_rq = dl_rq_of_se(dl_se); | 763 | struct dl_rq *dl_rq = dl_rq_of_se(dl_se); |
| 743 | struct rq *rq = rq_of_dl_rq(dl_rq); | 764 | struct rq *rq = rq_of_dl_rq(dl_rq); |
| 744 | 765 | ||
| 745 | BUG_ON(pi_se->dl_runtime <= 0); | 766 | BUG_ON(pi_of(dl_se)->dl_runtime <= 0); |
| 746 | 767 | ||
| 747 | /* | 768 | /* |
| 748 | * This could be the case for a !-dl task that is boosted. | 769 | * This could be the case for a !-dl task that is boosted. |
| 749 | * Just go with full inherited parameters. | 770 | * Just go with full inherited parameters. |
| 750 | */ | 771 | */ |
| 751 | if (dl_se->dl_deadline == 0) { | 772 | if (dl_se->dl_deadline == 0) { |
| 752 | dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; | 773 | dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline; |
| 753 | dl_se->runtime = pi_se->dl_runtime; | 774 | dl_se->runtime = pi_of(dl_se)->dl_runtime; |
| 754 | } | 775 | } |
| 755 | 776 | ||
| 756 | if (dl_se->dl_yielded && dl_se->runtime > 0) | 777 | if (dl_se->dl_yielded && dl_se->runtime > 0) |
| @@ -763,8 +784,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se, · 6 unmodified lines | |||
| 763 | * arbitrary large. | 784 | * arbitrary large. |
| 764 | */ | 785 | */ |
| 765 | while (dl_se->runtime <= 0) { | 786 | while (dl_se->runtime <= 0) { |
| 766 | dl_se->deadline += pi_se->dl_period; | 787 | dl_se->deadline += pi_of(dl_se)->dl_period; |
| 767 | dl_se->runtime += pi_se->dl_runtime; | 788 | dl_se->runtime += pi_of(dl_se)->dl_runtime; |
| 768 | } | 789 | } |
| 769 | 790 | ||
| 770 | /* | 791 | /* |
| @@ -778,8 +799,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se, · 7 unmodified lines | |||
| 778 | */ | 799 | */ |
| 779 | if (dl_time_before(dl_se->deadline, rq_clock(rq))) { | 800 | if (dl_time_before(dl_se->deadline, rq_clock(rq))) { |
| 780 | printk_deferred_once("sched: DL replenish lagged too much\n"); | 801 | printk_deferred_once("sched: DL replenish lagged too much\n"); |
| 781 | dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; | 802 | dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline; |
| 782 | dl_se->runtime = pi_se->dl_runtime; | 803 | dl_se->runtime = pi_of(dl_se)->dl_runtime; |
| 783 | } | 804 | } |
| 784 | 805 | ||
| 785 | if (dl_se->dl_yielded) | 806 | if (dl_se->dl_yielded) |
| @@ -812,8 +833,7 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se, · 26 unmodified lines | |||
| 812 | * task with deadline equal to period this is the same of using | 833 | * task with deadline equal to period this is the same of using |
| 813 | * dl_period instead of dl_deadline in the equation above. | 834 | * dl_period instead of dl_deadline in the equation above. |
| 814 | */ | 835 | */ |
| 815 | static bool dl_entity_overflow(struct sched_dl_entity *dl_se, | 836 | static bool dl_entity_overflow(struct sched_dl_entity *dl_se, u64 t) |
| 816 | struct sched_dl_entity *pi_se, u64 t) | ||
| 817 | { | 837 | { |
| 818 | u64 left, right; | 838 | u64 left, right; |
| 819 | 839 | ||
| @@ -835,9 +855,9 @@ static bool dl_entity_overflow(struct sched_dl_entity *dl_se, · 15 unmodified lines | |||
| 835 | * of anything below microseconds resolution is actually fiction | 855 | * of anything below microseconds resolution is actually fiction |
| 836 | * (but still we want to give the user that illusion >;). | 856 | * (but still we want to give the user that illusion >;). |
| 837 | */ | 857 | */ |
| 838 | left = (pi_se->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE); | 858 | left = (pi_of(dl_se)->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE); |
| 839 | right = ((dl_se->deadline - t) >> DL_SCALE) * | 859 | right = ((dl_se->deadline - t) >> DL_SCALE) * |
| 840 | (pi_se->dl_runtime >> DL_SCALE); | 860 | (pi_of(dl_se)->dl_runtime >> DL_SCALE); |
| 841 | 861 | ||
| 842 | return dl_time_before(right, left); | 862 | return dl_time_before(right, left); |
| 843 | } | 863 | } |
| @@ -922,24 +942,23 @@ static inline bool dl_is_implicit(struct sched_dl_entity *dl_se) · 78 unmodified lines | |||
| 922 | * Please refer to the comments update_dl_revised_wakeup() function to find | 942 | * Please refer to the comments update_dl_revised_wakeup() function to find |
| 923 | * more about the Revised CBS rule. | 943 | * more about the Revised CBS rule. |
| 924 | */ | 944 | */ |
| 925 | static void update_dl_entity(struct sched_dl_entity *dl_se, | 945 | static void update_dl_entity(struct sched_dl_entity *dl_se) |
| 926 | struct sched_dl_entity *pi_se) | ||
| 927 | { | 946 | { |
| 928 | struct dl_rq *dl_rq = dl_rq_of_se(dl_se); | 947 | struct dl_rq *dl_rq = dl_rq_of_se(dl_se); |
| 929 | struct rq *rq = rq_of_dl_rq(dl_rq); | 948 | struct rq *rq = rq_of_dl_rq(dl_rq); |
| 930 | 949 | ||
| 931 | if (dl_time_before(dl_se->deadline, rq_clock(rq)) || | 950 | if (dl_time_before(dl_se->deadline, rq_clock(rq)) || |
| 932 | dl_entity_overflow(dl_se, pi_se, rq_clock(rq))) { | 951 | dl_entity_overflow(dl_se, rq_clock(rq))) { |
| 933 | 952 | ||
| 934 | if (unlikely(!dl_is_implicit(dl_se) && | 953 | if (unlikely(!dl_is_implicit(dl_se) && |
| 935 | !dl_time_before(dl_se->deadline, rq_clock(rq)) && | 954 | !dl_time_before(dl_se->deadline, rq_clock(rq)) && |
| 936 | !dl_se->dl_boosted)){ | 955 | !is_dl_boosted(dl_se))) { |
| 937 | update_dl_revised_wakeup(dl_se, rq); | 956 | update_dl_revised_wakeup(dl_se, rq); |
| 938 | return; | 957 | return; |
| 939 | } | 958 | } |
| 940 | 959 | ||
| 941 | dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; | 960 | dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline; |
| 942 | dl_se->runtime = pi_se->dl_runtime; | 961 | dl_se->runtime = pi_of(dl_se)->dl_runtime; |
| 943 | } | 962 | } |
| 944 | } | 963 | } |
| 945 | 964 | ||
| @@ -1038,7 +1057,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer) · 92 unmodified lines | |||
| 1038 | * The task might have been boosted by someone else and might be in the | 1057 | * The task might have been boosted by someone else and might be in the |
| 1039 | * boosting/deboosting path, its not throttled. | 1058 | * boosting/deboosting path, its not throttled. |
| 1040 | */ | 1059 | */ |
| 1041 | if (dl_se->dl_boosted) | 1060 | if (is_dl_boosted(dl_se)) |
| 1042 | goto unlock; | 1061 | goto unlock; |
| 1043 | 1062 | ||
| 1044 | /* | 1063 | /* |
| @@ -1066,7 +1085,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer) · 21 unmodified lines | |||
| 1066 | * but do not enqueue -- wait for our wakeup to do that. | 1085 | * but do not enqueue -- wait for our wakeup to do that. |
| 1067 | */ | 1086 | */ |
| 1068 | if (!task_on_rq_queued(p)) { | 1087 | if (!task_on_rq_queued(p)) { |
| 1069 | replenish_dl_entity(dl_se, dl_se); | 1088 | replenish_dl_entity(dl_se); |
| 1070 | goto unlock; | 1089 | goto unlock; |
| 1071 | } | 1090 | } |
| 1072 | 1091 | ||
| @@ -1156,7 +1175,7 @@ static inline void dl_check_constrained_dl(struct sched_dl_entity *dl_se) · 83 unmodified lines | |||
| 1156 | 1175 | ||
| 1157 | if (dl_time_before(dl_se->deadline, rq_clock(rq)) && | 1176 | if (dl_time_before(dl_se->deadline, rq_clock(rq)) && |
| 1158 | dl_time_before(rq_clock(rq), dl_next_period(dl_se))) { | 1177 | dl_time_before(rq_clock(rq), dl_next_period(dl_se))) { |
| 1159 | if (unlikely(dl_se->dl_boosted || !start_dl_timer(p))) | 1178 | if (unlikely(is_dl_boosted(dl_se) || !start_dl_timer(p))) |
| 1160 | return; | 1179 | return; |
| 1161 | dl_se->dl_throttled = 1; | 1180 | dl_se->dl_throttled = 1; |
| 1162 | if (dl_se->runtime > 0) | 1181 | if (dl_se->runtime > 0) |
| @@ -1287,7 +1306,7 @@ throttle: · 124 unmodified lines | |||
| 1287 | dl_se->dl_overrun = 1; | 1306 | dl_se->dl_overrun = 1; |
| 1288 | 1307 | ||
| 1289 | __dequeue_task_dl(rq, curr, 0); | 1308 | __dequeue_task_dl(rq, curr, 0); |
| 1290 | if (unlikely(dl_se->dl_boosted || !start_dl_timer(curr))) | 1309 | if (unlikely(is_dl_boosted(dl_se) || !start_dl_timer(curr))) |
| 1291 | enqueue_task_dl(rq, curr, ENQUEUE_REPLENISH); | 1310 | enqueue_task_dl(rq, curr, ENQUEUE_REPLENISH); |
| 1292 | 1311 | ||
| 1293 | if (!is_leftmost(curr, &rq->dl)) | 1312 | if (!is_leftmost(curr, &rq->dl)) |
| @@ -1481,8 +1500,7 @@ static void __dequeue_dl_entity(struct sched_dl_entity *dl_se) · 187 unmodified lines | |||
| 1481 | } | 1500 | } |
| 1482 | 1501 | ||
| 1483 | static void | 1502 | static void |
| 1484 | enqueue_dl_entity(struct sched_dl_entity *dl_se, | 1503 | enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags) |
| 1485 | struct sched_dl_entity *pi_se, int flags) | ||
| 1486 | { | 1504 | { |
| 1487 | BUG_ON(on_dl_rq(dl_se)); | 1505 | BUG_ON(on_dl_rq(dl_se)); |
| 1488 | 1506 | ||
| @@ -1493,9 +1511,9 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se, · 4 unmodified lines | |||
| 1493 | */ | 1511 | */ |
| 1494 | if (flags & ENQUEUE_WAKEUP) { | 1512 | if (flags & ENQUEUE_WAKEUP) { |
| 1495 | task_contending(dl_se, flags); | 1513 | task_contending(dl_se, flags); |
| 1496 | update_dl_entity(dl_se, pi_se); | 1514 | update_dl_entity(dl_se); |
| 1497 | } else if (flags & ENQUEUE_REPLENISH) { | 1515 | } else if (flags & ENQUEUE_REPLENISH) { |
| 1498 | replenish_dl_entity(dl_se, pi_se); | 1516 | replenish_dl_entity(dl_se); |
| 1499 | } else if ((flags & ENQUEUE_RESTORE) && | 1517 | } else if ((flags & ENQUEUE_RESTORE) && |
| 1500 | dl_time_before(dl_se->deadline, | 1518 | dl_time_before(dl_se->deadline, |
| 1501 | rq_clock(rq_of_dl_rq(dl_rq_of_se(dl_se))))) { | 1519 | rq_clock(rq_of_dl_rq(dl_rq_of_se(dl_se))))) { |
| @@ -1512,19 +1530,7 @@ static void dequeue_dl_entity(struct sched_dl_entity *dl_se) · 10 unmodified lines | |||
| 1512 | 1530 | ||
| 1513 | static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) | 1531 | static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) |
| 1514 | { | 1532 | { |
| 1515 | struct task_struct *pi_task = rt_mutex_get_top_task(p); | 1533 | if (is_dl_boosted(&p->dl)) { |
| 1516 | struct sched_dl_entity *pi_se = &p->dl; | ||
| 1517 | |||
| 1518 | /* | ||
| 1519 | * Use the scheduling parameters of the top pi-waiter task if: | ||
| 1520 | * - we have a top pi-waiter which is a SCHED_DEADLINE task AND | ||
| 1521 | * - our dl_boosted is set (i.e. the pi-waiter's (absolute) deadline is | ||
| 1522 | * smaller than our deadline OR we are a !SCHED_DEADLINE task getting | ||
| 1523 | * boosted due to a SCHED_DEADLINE pi-waiter). | ||
| 1524 | * Otherwise we keep our runtime and deadline. | ||
| 1525 | */ | ||
| 1526 | if (pi_task && dl_prio(pi_task->normal_prio) && p->dl.dl_boosted) { | ||
| 1527 | pi_se = &pi_task->dl; | ||
| 1528 | /* | 1534 | /* |
| 1529 | * Because of delays in the detection of the overrun of a | 1535 | * Because of delays in the detection of the overrun of a |
| 1530 | * thread's runtime, it might be the case that a thread | 1536 | * thread's runtime, it might be the case that a thread |
| @@ -1557,7 +1563,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) · 26 unmodified lines | |||
| 1557 | * the throttle. | 1563 | * the throttle. |
| 1558 | */ | 1564 | */ |
| 1559 | p->dl.dl_throttled = 0; | 1565 | p->dl.dl_throttled = 0; |
| 1560 | BUG_ON(!p->dl.dl_boosted || flags != ENQUEUE_REPLENISH); | 1566 | BUG_ON(!is_dl_boosted(&p->dl) || flags != ENQUEUE_REPLENISH); |
| 1561 | return; | 1567 | return; |
| 1562 | } | 1568 | } |
| 1563 | 1569 | ||
| @@ -1594,7 +1600,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) · 30 unmodified lines | |||
| 1594 | return; | 1600 | return; |
| 1595 | } | 1601 | } |
| 1596 | 1602 | ||
| 1597 | enqueue_dl_entity(&p->dl, pi_se, flags); | 1603 | enqueue_dl_entity(&p->dl, flags); |
| 1598 | 1604 | ||
| 1599 | if (!task_current(rq, p) && p->nr_cpus_allowed > 1) | 1605 | if (!task_current(rq, p) && p->nr_cpus_allowed > 1) |
| 1600 | enqueue_pushable_dl_task(rq, p); | 1606 | enqueue_pushable_dl_task(rq, p); |
| @@ -2787,11 +2793,14 @@ void __dl_clear_params(struct task_struct *p) · 1186 unmodified lines | |||
| 2787 | dl_se->dl_bw = 0; | 2793 | dl_se->dl_bw = 0; |
| 2788 | dl_se->dl_density = 0; | 2794 | dl_se->dl_density = 0; |
| 2789 | 2795 | ||
| 2790 | dl_se->dl_boosted = 0; | ||
| 2791 | dl_se->dl_throttled = 0; | 2796 | dl_se->dl_throttled = 0; |
| 2792 | dl_se->dl_yielded = 0; | 2797 | dl_se->dl_yielded = 0; |
| 2793 | dl_se->dl_non_contending = 0; | 2798 | dl_se->dl_non_contending = 0; |
| 2794 | dl_se->dl_overrun = 0; | 2799 | dl_se->dl_overrun = 0; |
| 2800 | |||
| 2801 | #ifdef CONFIG_RT_MUTEXES | ||
| 2802 | dl_se->pi_se = dl_se; | ||
| 2803 | #endif | ||
| 2795 | } | 2804 | } |
| 2796 | 2805 | ||
| 2797 | bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr) | 2806 | bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr) |
| @@ -5477,6 +5477,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) · 5476 unmodified lines | |||
| 5477 | struct cfs_rq *cfs_rq; | 5477 | struct cfs_rq *cfs_rq; |
| 5478 | struct sched_entity *se = &p->se; | 5478 | struct sched_entity *se = &p->se; |
| 5479 | int idle_h_nr_running = task_has_idle_policy(p); | 5479 | int idle_h_nr_running = task_has_idle_policy(p); |
| 5480 | int task_new = !(flags & ENQUEUE_WAKEUP); | ||
| 5480 | 5481 | ||
| 5481 | /* | 5482 | /* |
| 5482 | * The code below (indirectly) updates schedutil which looks at | 5483 | * The code below (indirectly) updates schedutil which looks at |
| @@ -5549,7 +5550,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) · 66 unmodified lines | |||
| 5549 | * into account, but that is not straightforward to implement, | 5550 | * into account, but that is not straightforward to implement, |
| 5550 | * and the following generally works well enough in practice. | 5551 | * and the following generally works well enough in practice. |
| 5551 | */ | 5552 | */ |
| 5552 | if (flags & ENQUEUE_WAKEUP) | 5553 | if (!task_new) |
| 5553 | update_overutilized_status(rq); | 5554 | update_overutilized_status(rq); |
| 5554 | 5555 | ||
| 5555 | enqueue_throttle: | 5556 | enqueue_throttle: |
| @@ -38,7 +38,7 @@ · 37 unmodified lines | |||
| 38 | #include <linux/filter.h> | 38 | #include <linux/filter.h> |
| 39 | #include <linux/pid.h> | 39 | #include <linux/pid.h> |
| 40 | #include <linux/ptrace.h> | 40 | #include <linux/ptrace.h> |
| 41 | #include <linux/security.h> | 41 | #include <linux/capability.h> |
| 42 | #include <linux/tracehook.h> | 42 | #include <linux/tracehook.h> |
| 43 | #include <linux/uaccess.h> | 43 | #include <linux/uaccess.h> |
| 44 | #include <linux/anon_inodes.h> | 44 | #include <linux/anon_inodes.h> |
| @@ -558,8 +558,7 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog) · 513 unmodified lines | |||
| 558 | * behavior of privileged children. | 558 | * behavior of privileged children. |
| 559 | */ | 559 | */ |
| 560 | if (!task_no_new_privs(current) && | 560 | if (!task_no_new_privs(current) && |
| 561 | security_capable(current_cred(), current_user_ns(), | 561 | !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) |
| 562 | CAP_SYS_ADMIN, CAP_OPT_NOAUDIT) != 0) | ||
| 563 | return ERR_PTR(-EACCES); | 562 | return ERR_PTR(-EACCES); |
| 564 | 563 | ||
| 565 | /* Allocate a new seccomp_filter */ | 564 | /* Allocate a new seccomp_filter */ |
| @@ -1484,11 +1484,19 @@ void end_page_writeback(struct page *page) · 1483 unmodified lines | |||
| 1484 | rotate_reclaimable_page(page); | 1484 | rotate_reclaimable_page(page); |
| 1485 | } | 1485 | } |
| 1486 | 1486 | ||
| 1487 | /* | ||
| 1488 | * Writeback does not hold a page reference of its own, relying | ||
| 1489 | * on truncation to wait for the clearing of PG_writeback. | ||
| 1490 | * But here we must make sure that the page is not freed and | ||
| 1491 | * reused before the wake_up_page(). | ||
| 1492 | */ | ||
| 1493 | get_page(page); | ||
| 1487 | if (!test_clear_page_writeback(page)) | 1494 | if (!test_clear_page_writeback(page)) |
| 1488 | BUG(); | 1495 | BUG(); |
| 1489 | 1496 | ||
| 1490 | smp_mb__after_atomic(); | 1497 | smp_mb__after_atomic(); |
| 1491 | wake_up_page(page, PG_writeback); | 1498 | wake_up_page(page, PG_writeback); |
| 1499 | put_page(page); | ||
| 1492 | } | 1500 | } |
| 1493 | EXPORT_SYMBOL(end_page_writeback); | 1501 | EXPORT_SYMBOL(end_page_writeback); |
| 1494 | 1502 | ||
| @@ -2347,10 +2355,15 @@ page_ok: · 852 unmodified lines | |||
| 2347 | 2355 | ||
| 2348 | page_not_up_to_date: | 2356 | page_not_up_to_date: |
| 2349 | /* Get exclusive access to the page ... */ | 2357 | /* Get exclusive access to the page ... */ |
| 2350 | if (iocb->ki_flags & IOCB_WAITQ) | 2358 | if (iocb->ki_flags & IOCB_WAITQ) { |
| 2359 | if (written) { | ||
| 2360 | put_page(page); | ||
| 2361 | goto out; | ||
| 2362 | } | ||
| 2351 | error = lock_page_async(page, iocb->ki_waitq); | 2363 | error = lock_page_async(page, iocb->ki_waitq); |
| 2352 | else | 2364 | } else { |
| 2353 | error = lock_page_killable(page); | 2365 | error = lock_page_killable(page); |
| 2366 | } | ||
| 2354 | if (unlikely(error)) | 2367 | if (unlikely(error)) |
| 2355 | goto readpage_error; | 2368 | goto readpage_error; |
| 2356 | 2369 | ||
| @@ -2393,10 +2406,15 @@ readpage: · 36 unmodified lines | |||
| 2393 | } | 2406 | } |
| 2394 | 2407 | ||
| 2395 | if (!PageUptodate(page)) { | 2408 | if (!PageUptodate(page)) { |
| 2396 | if (iocb->ki_flags & IOCB_WAITQ) | 2409 | if (iocb->ki_flags & IOCB_WAITQ) { |
| 2410 | if (written) { | ||
| 2411 | put_page(page); | ||
| 2412 | goto out; | ||
| 2413 | } | ||
| 2397 | error = lock_page_async(page, iocb->ki_waitq); | 2414 | error = lock_page_async(page, iocb->ki_waitq); |
| 2398 | else | 2415 | } else { |
| 2399 | error = lock_page_killable(page); | 2416 | error = lock_page_killable(page); |
| 2417 | } | ||
| 2400 | 2418 | ||
| 2401 | if (unlikely(error)) | 2419 | if (unlikely(error)) |
| 2402 | goto readpage_error; | 2420 | goto readpage_error; |
| @@ -710,7 +710,6 @@ vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf) · 709 unmodified lines | |||
| 710 | transparent_hugepage_use_zero_page()) { | 710 | transparent_hugepage_use_zero_page()) { |
| 711 | pgtable_t pgtable; | 711 | pgtable_t pgtable; |
| 712 | struct page *zero_page; | 712 | struct page *zero_page; |
| 713 | bool set; | ||
| 714 | vm_fault_t ret; | 713 | vm_fault_t ret; |
| 715 | pgtable = pte_alloc_one(vma->vm_mm); | 714 | pgtable = pte_alloc_one(vma->vm_mm); |
| 716 | if (unlikely(!pgtable)) | 715 | if (unlikely(!pgtable)) |
| @@ -723,25 +722,25 @@ vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf) · 6 unmodified lines | |||
| 723 | } | 722 | } |
| 724 | vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); | 723 | vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); |
| 725 | ret = 0; | 724 | ret = 0; |
| 726 | set = false; | ||
| 727 | if (pmd_none(*vmf->pmd)) { | 725 | if (pmd_none(*vmf->pmd)) { |
| 728 | ret = check_stable_address_space(vma->vm_mm); | 726 | ret = check_stable_address_space(vma->vm_mm); |
| 729 | if (ret) { | 727 | if (ret) { |
| 730 | spin_unlock(vmf->ptl); | 728 | spin_unlock(vmf->ptl); |
| 729 | pte_free(vma->vm_mm, pgtable); | ||
| 731 | } else if (userfaultfd_missing(vma)) { | 730 | } else if (userfaultfd_missing(vma)) { |
| 732 | spin_unlock(vmf->ptl); | 731 | spin_unlock(vmf->ptl); |
| 732 | pte_free(vma->vm_mm, pgtable); | ||
| 733 | ret = handle_userfault(vmf, VM_UFFD_MISSING); | 733 | ret = handle_userfault(vmf, VM_UFFD_MISSING); |
| 734 | VM_BUG_ON(ret & VM_FAULT_FALLBACK); | 734 | VM_BUG_ON(ret & VM_FAULT_FALLBACK); |
| 735 | } else { | 735 | } else { |
| 736 | set_huge_zero_page(pgtable, vma->vm_mm, vma, | 736 | set_huge_zero_page(pgtable, vma->vm_mm, vma, |
| 737 | haddr, vmf->pmd, zero_page); | 737 | haddr, vmf->pmd, zero_page); |
| 738 | spin_unlock(vmf->ptl); | 738 | spin_unlock(vmf->ptl); |
| 739 | set = true; | ||
| 740 | } | 739 | } |
| 741 | } else | 740 | } else { |
| 742 | spin_unlock(vmf->ptl); | 741 | spin_unlock(vmf->ptl); |
| 743 | if (!set) | ||
| 744 | pte_free(vma->vm_mm, pgtable); | 742 | pte_free(vma->vm_mm, pgtable); |
| 743 | } | ||
| 745 | return ret; | 744 | return ret; |
| 746 | } | 745 | } |
| 747 | gfp = alloc_hugepage_direct_gfpmask(vma); | 746 | gfp = alloc_hugepage_direct_gfpmask(vma); |
| @@ -226,7 +226,7 @@ static void force_shm_swapin_readahead(struct vm_area_struct *vma, · 225 unmodified lines | |||
| 226 | struct address_space *mapping) | 226 | struct address_space *mapping) |
| 227 | { | 227 | { |
| 228 | XA_STATE(xas, &mapping->i_pages, linear_page_index(vma, start)); | 228 | XA_STATE(xas, &mapping->i_pages, linear_page_index(vma, start)); |
| 229 | pgoff_t end_index = end / PAGE_SIZE; | 229 | pgoff_t end_index = linear_page_index(vma, end + PAGE_SIZE - 1); |
| 230 | struct page *page; | 230 | struct page *page; |
| 231 | 231 | ||
| 232 | rcu_read_lock(); | 232 | rcu_read_lock(); |
| @@ -1231,8 +1231,6 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec, · 998 unmodified lines | |||
| 1231 | ret = total_len - iov_iter_count(&iter); | 1231 | ret = total_len - iov_iter_count(&iter); |
| 1232 | 1232 | ||
| 1233 | mmput(mm); | 1233 | mmput(mm); |
| 1234 | return ret; | ||
| 1235 | |||
| 1236 | release_task: | 1234 | release_task: |
| 1237 | put_task_struct(task); | 1235 | put_task_struct(task); |
| 1238 | put_pid: | 1236 | put_pid: |
| @@ -867,8 +867,13 @@ void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, int val) · 866 unmodified lines | |||
| 867 | rcu_read_lock(); | 867 | rcu_read_lock(); |
| 868 | memcg = mem_cgroup_from_obj(p); | 868 | memcg = mem_cgroup_from_obj(p); |
| 869 | 869 | ||
| 870 | /* Untracked pages have no memcg, no lruvec. Update only the node */ | 870 | /* |
| 871 | if (!memcg || memcg == root_mem_cgroup) { | 871 | * Untracked pages have no memcg, no lruvec. Update only the |
| 872 | * node. If we reparent the slab objects to the root memcg, | ||
| 873 | * when we free the slab object, we need to update the per-memcg | ||
| 874 | * vmstats to keep it correct for the root memcg. | ||
| 875 | */ | ||
| 876 | if (!memcg) { | ||
| 872 | __mod_node_page_state(pgdat, idx, val); | 877 | __mod_node_page_state(pgdat, idx, val); |
| 873 | } else { | 878 | } else { |
| 874 | lruvec = mem_cgroup_lruvec(memcg, pgdat); | 879 | lruvec = mem_cgroup_lruvec(memcg, pgdat); |
| @@ -350,24 +350,6 @@ int __ref __add_pages(int nid, unsigned long pfn, unsigned long nr_pages, · 349 unmodified lines | |||
| 350 | return err; | 350 | return err; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | #ifdef CONFIG_NUMA | ||
| 354 | int __weak memory_add_physaddr_to_nid(u64 start) | ||
| 355 | { | ||
| 356 | pr_info_once("Unknown online node for memory at 0x%llx, assuming node 0\n", | ||
| 357 | start); | ||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); | ||
| 361 | |||
| 362 | int __weak phys_to_target_node(u64 start) | ||
| 363 | { | ||
| 364 | pr_info_once("Unknown target node for memory at 0x%llx, assuming node 0\n", | ||
| 365 | start); | ||
| 366 | return 0; | ||
| 367 | } | ||
| 368 | EXPORT_SYMBOL_GPL(phys_to_target_node); | ||
| 369 | #endif | ||
| 370 | |||
| 371 | /* find the smallest valid pfn in the range [start_pfn, end_pfn) */ | 353 | /* find the smallest valid pfn in the range [start_pfn, end_pfn) */ |
| 372 | static unsigned long find_smallest_section_pfn(int nid, struct zone *zone, | 354 | static unsigned long find_smallest_section_pfn(int nid, struct zone *zone, |
| 373 | unsigned long start_pfn, | 355 | unsigned long start_pfn, |
| @@ -2754,12 +2754,6 @@ int test_clear_page_writeback(struct page *page) · 2753 unmodified lines | |||
| 2754 | } else { | 2754 | } else { |
| 2755 | ret = TestClearPageWriteback(page); | 2755 | ret = TestClearPageWriteback(page); |
| 2756 | } | 2756 | } |
| 2757 | /* | ||
| 2758 | * NOTE: Page might be free now! Writeback doesn't hold a page | ||
| 2759 | * reference on its own, it relies on truncation to wait for | ||
| 2760 | * the clearing of PG_writeback. The below can only access | ||
| 2761 | * page state that is static across allocation cycles. | ||
| 2762 | */ | ||
| 2763 | if (ret) { | 2757 | if (ret) { |
| 2764 | dec_lruvec_state(lruvec, NR_WRITEBACK); | 2758 | dec_lruvec_state(lruvec, NR_WRITEBACK); |
| 2765 | dec_zone_page_state(page, NR_ZONE_WRITE_PENDING); | 2759 | dec_zone_page_state(page, NR_ZONE_WRITE_PENDING); |
| @@ -180,6 +180,7 @@ static const struct file_operations batadv_log_fops = { · 179 unmodified lines | |||
| 180 | .read = batadv_log_read, | 180 | .read = batadv_log_read, |
| 181 | .poll = batadv_log_poll, | 181 | .poll = batadv_log_poll, |
| 182 | .llseek = no_llseek, | 182 | .llseek = no_llseek, |
| 183 | .owner = THIS_MODULE, | ||
| 183 | }; | 184 | }; |
| 184 | 185 | ||
| 185 | /** | 186 | /** |
| @@ -541,10 +541,13 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, · 540 unmodified lines | |||
| 541 | 541 | ||
| 542 | /* Check for bugs in CAN protocol implementations using af_can.c: | 542 | /* Check for bugs in CAN protocol implementations using af_can.c: |
| 543 | * 'rcv' will be NULL if no matching list item was found for removal. | 543 | * 'rcv' will be NULL if no matching list item was found for removal. |
| 544 | * As this case may potentially happen when closing a socket while | ||
| 545 | * the notifier for removing the CAN netdev is running we just print | ||
| 546 | * a warning here. | ||
| 544 | */ | 547 | */ |
| 545 | if (!rcv) { | 548 | if (!rcv) { |
| 546 | WARN(1, "BUG: receive list entry not found for dev %s, id %03X, mask %03X\n", | 549 | pr_warn("can: receive list entry not found for dev %s, id %03X, mask %03X\n", |
| 547 | DNAME(dev), can_id, mask); | 550 | DNAME(dev), can_id, mask); |
| 548 | goto out; | 551 | goto out; |
| 549 | } | 552 | } |
| 550 | 553 | ||
| @@ -517,7 +517,7 @@ devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_l · 516 unmodified lines | |||
| 517 | return test_bit(limit, &devlink->ops->reload_limits); | 517 | return test_bit(limit, &devlink->ops->reload_limits); |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_action action, | 520 | static int devlink_reload_stat_put(struct sk_buff *msg, |
| 521 | enum devlink_reload_limit limit, u32 value) | 521 | enum devlink_reload_limit limit, u32 value) |
| 522 | { | 522 | { |
| 523 | struct nlattr *reload_stats_entry; | 523 | struct nlattr *reload_stats_entry; |
| @@ -526,8 +526,7 @@ static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_acti · 2 unmodified lines | |||
| 526 | if (!reload_stats_entry) | 526 | if (!reload_stats_entry) |
| 527 | return -EMSGSIZE; | 527 | return -EMSGSIZE; |
| 528 | 528 | ||
| 529 | if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, action) || | 529 | if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || |
| 530 | nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || | ||
| 531 | nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) | 530 | nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) |
| 532 | goto nla_put_failure; | 531 | goto nla_put_failure; |
| 533 | nla_nest_end(msg, reload_stats_entry); | 532 | nla_nest_end(msg, reload_stats_entry); |
| @@ -540,7 +539,7 @@ nla_put_failure: · 6 unmodified lines | |||
| 540 | 539 | ||
| 541 | static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) | 540 | static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) |
| 542 | { | 541 | { |
| 543 | struct nlattr *reload_stats_attr; | 542 | struct nlattr *reload_stats_attr, *act_info, *act_stats; |
| 544 | int i, j, stat_idx; | 543 | int i, j, stat_idx; |
| 545 | u32 value; | 544 | u32 value; |
| 546 | 545 | ||
| @@ -552,17 +551,29 @@ static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink · 5 unmodified lines | |||
| 552 | if (!reload_stats_attr) | 551 | if (!reload_stats_attr) |
| 553 | return -EMSGSIZE; | 552 | return -EMSGSIZE; |
| 554 | 553 | ||
| 555 | for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { | 554 | for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { |
| 556 | /* Remote stats are shown even if not locally supported. Stats | 555 | if ((!is_remote && |
| 557 | * of actions with unspecified limit are shown though drivers | 556 | !devlink_reload_action_is_supported(devlink, i)) || |
| 558 | * don't need to register unspecified limit. | 557 | i == DEVLINK_RELOAD_ACTION_UNSPEC) |
| 559 | */ | ||
| 560 | if (!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && | ||
| 561 | !devlink_reload_limit_is_supported(devlink, j)) | ||
| 562 | continue; | 558 | continue; |
| 563 | for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { | 559 | act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); |
| 564 | if ((!is_remote && !devlink_reload_action_is_supported(devlink, i)) || | 560 | if (!act_info) |
| 565 | i == DEVLINK_RELOAD_ACTION_UNSPEC || | 561 | goto nla_put_failure; |
| 562 | |||
| 563 | if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) | ||
| 564 | goto action_info_nest_cancel; | ||
| 565 | act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); | ||
| 566 | if (!act_stats) | ||
| 567 | goto action_info_nest_cancel; | ||
| 568 | |||
| 569 | for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { | ||
| 570 | /* Remote stats are shown even if not locally supported. | ||
| 571 | * Stats of actions with unspecified limit are shown | ||
| 572 | * though drivers don't need to register unspecified | ||
| 573 | * limit. | ||
| 574 | */ | ||
| 575 | if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && | ||
| 576 | !devlink_reload_limit_is_supported(devlink, j)) || | ||
| 566 | devlink_reload_combination_is_invalid(i, j)) | 577 | devlink_reload_combination_is_invalid(i, j)) |
| 567 | continue; | 578 | continue; |
| 568 | 579 | ||
| @@ -571,13 +582,19 @@ static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink · 2 unmodified lines | |||
| 571 | value = devlink->stats.reload_stats[stat_idx]; | 582 | value = devlink->stats.reload_stats[stat_idx]; |
| 572 | else | 583 | else |
| 573 | value = devlink->stats.remote_reload_stats[stat_idx]; | 584 | value = devlink->stats.remote_reload_stats[stat_idx]; |
| 574 | if (devlink_reload_stat_put(msg, i, j, value)) | 585 | if (devlink_reload_stat_put(msg, j, value)) |
| 575 | goto nla_put_failure; | 586 | goto action_stats_nest_cancel; |
| 576 | } | 587 | } |
| 588 | nla_nest_end(msg, act_stats); | ||
| 589 | nla_nest_end(msg, act_info); | ||
| 577 | } | 590 | } |
| 578 | nla_nest_end(msg, reload_stats_attr); | 591 | nla_nest_end(msg, reload_stats_attr); |
| 579 | return 0; | 592 | return 0; |
| 580 | 593 | ||
| 594 | action_stats_nest_cancel: | ||
| 595 | nla_nest_cancel(msg, act_stats); | ||
| 596 | action_info_nest_cancel: | ||
| 597 | nla_nest_cancel(msg, act_info); | ||
| 581 | nla_put_failure: | 598 | nla_put_failure: |
| 582 | nla_nest_cancel(msg, reload_stats_attr); | 599 | nla_nest_cancel(msg, reload_stats_attr); |
| 583 | return -EMSGSIZE; | 600 | return -EMSGSIZE; |
| @@ -755,6 +772,8 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink, · 171 unmodified lines | |||
| 755 | if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) | 772 | if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) |
| 756 | goto nla_put_failure; | 773 | goto nla_put_failure; |
| 757 | 774 | ||
| 775 | /* Hold rtnl lock while accessing port's netdev attributes. */ | ||
| 776 | rtnl_lock(); | ||
| 758 | spin_lock_bh(&devlink_port->type_lock); | 777 | spin_lock_bh(&devlink_port->type_lock); |
| 759 | if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) | 778 | if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) |
| 760 | goto nla_put_failure_type_locked; | 779 | goto nla_put_failure_type_locked; |
| @@ -763,9 +782,10 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink, · 2 unmodified lines | |||
| 763 | devlink_port->desired_type)) | 782 | devlink_port->desired_type)) |
| 764 | goto nla_put_failure_type_locked; | 783 | goto nla_put_failure_type_locked; |
| 765 | if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { | 784 | if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { |
| 785 | struct net *net = devlink_net(devlink_port->devlink); | ||
| 766 | struct net_device *netdev = devlink_port->type_dev; | 786 | struct net_device *netdev = devlink_port->type_dev; |
| 767 | 787 | ||
| 768 | if (netdev && | 788 | if (netdev && net_eq(net, dev_net(netdev)) && |
| 769 | (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, | 789 | (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, |
| 770 | netdev->ifindex) || | 790 | netdev->ifindex) || |
| 771 | nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, | 791 | nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, |
| @@ -781,6 +801,7 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink, · 9 unmodified lines | |||
| 781 | goto nla_put_failure_type_locked; | 801 | goto nla_put_failure_type_locked; |
| 782 | } | 802 | } |
| 783 | spin_unlock_bh(&devlink_port->type_lock); | 803 | spin_unlock_bh(&devlink_port->type_lock); |
| 804 | rtnl_unlock(); | ||
| 784 | if (devlink_nl_port_attrs_put(msg, devlink_port)) | 805 | if (devlink_nl_port_attrs_put(msg, devlink_port)) |
| 785 | goto nla_put_failure; | 806 | goto nla_put_failure; |
| 786 | if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) | 807 | if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) |
| @@ -791,6 +812,7 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink, · 4 unmodified lines | |||
| 791 | 812 | ||
| 792 | nla_put_failure_type_locked: | 813 | nla_put_failure_type_locked: |
| 793 | spin_unlock_bh(&devlink_port->type_lock); | 814 | spin_unlock_bh(&devlink_port->type_lock); |
| 815 | rtnl_unlock(); | ||
| 794 | nla_put_failure: | 816 | nla_put_failure: |
| 795 | genlmsg_cancel(msg, hdr); | 817 | genlmsg_cancel(msg, hdr); |
| 796 | return -EMSGSIZE; | 818 | return -EMSGSIZE; |
| @@ -99,9 +99,14 @@ void gro_cells_destroy(struct gro_cells *gcells) · 98 unmodified lines | |||
| 99 | struct gro_cell *cell = per_cpu_ptr(gcells->cells, i); | 99 | struct gro_cell *cell = per_cpu_ptr(gcells->cells, i); |
| 100 | 100 | ||
| 101 | napi_disable(&cell->napi); | 101 | napi_disable(&cell->napi); |
| 102 | netif_napi_del(&cell->napi); | 102 | __netif_napi_del(&cell->napi); |
| 103 | __skb_queue_purge(&cell->napi_skbs); | 103 | __skb_queue_purge(&cell->napi_skbs); |
| 104 | } | 104 | } |
| 105 | /* This barrier is needed because netpoll could access dev->napi_list | ||
| 106 | * under rcu protection. | ||
| 107 | */ | ||
| 108 | synchronize_net(); | ||
| 109 | |||
| 105 | free_percpu(gcells->cells); | 110 | free_percpu(gcells->cells); |
| 106 | gcells->cells = NULL; | 111 | gcells->cells = NULL; |
| 107 | } | 112 | } |
| @@ -4562,7 +4562,7 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk) · 4561 unmodified lines | |||
| 4562 | if (skb && (skb_next = skb_peek(q))) { | 4562 | if (skb && (skb_next = skb_peek(q))) { |
| 4563 | icmp_next = is_icmp_err_skb(skb_next); | 4563 | icmp_next = is_icmp_err_skb(skb_next); |
| 4564 | if (icmp_next) | 4564 | if (icmp_next) |
| 4565 | sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_origin; | 4565 | sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_errno; |
| 4566 | } | 4566 | } |
| 4567 | spin_unlock_irqrestore(&q->lock, flags); | 4567 | spin_unlock_irqrestore(&q->lock, flags); |
| 4568 | 4568 | ||
| @@ -427,7 +427,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, · 426 unmodified lines | |||
| 427 | 427 | ||
| 428 | if (__inet_inherit_port(sk, newsk) < 0) | 428 | if (__inet_inherit_port(sk, newsk) < 0) |
| 429 | goto put_and_exit; | 429 | goto put_and_exit; |
| 430 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); | 430 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL); |
| 431 | if (*own_req) | 431 | if (*own_req) |
| 432 | ireq->ireq_opt = NULL; | 432 | ireq->ireq_opt = NULL; |
| 433 | else | 433 | else |
| @@ -533,7 +533,7 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, · 532 unmodified lines | |||
| 533 | dccp_done(newsk); | 533 | dccp_done(newsk); |
| 534 | goto out; | 534 | goto out; |
| 535 | } | 535 | } |
| 536 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); | 536 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL); |
| 537 | /* Clone pktoptions received with SYN, if we own the req */ | 537 | /* Clone pktoptions received with SYN, if we own the req */ |
| 538 | if (*own_req && ireq->pktopts) { | 538 | if (*own_req && ireq->pktopts) { |
| 539 | newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC); | 539 | newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC); |
| @@ -787,7 +787,7 @@ static void reqsk_queue_hash_req(struct request_sock *req, · 786 unmodified lines | |||
| 787 | timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED); | 787 | timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED); |
| 788 | mod_timer(&req->rsk_timer, jiffies + timeout); | 788 | mod_timer(&req->rsk_timer, jiffies + timeout); |
| 789 | 789 | ||
| 790 | inet_ehash_insert(req_to_sk(req), NULL); | 790 | inet_ehash_insert(req_to_sk(req), NULL, NULL); |
| 791 | /* before letting lookups find us, make sure all req fields | 791 | /* before letting lookups find us, make sure all req fields |
| 792 | * are committed to memory and refcnt initialized. | 792 | * are committed to memory and refcnt initialized. |
| 793 | */ | 793 | */ |
| @@ -20,6 +20,9 @@ · 19 unmodified lines | |||
| 20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
| 21 | #include <net/inet_connection_sock.h> | 21 | #include <net/inet_connection_sock.h> |
| 22 | #include <net/inet_hashtables.h> | 22 | #include <net/inet_hashtables.h> |
| 23 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 24 | #include <net/inet6_hashtables.h> | ||
| 25 | #endif | ||
| 23 | #include <net/secure_seq.h> | 26 | #include <net/secure_seq.h> |
| 24 | #include <net/ip.h> | 27 | #include <net/ip.h> |
| 25 | #include <net/tcp.h> | 28 | #include <net/tcp.h> |
| @@ -508,10 +511,52 @@ static u32 inet_sk_port_offset(const struct sock *sk) · 482 unmodified lines | |||
| 508 | inet->inet_dport); | 511 | inet->inet_dport); |
| 509 | } | 512 | } |
| 510 | 513 | ||
| 511 | /* insert a socket into ehash, and eventually remove another one | 514 | /* Searches for an exsiting socket in the ehash bucket list. |
| 512 | * (The another one can be a SYN_RECV or TIMEWAIT | 515 | * Returns true if found, false otherwise. |
| 513 | */ | 516 | */ |
| 514 | bool inet_ehash_insert(struct sock *sk, struct sock *osk) | 517 | static bool inet_ehash_lookup_by_sk(struct sock *sk, |
| 518 | struct hlist_nulls_head *list) | ||
| 519 | { | ||
| 520 | const __portpair ports = INET_COMBINED_PORTS(sk->sk_dport, sk->sk_num); | ||
| 521 | const int sdif = sk->sk_bound_dev_if; | ||
| 522 | const int dif = sk->sk_bound_dev_if; | ||
| 523 | const struct hlist_nulls_node *node; | ||
| 524 | struct net *net = sock_net(sk); | ||
| 525 | struct sock *esk; | ||
| 526 | |||
| 527 | INET_ADDR_COOKIE(acookie, sk->sk_daddr, sk->sk_rcv_saddr); | ||
| 528 | |||
| 529 | sk_nulls_for_each_rcu(esk, node, list) { | ||
| 530 | if (esk->sk_hash != sk->sk_hash) | ||
| 531 | continue; | ||
| 532 | if (sk->sk_family == AF_INET) { | ||
| 533 | if (unlikely(INET_MATCH(esk, net, acookie, | ||
| 534 | sk->sk_daddr, | ||
| 535 | sk->sk_rcv_saddr, | ||
| 536 | ports, dif, sdif))) { | ||
| 537 | return true; | ||
| 538 | } | ||
| 539 | } | ||
| 540 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 541 | else if (sk->sk_family == AF_INET6) { | ||
| 542 | if (unlikely(INET6_MATCH(esk, net, | ||
| 543 | &sk->sk_v6_daddr, | ||
| 544 | &sk->sk_v6_rcv_saddr, | ||
| 545 | ports, dif, sdif))) { | ||
| 546 | return true; | ||
| 547 | } | ||
| 548 | } | ||
| 549 | #endif | ||
| 550 | } | ||
| 551 | return false; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* Insert a socket into ehash, and eventually remove another one | ||
| 555 | * (The another one can be a SYN_RECV or TIMEWAIT) | ||
| 556 | * If an existing socket already exists, socket sk is not inserted, | ||
| 557 | * and sets found_dup_sk parameter to true. | ||
| 558 | */ | ||
| 559 | bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) | ||
| 515 | { | 560 | { |
| 516 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; | 561 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; |
| 517 | struct hlist_nulls_head *list; | 562 | struct hlist_nulls_head *list; |
| @@ -530,16 +575,23 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk) · 12 unmodified lines | |||
| 530 | if (osk) { | 575 | if (osk) { |
| 531 | WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); | 576 | WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); |
| 532 | ret = sk_nulls_del_node_init_rcu(osk); | 577 | ret = sk_nulls_del_node_init_rcu(osk); |
| 578 | } else if (found_dup_sk) { | ||
| 579 | *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); | ||
| 580 | if (*found_dup_sk) | ||
| 581 | ret = false; | ||
| 533 | } | 582 | } |
| 583 | |||
| 534 | if (ret) | 584 | if (ret) |
| 535 | __sk_nulls_add_node_rcu(sk, list); | 585 | __sk_nulls_add_node_rcu(sk, list); |
| 586 | |||
| 536 | spin_unlock(lock); | 587 | spin_unlock(lock); |
| 588 | |||
| 537 | return ret; | 589 | return ret; |
| 538 | } | 590 | } |
| 539 | 591 | ||
| 540 | bool inet_ehash_nolisten(struct sock *sk, struct sock *osk) | 592 | bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, bool *found_dup_sk) |
| 541 | { | 593 | { |
| 542 | bool ok = inet_ehash_insert(sk, osk); | 594 | bool ok = inet_ehash_insert(sk, osk, found_dup_sk); |
| 543 | 595 | ||
| 544 | if (ok) { | 596 | if (ok) { |
| 545 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 597 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
| @@ -583,7 +635,7 @@ int __inet_hash(struct sock *sk, struct sock *osk) · 37 unmodified lines | |||
| 583 | int err = 0; | 635 | int err = 0; |
| 584 | 636 | ||
| 585 | if (sk->sk_state != TCP_LISTEN) { | 637 | if (sk->sk_state != TCP_LISTEN) { |
| 586 | inet_ehash_nolisten(sk, osk); | 638 | inet_ehash_nolisten(sk, osk, NULL); |
| 587 | return 0; | 639 | return 0; |
| 588 | } | 640 | } |
| 589 | WARN_ON(!sk_unhashed(sk)); | 641 | WARN_ON(!sk_unhashed(sk)); |
| @@ -679,7 +731,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, · 89 unmodified lines | |||
| 679 | tb = inet_csk(sk)->icsk_bind_hash; | 731 | tb = inet_csk(sk)->icsk_bind_hash; |
| 680 | spin_lock_bh(&head->lock); | 732 | spin_lock_bh(&head->lock); |
| 681 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | 733 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
| 682 | inet_ehash_nolisten(sk, NULL); | 734 | inet_ehash_nolisten(sk, NULL, NULL); |
| 683 | spin_unlock_bh(&head->lock); | 735 | spin_unlock_bh(&head->lock); |
| 684 | return 0; | 736 | return 0; |
| 685 | } | 737 | } |
| @@ -758,7 +810,7 @@ ok: · 72 unmodified lines | |||
| 758 | inet_bind_hash(sk, tb, port); | 810 | inet_bind_hash(sk, tb, port); |
| 759 | if (sk_unhashed(sk)) { | 811 | if (sk_unhashed(sk)) { |
| 760 | inet_sk(sk)->inet_sport = htons(port); | 812 | inet_sk(sk)->inet_sport = htons(port); |
| 761 | inet_ehash_nolisten(sk, (struct sock *)tw); | 813 | inet_ehash_nolisten(sk, (struct sock *)tw, NULL); |
| 762 | } | 814 | } |
| 763 | if (tw) | 815 | if (tw) |
| 764 | inet_twsk_bind_unhash(tw, hinfo); | 816 | inet_twsk_bind_unhash(tw, hinfo); |
| @@ -198,6 +198,11 @@ static void tcp_reinit_congestion_control(struct sock *sk, · 197 unmodified lines | |||
| 198 | icsk->icsk_ca_setsockopt = 1; | 198 | icsk->icsk_ca_setsockopt = 1; |
| 199 | memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); | 199 | memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); |
| 200 | 200 | ||
| 201 | if (ca->flags & TCP_CONG_NEEDS_ECN) | ||
| 202 | INET_ECN_xmit(sk); | ||
| 203 | else | ||
| 204 | INET_ECN_dontxmit(sk); | ||
| 205 | |||
| 201 | if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) | 206 | if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) |
| 202 | tcp_init_congestion_control(sk); | 207 | tcp_init_congestion_control(sk); |
| 203 | } | 208 | } |
| @@ -980,17 +980,22 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, · 979 unmodified lines | |||
| 980 | 980 | ||
| 981 | skb = tcp_make_synack(sk, dst, req, foc, synack_type, syn_skb); | 981 | skb = tcp_make_synack(sk, dst, req, foc, synack_type, syn_skb); |
| 982 | 982 | ||
| 983 | tos = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? | ||
| 984 | tcp_rsk(req)->syn_tos : inet_sk(sk)->tos; | ||
| 985 | |||
| 986 | if (skb) { | 983 | if (skb) { |
| 987 | __tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr); | 984 | __tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr); |
| 988 | 985 | ||
| 986 | tos = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? | ||
| 987 | tcp_rsk(req)->syn_tos & ~INET_ECN_MASK : | ||
| 988 | inet_sk(sk)->tos; | ||
| 989 | |||
| 990 | if (!INET_ECN_is_capable(tos) && | ||
| 991 | tcp_bpf_ca_needs_ecn((struct sock *)req)) | ||
| 992 | tos |= INET_ECN_ECT_0; | ||
| 993 | |||
| 989 | rcu_read_lock(); | 994 | rcu_read_lock(); |
| 990 | err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, | 995 | err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, |
| 991 | ireq->ir_rmt_addr, | 996 | ireq->ir_rmt_addr, |
| 992 | rcu_dereference(ireq->ireq_opt), | 997 | rcu_dereference(ireq->ireq_opt), |
| 993 | tos & ~INET_ECN_MASK); | 998 | tos); |
| 994 | rcu_read_unlock(); | 999 | rcu_read_unlock(); |
| 995 | err = net_xmit_eval(err); | 1000 | err = net_xmit_eval(err); |
| 996 | } | 1001 | } |
| @@ -1498,6 +1503,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, · 501 unmodified lines | |||
| 1498 | bool *own_req) | 1503 | bool *own_req) |
| 1499 | { | 1504 | { |
| 1500 | struct inet_request_sock *ireq; | 1505 | struct inet_request_sock *ireq; |
| 1506 | bool found_dup_sk = false; | ||
| 1501 | struct inet_sock *newinet; | 1507 | struct inet_sock *newinet; |
| 1502 | struct tcp_sock *newtp; | 1508 | struct tcp_sock *newtp; |
| 1503 | struct sock *newsk; | 1509 | struct sock *newsk; |
| @@ -1575,12 +1581,22 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, · 71 unmodified lines | |||
| 1575 | 1581 | ||
| 1576 | if (__inet_inherit_port(sk, newsk) < 0) | 1582 | if (__inet_inherit_port(sk, newsk) < 0) |
| 1577 | goto put_and_exit; | 1583 | goto put_and_exit; |
| 1578 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); | 1584 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), |
| 1585 | &found_dup_sk); | ||
| 1579 | if (likely(*own_req)) { | 1586 | if (likely(*own_req)) { |
| 1580 | tcp_move_syn(newtp, req); | 1587 | tcp_move_syn(newtp, req); |
| 1581 | ireq->ireq_opt = NULL; | 1588 | ireq->ireq_opt = NULL; |
| 1582 | } else { | 1589 | } else { |
| 1583 | newinet->inet_opt = NULL; | 1590 | if (!req_unhash && found_dup_sk) { |
| 1591 | /* This code path should only be executed in the | ||
| 1592 | * syncookie case only | ||
| 1593 | */ | ||
| 1594 | bh_unlock_sock(newsk); | ||
| 1595 | sock_put(newsk); | ||
| 1596 | newsk = NULL; | ||
| 1597 | } else { | ||
| 1598 | newinet->inet_opt = NULL; | ||
| 1599 | } | ||
| 1584 | } | 1600 | } |
| 1585 | return newsk; | 1601 | return newsk; |
| 1586 | 1602 | ||
| @@ -306,7 +306,9 @@ static int ip6addrlbl_del(struct net *net, · 305 unmodified lines | |||
| 306 | /* add default label */ | 306 | /* add default label */ |
| 307 | static int __net_init ip6addrlbl_net_init(struct net *net) | 307 | static int __net_init ip6addrlbl_net_init(struct net *net) |
| 308 | { | 308 | { |
| 309 | int err = 0; | 309 | struct ip6addrlbl_entry *p = NULL; |
| 310 | struct hlist_node *n; | ||
| 311 | int err; | ||
| 310 | int i; | 312 | int i; |
| 311 | 313 | ||
| 312 | ADDRLABEL(KERN_DEBUG "%s\n", __func__); | 314 | ADDRLABEL(KERN_DEBUG "%s\n", __func__); |
| @@ -315,14 +317,20 @@ static int __net_init ip6addrlbl_net_init(struct net *net) · 2 unmodified lines | |||
| 315 | INIT_HLIST_HEAD(&net->ipv6.ip6addrlbl_table.head); | 317 | INIT_HLIST_HEAD(&net->ipv6.ip6addrlbl_table.head); |
| 316 | 318 | ||
| 317 | for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { | 319 | for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { |
| 318 | int ret = ip6addrlbl_add(net, | 320 | err = ip6addrlbl_add(net, |
| 319 | ip6addrlbl_init_table[i].prefix, | 321 | ip6addrlbl_init_table[i].prefix, |
| 320 | ip6addrlbl_init_table[i].prefixlen, | 322 | ip6addrlbl_init_table[i].prefixlen, |
| 321 | 0, | 323 | 0, |
| 322 | ip6addrlbl_init_table[i].label, 0); | 324 | ip6addrlbl_init_table[i].label, 0); |
| 323 | /* XXX: should we free all rules when we catch an error? */ | 325 | if (err) |
| 324 | if (ret && (!err || err != -ENOMEM)) | 326 | goto err_ip6addrlbl_add; |
| 325 | err = ret; | 327 | } |
| 328 | return 0; | ||
| 329 | |||
| 330 | err_ip6addrlbl_add: | ||
| 331 | hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) { | ||
| 332 | hlist_del_rcu(&p->list); | ||
| 333 | kfree_rcu(p, rcu); | ||
| 326 | } | 334 | } |
| 327 | return err; | 335 | return err; |
| 328 | } | 336 | } |
| @@ -527,15 +527,20 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, · 526 unmodified lines | |||
| 527 | if (np->repflow && ireq->pktopts) | 527 | if (np->repflow && ireq->pktopts) |
| 528 | fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); | 528 | fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); |
| 529 | 529 | ||
| 530 | tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? | ||
| 531 | tcp_rsk(req)->syn_tos & ~INET_ECN_MASK : | ||
| 532 | np->tclass; | ||
| 533 | |||
| 534 | if (!INET_ECN_is_capable(tclass) && | ||
| 535 | tcp_bpf_ca_needs_ecn((struct sock *)req)) | ||
| 536 | tclass |= INET_ECN_ECT_0; | ||
| 537 | |||
| 530 | rcu_read_lock(); | 538 | rcu_read_lock(); |
| 531 | opt = ireq->ipv6_opt; | 539 | opt = ireq->ipv6_opt; |
| 532 | tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? | ||
| 533 | tcp_rsk(req)->syn_tos : np->tclass; | ||
| 534 | if (!opt) | 540 | if (!opt) |
| 535 | opt = rcu_dereference(np->opt); | 541 | opt = rcu_dereference(np->opt); |
| 536 | err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, | 542 | err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, |
| 537 | tclass & ~INET_ECN_MASK, | 543 | tclass, sk->sk_priority); |
| 538 | sk->sk_priority); | ||
| 539 | rcu_read_unlock(); | 544 | rcu_read_unlock(); |
| 540 | err = net_xmit_eval(err); | 545 | err = net_xmit_eval(err); |
| 541 | } | 546 | } |
| @@ -1193,6 +1198,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * · 651 unmodified lines | |||
| 1193 | const struct ipv6_pinfo *np = tcp_inet6_sk(sk); | 1198 | const struct ipv6_pinfo *np = tcp_inet6_sk(sk); |
| 1194 | struct ipv6_txoptions *opt; | 1199 | struct ipv6_txoptions *opt; |
| 1195 | struct inet_sock *newinet; | 1200 | struct inet_sock *newinet; |
| 1201 | bool found_dup_sk = false; | ||
| 1196 | struct tcp_sock *newtp; | 1202 | struct tcp_sock *newtp; |
| 1197 | struct sock *newsk; | 1203 | struct sock *newsk; |
| 1198 | #ifdef CONFIG_TCP_MD5SIG | 1204 | #ifdef CONFIG_TCP_MD5SIG |
| @@ -1368,7 +1374,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * · 169 unmodified lines | |||
| 1368 | tcp_done(newsk); | 1374 | tcp_done(newsk); |
| 1369 | goto out; | 1375 | goto out; |
| 1370 | } | 1376 | } |
| 1371 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); | 1377 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), |
| 1378 | &found_dup_sk); | ||
| 1372 | if (*own_req) { | 1379 | if (*own_req) { |
| 1373 | tcp_move_syn(newtp, req); | 1380 | tcp_move_syn(newtp, req); |
| 1374 | 1381 | ||
| @@ -1383,6 +1390,15 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * · 8 unmodified lines | |||
| 1383 | skb_set_owner_r(newnp->pktoptions, newsk); | 1390 | skb_set_owner_r(newnp->pktoptions, newsk); |
| 1384 | } | 1391 | } |
| 1385 | } | 1392 | } |
| 1393 | } else { | ||
| 1394 | if (!req_unhash && found_dup_sk) { | ||
| 1395 | /* This code path should only be executed in the | ||
| 1396 | * syncookie case only | ||
| 1397 | */ | ||
| 1398 | bh_unlock_sock(newsk); | ||
| 1399 | sock_put(newsk); | ||
| 1400 | newsk = NULL; | ||
| 1401 | } | ||
| 1386 | } | 1402 | } |
| 1387 | 1403 | ||
| 1388 | return newsk; | 1404 | return newsk; |
| @@ -1645,7 +1645,7 @@ static int iucv_callback_connreq(struct iucv_path *path, · 1644 unmodified lines | |||
| 1645 | } | 1645 | } |
| 1646 | 1646 | ||
| 1647 | /* Create the new socket */ | 1647 | /* Create the new socket */ |
| 1648 | nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0); | 1648 | nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0); |
| 1649 | if (!nsk) { | 1649 | if (!nsk) { |
| 1650 | err = pr_iucv->path_sever(path, user_data); | 1650 | err = pr_iucv->path_sever(path, user_data); |
| 1651 | iucv_path_free(path); | 1651 | iucv_path_free(path); |
| @@ -1851,7 +1851,7 @@ static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb) · 199 unmodified lines | |||
| 1851 | goto out; | 1851 | goto out; |
| 1852 | } | 1852 | } |
| 1853 | 1853 | ||
| 1854 | nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0); | 1854 | nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0); |
| 1855 | bh_lock_sock(sk); | 1855 | bh_lock_sock(sk); |
| 1856 | if ((sk->sk_state != IUCV_LISTEN) || | 1856 | if ((sk->sk_state != IUCV_LISTEN) || |
| 1857 | sk_acceptq_is_full(sk) || | 1857 | sk_acceptq_is_full(sk) || |
| @@ -543,9 +543,8 @@ create_msk: · 542 unmodified lines | |||
| 543 | fallback = true; | 543 | fallback = true; |
| 544 | } else if (subflow_req->mp_join) { | 544 | } else if (subflow_req->mp_join) { |
| 545 | mptcp_get_options(skb, &mp_opt); | 545 | mptcp_get_options(skb, &mp_opt); |
| 546 | if (!mp_opt.mp_join || | 546 | if (!mp_opt.mp_join || !subflow_hmac_valid(req, &mp_opt) || |
| 547 | !mptcp_can_accept_new_subflow(subflow_req->msk) || | 547 | !mptcp_can_accept_new_subflow(subflow_req->msk)) { |
| 548 | !subflow_hmac_valid(req, &mp_opt)) { | ||
| 549 | SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); | 548 | SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); |
| 550 | fallback = true; | 549 | fallback = true; |
| 551 | } | 550 | } |
| @@ -958,14 +958,13 @@ static int dec_ttl_exception_handler(struct datapath *dp, struct sk_buff *skb, · 957 unmodified lines | |||
| 958 | { | 958 | { |
| 959 | /* The first action is always 'OVS_DEC_TTL_ATTR_ARG'. */ | 959 | /* The first action is always 'OVS_DEC_TTL_ATTR_ARG'. */ |
| 960 | struct nlattr *dec_ttl_arg = nla_data(attr); | 960 | struct nlattr *dec_ttl_arg = nla_data(attr); |
| 961 | int rem = nla_len(attr); | ||
| 962 | 961 | ||
| 963 | if (nla_len(dec_ttl_arg)) { | 962 | if (nla_len(dec_ttl_arg)) { |
| 964 | struct nlattr *actions = nla_next(dec_ttl_arg, &rem); | 963 | struct nlattr *actions = nla_data(dec_ttl_arg); |
| 965 | 964 | ||
| 966 | if (actions) | 965 | if (actions) |
| 967 | return clone_execute(dp, skb, key, 0, actions, rem, | 966 | return clone_execute(dp, skb, key, 0, nla_data(actions), |
| 968 | last, false); | 967 | nla_len(actions), last, false); |
| 969 | } | 968 | } |
| 970 | consume_skb(skb); | 969 | consume_skb(skb); |
| 971 | return 0; | 970 | return 0; |
| @@ -2503,28 +2503,42 @@ static int validate_and_copy_dec_ttl(struct net *net, · 2502 unmodified lines | |||
| 2503 | __be16 eth_type, __be16 vlan_tci, | 2503 | __be16 eth_type, __be16 vlan_tci, |
| 2504 | u32 mpls_label_count, bool log) | 2504 | u32 mpls_label_count, bool log) |
| 2505 | { | 2505 | { |
| 2506 | int start, err; | 2506 | const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1]; |
| 2507 | u32 nested = true; | 2507 | int start, action_start, err, rem; |
| 2508 | const struct nlattr *a, *actions; | ||
| 2509 | |||
| 2510 | memset(attrs, 0, sizeof(attrs)); | ||
| 2511 | nla_for_each_nested(a, attr, rem) { | ||
| 2512 | int type = nla_type(a); | ||
| 2508 | 2513 | ||
| 2509 | if (!nla_len(attr)) | 2514 | /* Ignore unknown attributes to be future proof. */ |
| 2510 | return ovs_nla_add_action(sfa, OVS_ACTION_ATTR_DEC_TTL, | 2515 | if (type > OVS_DEC_TTL_ATTR_MAX) |
| 2511 | NULL, 0, log); | 2516 | continue; |
| 2517 | |||
| 2518 | if (!type || attrs[type]) | ||
| 2519 | return -EINVAL; | ||
| 2520 | |||
| 2521 | attrs[type] = a; | ||
| 2522 | } | ||
| 2523 | |||
| 2524 | actions = attrs[OVS_DEC_TTL_ATTR_ACTION]; | ||
| 2525 | if (rem || !actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN)) | ||
| 2526 | return -EINVAL; | ||
| 2512 | 2527 | ||
| 2513 | start = add_nested_action_start(sfa, OVS_ACTION_ATTR_DEC_TTL, log); | 2528 | start = add_nested_action_start(sfa, OVS_ACTION_ATTR_DEC_TTL, log); |
| 2514 | if (start < 0) | 2529 | if (start < 0) |
| 2515 | return start; | 2530 | return start; |
| 2516 | 2531 | ||
| 2517 | err = ovs_nla_add_action(sfa, OVS_DEC_TTL_ATTR_ACTION, &nested, | 2532 | action_start = add_nested_action_start(sfa, OVS_DEC_TTL_ATTR_ACTION, log); |
| 2518 | sizeof(nested), log); | 2533 | if (action_start < 0) |
| 2519 | 2534 | return start; | |
| 2520 | if (err) | ||
| 2521 | return err; | ||
| 2522 | 2535 | ||
| 2523 | err = __ovs_nla_copy_actions(net, attr, key, sfa, eth_type, | 2536 | err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type, |
| 2524 | vlan_tci, mpls_label_count, log); | 2537 | vlan_tci, mpls_label_count, log); |
| 2525 | if (err) | 2538 | if (err) |
| 2526 | return err; | 2539 | return err; |
| 2527 | 2540 | ||
| 2541 | add_nested_action_end(*sfa, action_start); | ||
| 2528 | add_nested_action_end(*sfa, start); | 2542 | add_nested_action_end(*sfa, start); |
| 2529 | return 0; | 2543 | return 0; |
| 2530 | } | 2544 | } |
| @@ -3487,20 +3501,42 @@ out: · 956 unmodified lines | |||
| 3487 | static int dec_ttl_action_to_attr(const struct nlattr *attr, | 3501 | static int dec_ttl_action_to_attr(const struct nlattr *attr, |
| 3488 | struct sk_buff *skb) | 3502 | struct sk_buff *skb) |
| 3489 | { | 3503 | { |
| 3490 | int err = 0, rem = nla_len(attr); | 3504 | struct nlattr *start, *action_start; |
| 3491 | struct nlattr *start; | 3505 | const struct nlattr *a; |
| 3506 | int err = 0, rem; | ||
| 3492 | 3507 | ||
| 3493 | start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_DEC_TTL); | 3508 | start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_DEC_TTL); |
| 3494 | |||
| 3495 | if (!start) | 3509 | if (!start) |
| 3496 | return -EMSGSIZE; | 3510 | return -EMSGSIZE; |
| 3497 | 3511 | ||
| 3498 | err = ovs_nla_put_actions(nla_data(attr), rem, skb); | 3512 | nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) { |
| 3499 | if (err) | 3513 | switch (nla_type(a)) { |
| 3500 | nla_nest_cancel(skb, start); | 3514 | case OVS_DEC_TTL_ATTR_ACTION: |
| 3501 | else | 3515 | |
| 3502 | nla_nest_end(skb, start); | 3516 | action_start = nla_nest_start_noflag(skb, OVS_DEC_TTL_ATTR_ACTION); |
| 3517 | if (!action_start) { | ||
| 3518 | err = -EMSGSIZE; | ||
| 3519 | goto out; | ||
| 3520 | } | ||
| 3521 | |||
| 3522 | err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb); | ||
| 3523 | if (err) | ||
| 3524 | goto out; | ||
| 3525 | |||
| 3526 | nla_nest_end(skb, action_start); | ||
| 3527 | break; | ||
| 3503 | 3528 | ||
| 3529 | default: | ||
| 3530 | /* Ignore all other option to be future compatible */ | ||
| 3531 | break; | ||
| 3532 | } | ||
| 3533 | } | ||
| 3534 | |||
| 3535 | nla_nest_end(skb, start); | ||
| 3536 | return 0; | ||
| 3537 | |||
| 3538 | out: | ||
| 3539 | nla_nest_cancel(skb, start); | ||
| 3504 | return err; | 3540 | return err; |
| 3505 | } | 3541 | } |
| 3506 | 3542 | ||
| @@ -94,8 +94,8 @@ · 93 unmodified lines | |||
| 94 | 94 | ||
| 95 | /* | 95 | /* |
| 96 | Assumptions: | 96 | Assumptions: |
| 97 | - If the device has no dev->header_ops, there is no LL header visible | 97 | - If the device has no dev->header_ops->create, there is no LL header |
| 98 | above the device. In this case, its hard_header_len should be 0. | 98 | visible above the device. In this case, its hard_header_len should be 0. |
| 99 | The device may prepend its own header internally. In this case, its | 99 | The device may prepend its own header internally. In this case, its |
| 100 | needed_headroom should be set to the space needed for it to add its | 100 | needed_headroom should be set to the space needed for it to add its |
| 101 | internal header. | 101 | internal header. |
| @@ -109,26 +109,26 @@ · 7 unmodified lines | |||
| 109 | On receive: | 109 | On receive: |
| 110 | ----------- | 110 | ----------- |
| 111 | 111 | ||
| 112 | Incoming, dev->header_ops != NULL | 112 | Incoming, dev_has_header(dev) == true |
| 113 | mac_header -> ll header | 113 | mac_header -> ll header |
| 114 | data -> data | 114 | data -> data |
| 115 | 115 | ||
| 116 | Outgoing, dev->header_ops != NULL | 116 | Outgoing, dev_has_header(dev) == true |
| 117 | mac_header -> ll header | 117 | mac_header -> ll header |
| 118 | data -> ll header | 118 | data -> ll header |
| 119 | 119 | ||
| 120 | Incoming, dev->header_ops == NULL | 120 | Incoming, dev_has_header(dev) == false |
| 121 | mac_header -> data | 121 | mac_header -> data |
| 122 | However drivers often make it point to the ll header. | 122 | However drivers often make it point to the ll header. |
| 123 | This is incorrect because the ll header should be invisible to us. | 123 | This is incorrect because the ll header should be invisible to us. |
| 124 | data -> data | 124 | data -> data |
| 125 | 125 | ||
| 126 | Outgoing, dev->header_ops == NULL | 126 | Outgoing, dev_has_header(dev) == false |
| 127 | mac_header -> data. ll header is invisible to us. | 127 | mac_header -> data. ll header is invisible to us. |
| 128 | data -> data | 128 | data -> data |
| 129 | 129 | ||
| 130 | Resume | 130 | Resume |
| 131 | If dev->header_ops == NULL we are unable to restore the ll header, | 131 | If dev_has_header(dev) == false we are unable to restore the ll header, |
| 132 | because it is invisible to us. | 132 | because it is invisible to us. |
| 133 | 133 | ||
| 134 | 134 | ||
| @@ -2083,7 +2083,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, · 1948 unmodified lines | |||
| 2083 | 2083 | ||
| 2084 | skb->dev = dev; | 2084 | skb->dev = dev; |
| 2085 | 2085 | ||
| 2086 | if (dev->header_ops) { | 2086 | if (dev_has_header(dev)) { |
| 2087 | /* The device has an explicit notion of ll header, | 2087 | /* The device has an explicit notion of ll header, |
| 2088 | * exported to higher levels. | 2088 | * exported to higher levels. |
| 2089 | * | 2089 | * |
| @@ -2212,7 +2212,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, · 122 unmodified lines | |||
| 2212 | if (!net_eq(dev_net(dev), sock_net(sk))) | 2212 | if (!net_eq(dev_net(dev), sock_net(sk))) |
| 2213 | goto drop; | 2213 | goto drop; |
| 2214 | 2214 | ||
| 2215 | if (dev->header_ops) { | 2215 | if (dev_has_header(dev)) { |
| 2216 | if (sk->sk_type != SOCK_DGRAM) | 2216 | if (sk->sk_type != SOCK_DGRAM) |
| 2217 | skb_push(skb, skb->data - skb_mac_header(skb)); | 2217 | skb_push(skb, skb->data - skb_mac_header(skb)); |
| 2218 | else if (skb->pkt_type == PACKET_OUTGOING) { | 2218 | else if (skb->pkt_type == PACKET_OUTGOING) { |
| @@ -96,10 +96,19 @@ static void rose_loopback_timer(struct timer_list *unused) · 95 unmodified lines | |||
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | if (frametype == ROSE_CALL_REQUEST) { | 98 | if (frametype == ROSE_CALL_REQUEST) { |
| 99 | if ((dev = rose_dev_get(dest)) != NULL) { | 99 | if (!rose_loopback_neigh->dev) { |
| 100 | if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) | 100 | kfree_skb(skb); |
| 101 | kfree_skb(skb); | 101 | continue; |
| 102 | } else { | 102 | } |
| 103 | |||
| 104 | dev = rose_dev_get(dest); | ||
| 105 | if (!dev) { | ||
| 106 | kfree_skb(skb); | ||
| 107 | continue; | ||
| 108 | } | ||
| 109 | |||
| 110 | if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) { | ||
| 111 | dev_put(dev); | ||
| 103 | kfree_skb(skb); | 112 | kfree_skb(skb); |
| 104 | } | 113 | } |
| 105 | } else { | 114 | } else { |
| @@ -1262,6 +1262,8 @@ void tls_device_offload_cleanup_rx(struct sock *sk) · 1261 unmodified lines | |||
| 1262 | if (tls_ctx->tx_conf != TLS_HW) { | 1262 | if (tls_ctx->tx_conf != TLS_HW) { |
| 1263 | dev_put(netdev); | 1263 | dev_put(netdev); |
| 1264 | tls_ctx->netdev = NULL; | 1264 | tls_ctx->netdev = NULL; |
| 1265 | } else { | ||
| 1266 | set_bit(TLS_RX_DEV_CLOSED, &tls_ctx->flags); | ||
| 1265 | } | 1267 | } |
| 1266 | out: | 1268 | out: |
| 1267 | up_read(&device_offload_lock); | 1269 | up_read(&device_offload_lock); |
| @@ -1291,7 +1293,8 @@ static int tls_device_down(struct net_device *netdev) · 23 unmodified lines | |||
| 1291 | if (ctx->tx_conf == TLS_HW) | 1293 | if (ctx->tx_conf == TLS_HW) |
| 1292 | netdev->tlsdev_ops->tls_dev_del(netdev, ctx, | 1294 | netdev->tlsdev_ops->tls_dev_del(netdev, ctx, |
| 1293 | TLS_OFFLOAD_CTX_DIR_TX); | 1295 | TLS_OFFLOAD_CTX_DIR_TX); |
| 1294 | if (ctx->rx_conf == TLS_HW) | 1296 | if (ctx->rx_conf == TLS_HW && |
| 1297 | !test_bit(TLS_RX_DEV_CLOSED, &ctx->flags)) | ||
| 1295 | netdev->tlsdev_ops->tls_dev_del(netdev, ctx, | 1298 | netdev->tlsdev_ops->tls_dev_del(netdev, ctx, |
| 1296 | TLS_OFFLOAD_CTX_DIR_RX); | 1299 | TLS_OFFLOAD_CTX_DIR_RX); |
| 1297 | WRITE_ONCE(ctx->netdev, NULL); | 1300 | WRITE_ONCE(ctx->netdev, NULL); |
| @@ -1294,6 +1294,12 @@ static struct sk_buff *tls_wait_data(struct sock *sk, struct sk_psock *psock, · 1293 unmodified lines | |||
| 1294 | return NULL; | 1294 | return NULL; |
| 1295 | } | 1295 | } |
| 1296 | 1296 | ||
| 1297 | if (!skb_queue_empty(&sk->sk_receive_queue)) { | ||
| 1298 | __strp_unpause(&ctx->strp); | ||
| 1299 | if (ctx->recv_pkt) | ||
| 1300 | return ctx->recv_pkt; | ||
| 1301 | } | ||
| 1302 | |||
| 1297 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1303 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 1298 | return NULL; | 1304 | return NULL; |
| 1299 | 1305 | ||
| @@ -841,8 +841,10 @@ void virtio_transport_release(struct vsock_sock *vsk) · 840 unmodified lines | |||
| 841 | virtio_transport_free_pkt(pkt); | 841 | virtio_transport_free_pkt(pkt); |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | if (remove_sock) | 844 | if (remove_sock) { |
| 845 | sock_set_flag(sk, SOCK_DONE); | ||
| 845 | vsock_remove_sock(vsk); | 846 | vsock_remove_sock(vsk); |
| 847 | } | ||
| 846 | } | 848 | } |
| 847 | EXPORT_SYMBOL_GPL(virtio_transport_release); | 849 | EXPORT_SYMBOL_GPL(virtio_transport_release); |
| 848 | 850 | ||
| @@ -1132,8 +1134,8 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, · 283 unmodified lines | |||
| 1132 | 1134 | ||
| 1133 | lock_sock(sk); | 1135 | lock_sock(sk); |
| 1134 | 1136 | ||
| 1135 | /* Check if sk has been released before lock_sock */ | 1137 | /* Check if sk has been closed before lock_sock */ |
| 1136 | if (sk->sk_shutdown == SHUTDOWN_MASK) { | 1138 | if (sock_flag(sk, SOCK_DONE)) { |
| 1137 | (void)virtio_transport_reset_no_sock(t, pkt); | 1139 | (void)virtio_transport_reset_no_sock(t, pkt); |
| 1138 | release_sock(sk); | 1140 | release_sock(sk); |
| 1139 | sock_put(sk); | 1141 | sock_put(sk); |
| @@ -1539,7 +1539,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, · 1538 unmodified lines | |||
| 1539 | 1539 | ||
| 1540 | unlock: | 1540 | unlock: |
| 1541 | up_write(&card->controls_rwsem); | 1541 | up_write(&card->controls_rwsem); |
| 1542 | return 0; | 1542 | return err; |
| 1543 | } | 1543 | } |
| 1544 | 1544 | ||
| 1545 | static int snd_ctl_elem_add_user(struct snd_ctl_file *file, | 1545 | static int snd_ctl_elem_add_user(struct snd_ctl_file *file, |
| @@ -123,7 +123,7 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode) · 122 unmodified lines | |||
| 123 | t = (struct snd_efw_transaction *)data; | 123 | t = (struct snd_efw_transaction *)data; |
| 124 | length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length); | 124 | length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length); |
| 125 | 125 | ||
| 126 | spin_lock_irq(&efw->lock); | 126 | spin_lock(&efw->lock); |
| 127 | 127 | ||
| 128 | if (efw->push_ptr < efw->pull_ptr) | 128 | if (efw->push_ptr < efw->pull_ptr) |
| 129 | capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr); | 129 | capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr); |
| @@ -190,7 +190,7 @@ handle_resp_for_user(struct fw_card *card, int generation, int source, · 60 unmodified lines | |||
| 190 | 190 | ||
| 191 | copy_resp_to_buf(efw, data, length, rcode); | 191 | copy_resp_to_buf(efw, data, length, rcode); |
| 192 | end: | 192 | end: |
| 193 | spin_unlock_irq(&instances_lock); | 193 | spin_unlock(&instances_lock); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static void | 196 | static void |
| @@ -2506,6 +2506,9 @@ static const struct pci_device_id azx_ids[] = { · 2505 unmodified lines | |||
| 2506 | /* DG1 */ | 2506 | /* DG1 */ |
| 2507 | { PCI_DEVICE(0x8086, 0x490d), | 2507 | { PCI_DEVICE(0x8086, 0x490d), |
| 2508 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2508 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
| 2509 | /* Alderlake-S */ | ||
| 2510 | { PCI_DEVICE(0x8086, 0x7ad0), | ||
| 2511 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | ||
| 2509 | /* Elkhart Lake */ | 2512 | /* Elkhart Lake */ |
| 2510 | { PCI_DEVICE(0x8086, 0x4b55), | 2513 | { PCI_DEVICE(0x8086, 0x4b55), |
| 2511 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2514 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
| @@ -9183,6 +9183,8 @@ static void ca0132_mmio_init(struct hda_codec *codec) · 9182 unmodified lines | |||
| 9183 | case QUIRK_AE5: | 9183 | case QUIRK_AE5: |
| 9184 | ca0132_mmio_init_ae5(codec); | 9184 | ca0132_mmio_init_ae5(codec); |
| 9185 | break; | 9185 | break; |
| 9186 | default: | ||
| 9187 | break; | ||
| 9186 | } | 9188 | } |
| 9187 | } | 9189 | } |
| 9188 | 9190 | ||
| @@ -4274,6 +4274,7 @@ HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi), · 4273 unmodified lines | |||
| 4274 | HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi), | 4274 | HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi), |
| 4275 | HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi), | 4275 | HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi), |
| 4276 | HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi), | 4276 | HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi), |
| 4277 | HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi), | ||
| 4277 | HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi), | 4278 | HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi), |
| 4278 | HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi), | 4279 | HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi), |
| 4279 | HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi), | 4280 | HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi), |
| @@ -2522,13 +2522,23 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { · 2521 unmodified lines | |||
| 2522 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 2522 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
| 2523 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 2523 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
| 2524 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), | 2524 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), |
| 2525 | SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950), | ||
| 2526 | SND_PCI_QUIRK(0x1558, 0x950A, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950), | ||
| 2525 | SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), | 2527 | SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), |
| 2526 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), | 2528 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), |
| 2529 | SND_PCI_QUIRK(0x1558, 0x95e3, "Clevo P955[ER]T", ALC1220_FIXUP_CLEVO_P950), | ||
| 2530 | SND_PCI_QUIRK(0x1558, 0x95e4, "Clevo P955ER", ALC1220_FIXUP_CLEVO_P950), | ||
| 2531 | SND_PCI_QUIRK(0x1558, 0x95e5, "Clevo P955EE6", ALC1220_FIXUP_CLEVO_P950), | ||
| 2532 | SND_PCI_QUIRK(0x1558, 0x95e6, "Clevo P950R[CDF]", ALC1220_FIXUP_CLEVO_P950), | ||
| 2527 | SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950), | 2533 | SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950), |
| 2528 | SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950), | 2534 | SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950), |
| 2535 | SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950), | ||
| 2536 | SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | ||
| 2529 | SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | 2537 | SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2538 | SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | ||
| 2539 | SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | ||
| 2530 | SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | 2540 | SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2531 | SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | 2541 | SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2532 | SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | 2542 | SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2533 | SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | 2543 | SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2534 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2544 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
| @@ -4216,6 +4226,12 @@ static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, · 1681 unmodified lines | |||
| 4216 | alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20); | 4226 | alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20); |
| 4217 | } | 4227 | } |
| 4218 | 4228 | ||
| 4229 | static void alc287_fixup_hp_gpio_led(struct hda_codec *codec, | ||
| 4230 | const struct hda_fixup *fix, int action) | ||
| 4231 | { | ||
| 4232 | alc_fixup_hp_gpio_led(codec, action, 0x10, 0); | ||
| 4233 | } | ||
| 4234 | |||
| 4219 | /* turn on/off mic-mute LED per capture hook via VREF change */ | 4235 | /* turn on/off mic-mute LED per capture hook via VREF change */ |
| 4220 | static int vref_micmute_led_set(struct led_classdev *led_cdev, | 4236 | static int vref_micmute_led_set(struct led_classdev *led_cdev, |
| 4221 | enum led_brightness brightness) | 4237 | enum led_brightness brightness) |
| @@ -6301,6 +6317,9 @@ enum { · 2079 unmodified lines | |||
| 6301 | ALC274_FIXUP_HP_MIC, | 6317 | ALC274_FIXUP_HP_MIC, |
| 6302 | ALC274_FIXUP_HP_HEADSET_MIC, | 6318 | ALC274_FIXUP_HP_HEADSET_MIC, |
| 6303 | ALC256_FIXUP_ASUS_HPE, | 6319 | ALC256_FIXUP_ASUS_HPE, |
| 6320 | ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, | ||
| 6321 | ALC287_FIXUP_HP_GPIO_LED, | ||
| 6322 | ALC256_FIXUP_HP_HEADSET_MIC, | ||
| 6304 | }; | 6323 | }; |
| 6305 | 6324 | ||
| 6306 | static const struct hda_fixup alc269_fixups[] = { | 6325 | static const struct hda_fixup alc269_fixups[] = { |
| @@ -7705,6 +7724,20 @@ static const struct hda_fixup alc269_fixups[] = { · 1398 unmodified lines | |||
| 7705 | .chained = true, | 7724 | .chained = true, |
| 7706 | .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC | 7725 | .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC |
| 7707 | }, | 7726 | }, |
| 7727 | [ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK] = { | ||
| 7728 | .type = HDA_FIXUP_FUNC, | ||
| 7729 | .v.func = alc_fixup_headset_jack, | ||
| 7730 | .chained = true, | ||
| 7731 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI | ||
| 7732 | }, | ||
| 7733 | [ALC287_FIXUP_HP_GPIO_LED] = { | ||
| 7734 | .type = HDA_FIXUP_FUNC, | ||
| 7735 | .v.func = alc287_fixup_hp_gpio_led, | ||
| 7736 | }, | ||
| 7737 | [ALC256_FIXUP_HP_HEADSET_MIC] = { | ||
| 7738 | .type = HDA_FIXUP_FUNC, | ||
| 7739 | .v.func = alc274_fixup_hp_headset_mic, | ||
| 7740 | }, | ||
| 7708 | }; | 7741 | }; |
| 7709 | 7742 | ||
| 7710 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 7743 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
| @@ -7859,6 +7892,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 148 unmodified lines | |||
| 7859 | SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), | 7892 | SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), |
| 7860 | SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), | 7893 | SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), |
| 7861 | SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), | 7894 | SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), |
| 7895 | SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), | ||
| 7896 | SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), | ||
| 7862 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), | 7897 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), |
| 7863 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 7898 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
| 7864 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 7899 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| @@ -7924,11 +7959,49 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 59 unmodified lines | |||
| 7924 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), | 7959 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), |
| 7925 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), | 7960 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), |
| 7926 | SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), | 7961 | SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), |
| 7962 | SND_PCI_QUIRK(0x1558, 0x1323, "Clevo N130ZU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7927 | SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | 7963 | SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
| 7964 | SND_PCI_QUIRK(0x1558, 0x1401, "Clevo L140[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7965 | SND_PCI_QUIRK(0x1558, 0x1403, "Clevo N140CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7966 | SND_PCI_QUIRK(0x1558, 0x1404, "Clevo N150CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7967 | SND_PCI_QUIRK(0x1558, 0x14a1, "Clevo L141MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7968 | SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7969 | SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7970 | SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7971 | SND_PCI_QUIRK(0x1558, 0x40a1, "Clevo NL40GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7972 | SND_PCI_QUIRK(0x1558, 0x40c1, "Clevo NL40[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7973 | SND_PCI_QUIRK(0x1558, 0x40d1, "Clevo NL41DU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7974 | SND_PCI_QUIRK(0x1558, 0x50a3, "Clevo NJ51GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7975 | SND_PCI_QUIRK(0x1558, 0x50b3, "Clevo NK50S[BEZ]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7976 | SND_PCI_QUIRK(0x1558, 0x50b6, "Clevo NK50S5", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7977 | SND_PCI_QUIRK(0x1558, 0x50b8, "Clevo NK50SZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7978 | SND_PCI_QUIRK(0x1558, 0x50d5, "Clevo NP50D5", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7979 | SND_PCI_QUIRK(0x1558, 0x50f0, "Clevo NH50A[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7980 | SND_PCI_QUIRK(0x1558, 0x50f3, "Clevo NH58DPQ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7981 | SND_PCI_QUIRK(0x1558, 0x5101, "Clevo S510WU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7982 | SND_PCI_QUIRK(0x1558, 0x5157, "Clevo W517GU1", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7983 | SND_PCI_QUIRK(0x1558, 0x51a1, "Clevo NS50MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7984 | SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7985 | SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7986 | SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7987 | SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7988 | SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7989 | SND_PCI_QUIRK(0x1558, 0x8535, "Clevo NH50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7990 | SND_PCI_QUIRK(0x1558, 0x8536, "Clevo NH79D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7928 | SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | 7991 | SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
| 7929 | SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | 7992 | SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), |
| 7930 | SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), | 7993 | SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7931 | SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), | 7994 | SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7995 | SND_PCI_QUIRK(0x1558, 0x8668, "Clevo NP50B[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7996 | SND_PCI_QUIRK(0x1558, 0x8680, "Clevo NJ50LU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7997 | SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7998 | SND_PCI_QUIRK(0x1558, 0x8a20, "Clevo NH55DCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7999 | SND_PCI_QUIRK(0x1558, 0x8a51, "Clevo NH70RCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 8000 | SND_PCI_QUIRK(0x1558, 0x8d50, "Clevo NH55RCQ-M", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 8001 | SND_PCI_QUIRK(0x1558, 0x951d, "Clevo N950T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 8002 | SND_PCI_QUIRK(0x1558, 0x961d, "Clevo N960S[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 8003 | SND_PCI_QUIRK(0x1558, 0x971d, "Clevo N970T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 8004 | SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL53RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), | ||
| 7932 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), | 8005 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), |
| 7933 | SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), | 8006 | SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), |
| 7934 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 8007 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
| @@ -7966,6 +8039,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 31 unmodified lines | |||
| 7966 | SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 8039 | SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 7967 | SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), | 8040 | SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), |
| 7968 | SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), | 8041 | SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), |
| 8042 | SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), | ||
| 8043 | SND_PCI_QUIRK(0x17aa, 0x22c2, "Thinkpad X1 Extreme Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), | ||
| 7969 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 8044 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
| 7970 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 8045 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
| 7971 | SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), | 8046 | SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), |
| @@ -8278,6 +8353,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { · 306 unmodified lines | |||
| 8278 | {0x19, 0x02a11020}, | 8353 | {0x19, 0x02a11020}, |
| 8279 | {0x1a, 0x02a11030}, | 8354 | {0x1a, 0x02a11030}, |
| 8280 | {0x21, 0x0221101f}), | 8355 | {0x21, 0x0221101f}), |
| 8356 | SND_HDA_PIN_QUIRK(0x10ec0236, 0x103c, "HP", ALC256_FIXUP_HP_HEADSET_MIC, | ||
| 8357 | {0x14, 0x90170110}, | ||
| 8358 | {0x19, 0x02a11020}, | ||
| 8359 | {0x21, 0x02211030}), | ||
| 8281 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, | 8360 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, |
| 8282 | {0x14, 0x90170110}, | 8361 | {0x14, 0x90170110}, |
| 8283 | {0x21, 0x02211020}), | 8362 | {0x21, 0x02211020}), |
| @@ -8380,6 +8459,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { · 96 unmodified lines | |||
| 8380 | {0x1a, 0x90a70130}, | 8459 | {0x1a, 0x90a70130}, |
| 8381 | {0x1b, 0x90170110}, | 8460 | {0x1b, 0x90170110}, |
| 8382 | {0x21, 0x03211020}), | 8461 | {0x21, 0x03211020}), |
| 8462 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x103c, "HP", ALC256_FIXUP_HP_HEADSET_MIC, | ||
| 8463 | {0x14, 0x90170110}, | ||
| 8464 | {0x19, 0x02a11020}, | ||
| 8465 | {0x21, 0x0221101f}), | ||
| 8383 | SND_HDA_PIN_QUIRK(0x10ec0274, 0x103c, "HP", ALC274_FIXUP_HP_HEADSET_MIC, | 8466 | SND_HDA_PIN_QUIRK(0x10ec0274, 0x103c, "HP", ALC274_FIXUP_HP_HEADSET_MIC, |
| 8384 | {0x17, 0x90170110}, | 8467 | {0x17, 0x90170110}, |
| 8385 | {0x19, 0x03a11030}, | 8468 | {0x19, 0x03a11030}, |
| @@ -70,7 +70,6 @@ static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp, · 69 unmodified lines | |||
| 70 | unsigned int i; | 70 | unsigned int i; |
| 71 | #endif | 71 | #endif |
| 72 | 72 | ||
| 73 | mutex_lock(&mgr->msg_lock); | ||
| 74 | err = 0; | 73 | err = 0; |
| 75 | 74 | ||
| 76 | /* copy message descriptor from miXart to driver */ | 75 | /* copy message descriptor from miXart to driver */ |
| @@ -119,8 +118,6 @@ static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp, · 42 unmodified lines | |||
| 119 | writel_be(headptr, MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD)); | 118 | writel_be(headptr, MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD)); |
| 120 | 119 | ||
| 121 | _clean_exit: | 120 | _clean_exit: |
| 122 | mutex_unlock(&mgr->msg_lock); | ||
| 123 | |||
| 124 | return err; | 121 | return err; |
| 125 | } | 122 | } |
| 126 | 123 | ||
| @@ -258,7 +255,9 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int · 131 unmodified lines | |||
| 258 | resp.data = resp_data; | 255 | resp.data = resp_data; |
| 259 | resp.size = max_resp_size; | 256 | resp.size = max_resp_size; |
| 260 | 257 | ||
| 258 | mutex_lock(&mgr->msg_lock); | ||
| 261 | err = get_msg(mgr, &resp, msg_frame); | 259 | err = get_msg(mgr, &resp, msg_frame); |
| 260 | mutex_unlock(&mgr->msg_lock); | ||
| 262 | 261 | ||
| 263 | if( request->message_id != resp.message_id ) | 262 | if( request->message_id != resp.message_id ) |
| 264 | dev_err(&mgr->pci->dev, "RESPONSE ERROR!\n"); | 263 | dev_err(&mgr->pci->dev, "RESPONSE ERROR!\n"); |
| @@ -27,10 +27,15 @@ · 26 unmodified lines | |||
| 27 | #include <sound/soc-dapm.h> | 27 | #include <sound/soc-dapm.h> |
| 28 | #include <sound/soc.h> | 28 | #include <sound/soc.h> |
| 29 | #include <sound/tlv.h> | 29 | #include <sound/tlv.h> |
| 30 | #include <sound/rt1015.h> | ||
| 30 | 31 | ||
| 31 | #include "rl6231.h" | 32 | #include "rl6231.h" |
| 32 | #include "rt1015.h" | 33 | #include "rt1015.h" |
| 33 | 34 | ||
| 35 | static const struct rt1015_platform_data i2s_default_platform_data = { | ||
| 36 | .power_up_delay_ms = 50, | ||
| 37 | }; | ||
| 38 | |||
| 34 | static const struct reg_default rt1015_reg[] = { | 39 | static const struct reg_default rt1015_reg[] = { |
| 35 | { 0x0000, 0x0000 }, | 40 | { 0x0000, 0x0000 }, |
| 36 | { 0x0004, 0xa000 }, | 41 | { 0x0004, 0xa000 }, |
| @@ -539,7 +544,7 @@ static void rt1015_flush_work(struct work_struct *work) · 502 unmodified lines | |||
| 539 | struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, | 544 | struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, |
| 540 | flush_work.work); | 545 | flush_work.work); |
| 541 | struct snd_soc_component *component = rt1015->component; | 546 | struct snd_soc_component *component = rt1015->component; |
| 542 | unsigned int val, i = 0, count = 20; | 547 | unsigned int val, i = 0, count = 200; |
| 543 | 548 | ||
| 544 | while (i < count) { | 549 | while (i < count) { |
| 545 | usleep_range(1000, 1500); | 550 | usleep_range(1000, 1500); |
| @@ -650,6 +655,7 @@ static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w, · 104 unmodified lines | |||
| 650 | case SND_SOC_DAPM_POST_PMU: | 655 | case SND_SOC_DAPM_POST_PMU: |
| 651 | if (rt1015->hw_config == RT1015_HW_28) | 656 | if (rt1015->hw_config == RT1015_HW_28) |
| 652 | schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10)); | 657 | schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10)); |
| 658 | msleep(rt1015->pdata.power_up_delay_ms); | ||
| 653 | break; | 659 | break; |
| 654 | default: | 660 | default: |
| 655 | break; | 661 | break; |
| @@ -1067,9 +1073,16 @@ static struct acpi_device_id rt1015_acpi_match[] = { · 411 unmodified lines | |||
| 1067 | MODULE_DEVICE_TABLE(acpi, rt1015_acpi_match); | 1073 | MODULE_DEVICE_TABLE(acpi, rt1015_acpi_match); |
| 1068 | #endif | 1074 | #endif |
| 1069 | 1075 | ||
| 1076 | static void rt1015_parse_dt(struct rt1015_priv *rt1015, struct device *dev) | ||
| 1077 | { | ||
| 1078 | device_property_read_u32(dev, "realtek,power-up-delay-ms", | ||
| 1079 | &rt1015->pdata.power_up_delay_ms); | ||
| 1080 | } | ||
| 1081 | |||
| 1070 | static int rt1015_i2c_probe(struct i2c_client *i2c, | 1082 | static int rt1015_i2c_probe(struct i2c_client *i2c, |
| 1071 | const struct i2c_device_id *id) | 1083 | const struct i2c_device_id *id) |
| 1072 | { | 1084 | { |
| 1085 | struct rt1015_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
| 1073 | struct rt1015_priv *rt1015; | 1086 | struct rt1015_priv *rt1015; |
| 1074 | int ret; | 1087 | int ret; |
| 1075 | unsigned int val; | 1088 | unsigned int val; |
| @@ -1081,6 +1094,13 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, · 5 unmodified lines | |||
| 1081 | 1094 | ||
| 1082 | i2c_set_clientdata(i2c, rt1015); | 1095 | i2c_set_clientdata(i2c, rt1015); |
| 1083 | 1096 | ||
| 1097 | rt1015->pdata = i2s_default_platform_data; | ||
| 1098 | |||
| 1099 | if (pdata) | ||
| 1100 | rt1015->pdata = *pdata; | ||
| 1101 | else | ||
| 1102 | rt1015_parse_dt(rt1015, &i2c->dev); | ||
| 1103 | |||
| 1084 | rt1015->regmap = devm_regmap_init_i2c(i2c, &rt1015_regmap); | 1104 | rt1015->regmap = devm_regmap_init_i2c(i2c, &rt1015_regmap); |
| 1085 | if (IS_ERR(rt1015->regmap)) { | 1105 | if (IS_ERR(rt1015->regmap)) { |
| 1086 | ret = PTR_ERR(rt1015->regmap); | 1106 | ret = PTR_ERR(rt1015->regmap); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #ifndef __RT1015_H__ | 13 | #ifndef __RT1015_H__ |
| 14 | #define __RT1015_H__ | 14 | #define __RT1015_H__ |
| 15 | #include <sound/rt1015.h> | ||
| 15 | 16 | ||
| 16 | #define RT1015_DEVICE_ID_VAL 0x1011 | 17 | #define RT1015_DEVICE_ID_VAL 0x1011 |
| 17 | #define RT1015_DEVICE_ID_VAL2 0x1015 | 18 | #define RT1015_DEVICE_ID_VAL2 0x1015 |
| @@ -380,6 +381,7 @@ enum { · 362 unmodified lines | |||
| 380 | 381 | ||
| 381 | struct rt1015_priv { | 382 | struct rt1015_priv { |
| 382 | struct snd_soc_component *component; | 383 | struct snd_soc_component *component; |
| 384 | struct rt1015_platform_data pdata; | ||
| 383 | struct regmap *regmap; | 385 | struct regmap *regmap; |
| 384 | int sysclk; | 386 | int sysclk; |
| 385 | int sysclk_src; | 387 | int sysclk_src; |
| @@ -700,6 +700,8 @@ static int kabylake_set_bias_level(struct snd_soc_card *card, · 699 unmodified lines | |||
| 700 | switch (level) { | 700 | switch (level) { |
| 701 | case SND_SOC_BIAS_PREPARE: | 701 | case SND_SOC_BIAS_PREPARE: |
| 702 | if (dapm->bias_level == SND_SOC_BIAS_ON) { | 702 | if (dapm->bias_level == SND_SOC_BIAS_ON) { |
| 703 | if (!__clk_is_enabled(priv->mclk)) | ||
| 704 | return 0; | ||
| 703 | dev_dbg(card->dev, "Disable mclk"); | 705 | dev_dbg(card->dev, "Disable mclk"); |
| 704 | clk_disable_unprepare(priv->mclk); | 706 | clk_disable_unprepare(priv->mclk); |
| 705 | } else { | 707 | } else { |
| @@ -458,10 +458,6 @@ static int catpt_dai_prepare(struct snd_pcm_substream *substream, · 457 unmodified lines | |||
| 458 | if (ret) | 458 | if (ret) |
| 459 | return CATPT_IPC_ERROR(ret); | 459 | return CATPT_IPC_ERROR(ret); |
| 460 | 460 | ||
| 461 | ret = catpt_dsp_update_lpclock(cdev); | ||
| 462 | if (ret) | ||
| 463 | return ret; | ||
| 464 | |||
| 465 | ret = catpt_dai_apply_usettings(dai, stream); | 461 | ret = catpt_dai_apply_usettings(dai, stream); |
| 466 | if (ret) | 462 | if (ret) |
| 467 | return ret; | 463 | return ret; |
| @@ -500,6 +496,7 @@ static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd, · 32 unmodified lines | |||
| 500 | case SNDRV_PCM_TRIGGER_RESUME: | 496 | case SNDRV_PCM_TRIGGER_RESUME: |
| 501 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 497 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 502 | resume_stream: | 498 | resume_stream: |
| 499 | catpt_dsp_update_lpclock(cdev); | ||
| 503 | ret = catpt_ipc_resume_stream(cdev, stream->info.stream_hw_id); | 500 | ret = catpt_ipc_resume_stream(cdev, stream->info.stream_hw_id); |
| 504 | if (ret) | 501 | if (ret) |
| 505 | return CATPT_IPC_ERROR(ret); | 502 | return CATPT_IPC_ERROR(ret); |
| @@ -507,11 +504,11 @@ static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd, · 1 unmodified line | |||
| 507 | 504 | ||
| 508 | case SNDRV_PCM_TRIGGER_STOP: | 505 | case SNDRV_PCM_TRIGGER_STOP: |
| 509 | stream->prepared = false; | 506 | stream->prepared = false; |
| 510 | catpt_dsp_update_lpclock(cdev); | ||
| 511 | fallthrough; | 507 | fallthrough; |
| 512 | case SNDRV_PCM_TRIGGER_SUSPEND: | 508 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 513 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 509 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 514 | ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id); | 510 | ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id); |
| 511 | catpt_dsp_update_lpclock(cdev); | ||
| 515 | if (ret) | 512 | if (ret) |
| 516 | return CATPT_IPC_ERROR(ret); | 513 | return CATPT_IPC_ERROR(ret); |
| 517 | break; | 514 | break; |
| @@ -534,6 +531,8 @@ void catpt_stream_update_position(struct catpt_dev *cdev, · 16 unmodified lines | |||
| 534 | 531 | ||
| 535 | dsppos = bytes_to_frames(r, pos->stream_position); | 532 | dsppos = bytes_to_frames(r, pos->stream_position); |
| 536 | 533 | ||
| 534 | if (!stream->prepared) | ||
| 535 | goto exit; | ||
| 537 | /* only offload is set_write_pos driven */ | 536 | /* only offload is set_write_pos driven */ |
| 538 | if (stream->template->type != CATPT_STRM_TYPE_RENDER) | 537 | if (stream->template->type != CATPT_STRM_TYPE_RENDER) |
| 539 | goto exit; | 538 | goto exit; |
| @@ -487,9 +487,9 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream, · 486 unmodified lines | |||
| 487 | kmb_i2s->xfer_resolution = 0x02; | 487 | kmb_i2s->xfer_resolution = 0x02; |
| 488 | break; | 488 | break; |
| 489 | case SNDRV_PCM_FORMAT_S24_LE: | 489 | case SNDRV_PCM_FORMAT_S24_LE: |
| 490 | config->data_width = 24; | 490 | config->data_width = 32; |
| 491 | kmb_i2s->ccr = 0x08; | 491 | kmb_i2s->ccr = 0x14; |
| 492 | kmb_i2s->xfer_resolution = 0x04; | 492 | kmb_i2s->xfer_resolution = 0x05; |
| 493 | break; | 493 | break; |
| 494 | case SNDRV_PCM_FORMAT_S32_LE: | 494 | case SNDRV_PCM_FORMAT_S32_LE: |
| 495 | config->data_width = 32; | 495 | config->data_width = 32; |
| @@ -122,8 +122,10 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, · 121 unmodified lines | |||
| 122 | else | 122 | else |
| 123 | dma_ch = 0; | 123 | dma_ch = 0; |
| 124 | 124 | ||
| 125 | if (dma_ch < 0) | 125 | if (dma_ch < 0) { |
| 126 | kfree(data); | ||
| 126 | return dma_ch; | 127 | return dma_ch; |
| 128 | } | ||
| 127 | 129 | ||
| 128 | if (cpu_dai->driver->id == LPASS_DP_RX) { | 130 | if (cpu_dai->driver->id == LPASS_DP_RX) { |
| 129 | map = drvdata->hdmiif_map; | 131 | map = drvdata->hdmiif_map; |
| @@ -147,6 +149,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, · 17 unmodified lines | |||
| 147 | ret = snd_pcm_hw_constraint_integer(runtime, | 149 | ret = snd_pcm_hw_constraint_integer(runtime, |
| 148 | SNDRV_PCM_HW_PARAM_PERIODS); | 150 | SNDRV_PCM_HW_PARAM_PERIODS); |
| 149 | if (ret < 0) { | 151 | if (ret < 0) { |
| 152 | kfree(data); | ||
| 150 | dev_err(soc_runtime->dev, "setting constraints failed: %d\n", | 153 | dev_err(soc_runtime->dev, "setting constraints failed: %d\n", |
| 151 | ret); | 154 | ret); |
| 152 | return -EINVAL; | 155 | return -EINVAL; |
| @@ -379,6 +379,10 @@ static const struct usb_audio_device_name usb_audio_names[] = { · 378 unmodified lines | |||
| 379 | 379 | ||
| 380 | DEVICE_NAME(0x046d, 0x0990, "Logitech, Inc.", "QuickCam Pro 9000"), | 380 | DEVICE_NAME(0x046d, 0x0990, "Logitech, Inc.", "QuickCam Pro 9000"), |
| 381 | 381 | ||
| 382 | /* ASUS ROG Strix */ | ||
| 383 | PROFILE_NAME(0x0b05, 0x1917, | ||
| 384 | "Realtek", "ALC1220-VB-DT", "Realtek-ALC1220-VB-Desktop"), | ||
| 385 | |||
| 382 | /* Dell WD15 Dock */ | 386 | /* Dell WD15 Dock */ |
| 383 | PROFILE_NAME(0x0bda, 0x4014, "Dell", "WD15 Dock", "Dell-WD15-Dock"), | 387 | PROFILE_NAME(0x0bda, 0x4014, "Dell", "WD15 Dock", "Dell-WD15-Dock"), |
| 384 | /* Dell WD19 Dock */ | 388 | /* Dell WD19 Dock */ |
| @@ -561,7 +561,8 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { · 560 unmodified lines | |||
| 561 | }, | 561 | }, |
| 562 | { /* ASUS ROG Strix */ | 562 | { /* ASUS ROG Strix */ |
| 563 | .id = USB_ID(0x0b05, 0x1917), | 563 | .id = USB_ID(0x0b05, 0x1917), |
| 564 | .map = asus_rog_map, | 564 | .map = trx40_mobo_map, |
| 565 | .connector_map = trx40_mobo_connector_map, | ||
| 565 | }, | 566 | }, |
| 566 | { /* MSI TRX40 Creator */ | 567 | { /* MSI TRX40 Creator */ |
| 567 | .id = USB_ID(0x0db0, 0x0d64), | 568 | .id = USB_ID(0x0db0, 0x0d64), |
| @@ -1672,13 +1672,13 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, · 1671 unmodified lines | |||
| 1672 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1672 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
| 1673 | msleep(20); | 1673 | msleep(20); |
| 1674 | 1674 | ||
| 1675 | /* Zoom R16/24, Logitech H650e/H570e, Jabra 550a, Kingston HyperX | 1675 | /* Zoom R16/24, many Logitech(at least H650e/H570e/BCC950), |
| 1676 | * needs a tiny delay here, otherwise requests like get/set | 1676 | * Jabra 550a, Kingston HyperX needs a tiny delay here, |
| 1677 | * frequency return as failed despite actually succeeding. | 1677 | * otherwise requests like get/set frequency return |
| 1678 | * as failed despite actually succeeding. | ||
| 1678 | */ | 1679 | */ |
| 1679 | if ((chip->usb_id == USB_ID(0x1686, 0x00dd) || | 1680 | if ((chip->usb_id == USB_ID(0x1686, 0x00dd) || |
| 1680 | chip->usb_id == USB_ID(0x046d, 0x0a46) || | 1681 | USB_ID_VENDOR(chip->usb_id) == 0x046d || /* Logitech */ |
| 1681 | chip->usb_id == USB_ID(0x046d, 0x0a56) || | ||
| 1682 | chip->usb_id == USB_ID(0x0b0e, 0x0349) || | 1682 | chip->usb_id == USB_ID(0x0b0e, 0x0349) || |
| 1683 | chip->usb_id == USB_ID(0x0951, 0x16ad)) && | 1683 | chip->usb_id == USB_ID(0x0951, 0x16ad)) && |
| 1684 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1684 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
| @@ -1758,10 +1758,10 @@ TEST_F(TRACE_poke, getpid_runs_normally) · 1757 unmodified lines | |||
| 1758 | * and the code is stored as a positive value. \ | 1758 | * and the code is stored as a positive value. \ |
| 1759 | */ \ | 1759 | */ \ |
| 1760 | if (_result < 0) { \ | 1760 | if (_result < 0) { \ |
| 1761 | SYSCALL_RET(_regs) = -result; \ | 1761 | SYSCALL_RET(_regs) = -_result; \ |
| 1762 | (_regs).ccr |= 0x10000000; \ | 1762 | (_regs).ccr |= 0x10000000; \ |
| 1763 | } else { \ | 1763 | } else { \ |
| 1764 | SYSCALL_RET(_regs) = result; \ | 1764 | SYSCALL_RET(_regs) = _result; \ |
| 1765 | (_regs).ccr &= ~0x10000000; \ | 1765 | (_regs).ccr &= ~0x10000000; \ |
| 1766 | } \ | 1766 | } \ |
| 1767 | } while (0) | 1767 | } while (0) |
| @@ -1804,8 +1804,8 @@ TEST_F(TRACE_poke, getpid_runs_normally) · 36 unmodified lines | |||
| 1804 | #define SYSCALL_RET(_regs) (_regs).a[(_regs).windowbase * 4 + 2] | 1804 | #define SYSCALL_RET(_regs) (_regs).a[(_regs).windowbase * 4 + 2] |
| 1805 | #elif defined(__sh__) | 1805 | #elif defined(__sh__) |
| 1806 | # define ARCH_REGS struct pt_regs | 1806 | # define ARCH_REGS struct pt_regs |
| 1807 | # define SYSCALL_NUM(_regs) (_regs).gpr[3] | 1807 | # define SYSCALL_NUM(_regs) (_regs).regs[3] |
| 1808 | # define SYSCALL_RET(_regs) (_regs).gpr[0] | 1808 | # define SYSCALL_RET(_regs) (_regs).regs[0] |
| 1809 | #else | 1809 | #else |
| 1810 | # error "Do not know how to find your architecture's registers and syscalls" | 1810 | # error "Do not know how to find your architecture's registers and syscalls" |
| 1811 | #endif | 1811 | #endif |